[
  {
    "path": ".all-contributorsrc",
    "content": "{\n  \"projectName\": \"barba\",\n  \"projectOwner\": \"barbajs\",\n  \"repoType\": \"github\",\n  \"repoHost\": \"https://github.com\",\n  \"files\": [\"README.md\"],\n  \"imageSize\": 100,\n  \"commit\": true,\n  \"commitTemplate\": \"docs(root): :busts_in_silhouette: <%= (newContributor ? 'add' : 'update') %> @<%= username %> as a contributor\",\n  \"contributorsPerLine\": 7,\n  \"contributors\": [\n    {\n      \"login\": \"luruke\",\n      \"name\": \"Luigi De Rosa\",\n      \"avatar_url\": \"https://avatars0.githubusercontent.com/u/61326?v=4\",\n      \"profile\": \"http://luruke.com\",\n      \"contributions\": [\n        \"ideas\",\n        \"code\",\n        \"doc\",\n        \"question\",\n        \"bug\",\n        \"test\",\n        \"review\",\n        \"infra\"\n      ]\n    },\n    {\n      \"login\": \"thierrymichel\",\n      \"name\": \"Thierry Michel\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/806883?v=4\",\n      \"profile\": \"http://thierrymichel.net\",\n      \"contributions\": [\n        \"ideas\",\n        \"code\",\n        \"doc\",\n        \"question\",\n        \"bug\",\n        \"test\",\n        \"review\",\n        \"infra\"\n      ]\n    },\n    {\n      \"login\": \"xavierfoucrier\",\n      \"name\": \"Xavier Foucrier\",\n      \"avatar_url\": \"https://avatars1.githubusercontent.com/u/2471223?v=4\",\n      \"profile\": \"https://xavierfoucrier.dev\",\n      \"contributions\": [\n        \"ideas\",\n        \"code\",\n        \"doc\",\n        \"question\",\n        \"test\",\n        \"review\",\n        \"bug\",\n        \"infra\"\n      ]\n    },\n    {\n      \"login\": \"markog85\",\n      \"name\": \"Marco Grimaldi\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/858150?v=4\",\n      \"profile\": \"http://www.thenerodesign.com\",\n      \"contributions\": [\"design\"]\n    },\n    {\n      \"login\": \"Ihatetomatoes\",\n      \"name\": \"Petr TIchy\",\n      \"avatar_url\": \"https://avatars1.githubusercontent.com/u/735672?v=4\",\n      \"profile\": \"https://ihatetomatoes.net\",\n      \"contributions\": [\"blog\", \"tutorial\", \"video\"]\n    },\n    {\n      \"login\": \"c0mrx\",\n      \"name\": \"Cody Marcoux\",\n      \"avatar_url\": \"https://avatars0.githubusercontent.com/u/22644154?v=4\",\n      \"profile\": \"https://studio123.ca\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"wiseoldman\",\n      \"name\": \"Phil.\",\n      \"avatar_url\": \"https://avatars1.githubusercontent.com/u/3285136?v=4\",\n      \"profile\": \"https://philiphussak.com\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"gfnool\",\n      \"name\": \"Giorgio Finulli\",\n      \"avatar_url\": \"https://avatars0.githubusercontent.com/u/5812801?v=4\",\n      \"profile\": \"http://www.fnool.com\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"Wouter125\",\n      \"name\": \"Wouter\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/6507123?v=4\",\n      \"profile\": \"https://www.thisisnota.studio\",\n      \"contributions\": [\"bug\", \"question\"]\n    },\n    {\n      \"login\": \"mikehwagz\",\n      \"name\": \"Mike Wagz\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/12376535?v=4\",\n      \"profile\": \"https://selfaware.studio\",\n      \"contributions\": [\"ideas\", \"question\", \"test\"]\n    },\n    {\n      \"login\": \"theredstapler\",\n      \"name\": \"Red Stapler\",\n      \"avatar_url\": \"https://avatars0.githubusercontent.com/u/16864380?v=4\",\n      \"profile\": \"https://www.youtube.com/c/redstapler_channel\",\n      \"contributions\": [\"tutorial\", \"video\"]\n    },\n    {\n      \"login\": \"19h47\",\n      \"name\": \"Jérémy Levron\",\n      \"avatar_url\": \"https://avatars1.githubusercontent.com/u/11242861?v=4\",\n      \"profile\": \"http://www.19h47.fr\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"anhskohbo\",\n      \"name\": \"Nguyen Van Anh\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/1529454?v=4\",\n      \"profile\": \"http://anhskohbo.github.io/\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"dlwebdev\",\n      \"name\": \"Daniel Weber\",\n      \"avatar_url\": \"https://avatars1.githubusercontent.com/u/668910?v=4\",\n      \"profile\": \"http://www.thedanielweber.com\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"jmporchet\",\n      \"name\": \"Jean-Marie Porchet\",\n      \"avatar_url\": \"https://avatars3.githubusercontent.com/u/3099008?v=4\",\n      \"profile\": \"http://www.jmporchet.ch\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"docherty\",\n      \"name\": \"James\",\n      \"avatar_url\": \"https://avatars1.githubusercontent.com/u/325490?v=4\",\n      \"profile\": \"https://www.jamesdocherty.com/\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"nicholasruggeri\",\n      \"name\": \"Nicholas\",\n      \"avatar_url\": \"https://avatars0.githubusercontent.com/u/999162?v=4\",\n      \"profile\": \"http://ruggeri.io\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"patrick91\",\n      \"name\": \"Patrick Arminio\",\n      \"avatar_url\": \"https://avatars1.githubusercontent.com/u/667029?v=4\",\n      \"profile\": \"http://patrick.wtf\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"angelogulina\",\n      \"name\": \"A (from Sicily)\",\n      \"avatar_url\": \"https://avatars0.githubusercontent.com/u/4223655?v=4\",\n      \"profile\": \"https://angelogulina.it\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"pavel-mazhuga\",\n      \"name\": \"Pavel Mazhuga\",\n      \"avatar_url\": \"https://avatars3.githubusercontent.com/u/29140681?v=4\",\n      \"profile\": \"https://github.com/pavel-mazhuga\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"DMDc0de\",\n      \"name\": \"Daniele De Matteo\",\n      \"avatar_url\": \"https://avatars0.githubusercontent.com/u/7113516?v=4\",\n      \"profile\": \"http://dmdcode.it\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"aswinkumar863\",\n      \"name\": \"aswinkumar863\",\n      \"avatar_url\": \"https://avatars0.githubusercontent.com/u/32381261?v=4\",\n      \"profile\": \"https://github.com/aswinkumar863\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"BounceIncHQ\",\n      \"name\": \"BounceIncHQ\",\n      \"avatar_url\": \"https://avatars0.githubusercontent.com/u/39249876?v=4\",\n      \"profile\": \"https://github.com/BounceIncHQ\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"gordonwes\",\n      \"name\": \"gordonwes\",\n      \"avatar_url\": \"https://avatars3.githubusercontent.com/u/10758596?v=4\",\n      \"profile\": \"https://github.com/gordonwes\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"evfleet\",\n      \"name\": \"Evan Fleet\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/7504632?v=4\",\n      \"profile\": \"https://github.com/evfleet\",\n      \"contributions\": [\"question\", \"bug\"]\n    },\n    {\n      \"login\": \"jd4Aligator\",\n      \"name\": \"Jörg\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/32126746?v=4\",\n      \"profile\": \"http://www.aligator-kom.de\",\n      \"contributions\": [\"example\"]\n    },\n    {\n      \"login\": \"StudioZAAK\",\n      \"name\": \"ZAAK\",\n      \"avatar_url\": \"https://avatars3.githubusercontent.com/u/12050808?v=4\",\n      \"profile\": \"http://www.zaak.ch\",\n      \"contributions\": [\"example\", \"question\"]\n    },\n    {\n      \"login\": \"leapincorp\",\n      \"name\": \"Masahiro Tonomura\",\n      \"avatar_url\": \"https://avatars1.githubusercontent.com/u/42055102?v=4\",\n      \"profile\": \"https://leap-in.com\",\n      \"contributions\": [\"example\"]\n    },\n    {\n      \"login\": \"CassiusHR\",\n      \"name\": \"CassiusHR\",\n      \"avatar_url\": \"https://avatars1.githubusercontent.com/u/24419585?v=4\",\n      \"profile\": \"https://github.com/CassiusHR\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"shanewmurphy\",\n      \"name\": \"Shane Murphy\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/3694619?v=4\",\n      \"profile\": \"http://www.shanemurphy.me\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"watzing\",\n      \"name\": \"Dylan Reeves\",\n      \"avatar_url\": \"https://avatars3.githubusercontent.com/u/1294637?v=4\",\n      \"profile\": \"http://www.dylanreeves.com\",\n      \"contributions\": [\"question\", \"example\"]\n    },\n    {\n      \"login\": \"quentinneyraud\",\n      \"name\": \"Quentin Neyraud\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/9378568?v=4\",\n      \"profile\": \"http://www.quentinneyraud.fr\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"tortilaman\",\n      \"name\": \"tortilaman\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/5018268?v=4\",\n      \"profile\": \"https://github.com/tortilaman\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"psntr\",\n      \"name\": \"psntr\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/20617539?v=4\",\n      \"profile\": \"https://github.com/psntr\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"thisbailiwick\",\n      \"name\": \"Kevin Clark\",\n      \"avatar_url\": \"https://avatars3.githubusercontent.com/u/12637253?v=4\",\n      \"profile\": \"http://thisbailiwick.com\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"Tedowski\",\n      \"name\": \"Tadeas Kosek\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/26543624?v=4\",\n      \"profile\": \"http://takodesign.one\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"gustavo-a\",\n      \"name\": \"Gustavo de Andrade\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/26806307?v=4\",\n      \"profile\": \"https://github.com/gustavo-a\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"crobbinsdg\",\n      \"name\": \"Clinton\",\n      \"avatar_url\": \"https://avatars0.githubusercontent.com/u/25391588?v=4\",\n      \"profile\": \"https://durkangroup.com/\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"magicspon\",\n      \"name\": \"Dave Stockley\",\n      \"avatar_url\": \"https://avatars3.githubusercontent.com/u/3268717?v=4\",\n      \"profile\": \"https://www.spon.io\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"khaiknievel\",\n      \"name\": \"khaiknievel\",\n      \"avatar_url\": \"https://avatars1.githubusercontent.com/u/5792500?v=4\",\n      \"profile\": \"http://khaiknievel.carbonmade.com\",\n      \"contributions\": [\"question\", \"bug\"]\n    },\n    {\n      \"login\": \"kekkorider\",\n      \"name\": \"Francesco Michelini\",\n      \"avatar_url\": \"https://avatars3.githubusercontent.com/u/5191941?v=4\",\n      \"profile\": \"http://www.francescomichelini.com/\",\n      \"contributions\": [\"question\", \"example\"]\n    },\n    {\n      \"login\": \"FistMeNaruto\",\n      \"name\": \"Domantas Petrauskas\",\n      \"avatar_url\": \"https://avatars1.githubusercontent.com/u/13431677?v=4\",\n      \"profile\": \"https://github.com/FistMeNaruto\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"kjbrum\",\n      \"name\": \"Kyle Brumm\",\n      \"avatar_url\": \"https://avatars3.githubusercontent.com/u/1709677?v=4\",\n      \"profile\": \"http://kylebrumm.com\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"obelmont\",\n      \"name\": \"Oliver Belmont\",\n      \"avatar_url\": \"https://avatars3.githubusercontent.com/u/6540497?v=4\",\n      \"profile\": \"https://github.com/obelmont\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"lunelson\",\n      \"name\": \"Lu Nelson\",\n      \"avatar_url\": \"https://avatars1.githubusercontent.com/u/1242864?v=4\",\n      \"profile\": \"https://lunelson.xyz/\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"bramcordie\",\n      \"name\": \"Bram Cordie\",\n      \"avatar_url\": \"https://avatars1.githubusercontent.com/u/1107185?v=4\",\n      \"profile\": \"http://bierdb.be\",\n      \"contributions\": [\"question\", \"ideas\"]\n    },\n    {\n      \"login\": \"metalmini\",\n      \"name\": \"Michael Schouman\",\n      \"avatar_url\": \"https://avatars1.githubusercontent.com/u/510652?v=4\",\n      \"profile\": \"http://portfolio.schouman.info\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"JumpLink\",\n      \"name\": \"Pascal Garber\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/1073989?v=4\",\n      \"profile\": \"https://www.jumplink.eu\",\n      \"contributions\": [\"question\", \"ideas\"]\n    },\n    {\n      \"login\": \"bfred-it\",\n      \"name\": \"Federico Brigante\",\n      \"avatar_url\": \"https://avatars3.githubusercontent.com/u/1402241?v=4\",\n      \"profile\": \"https://twitter.com/bfred_it\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"factorzero\",\n      \"name\": \"Corey Lee\",\n      \"avatar_url\": \"https://avatars1.githubusercontent.com/u/1465865?v=4\",\n      \"profile\": \"http://coreylee.tokyo/\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"mbsimonovic\",\n      \"name\": \"Milan Simonovic\",\n      \"avatar_url\": \"https://avatars3.githubusercontent.com/u/888008?v=4\",\n      \"profile\": \"http://www.imls.uzh.ch/research/vonmering/people/milan-simonovic.html\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"Djules\",\n      \"name\": \"Julien Vasseur\",\n      \"avatar_url\": \"https://avatars1.githubusercontent.com/u/196644?v=4\",\n      \"profile\": \"http://djul.es\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"panwron\",\n      \"name\": \"Maciej Wrona\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/8494786?v=4\",\n      \"profile\": \"https://github.com/panwron\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"terion-name\",\n      \"name\": \"Terion\",\n      \"avatar_url\": \"https://avatars0.githubusercontent.com/u/1060205?v=4\",\n      \"profile\": \"http://terion.name\",\n      \"contributions\": [\"ideas\"]\n    },\n    {\n      \"login\": \"cartogram\",\n      \"name\": \"Matt Seccafien\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/462077?v=4\",\n      \"profile\": \"https://github.com/cartogram\",\n      \"contributions\": [\"ideas\"]\n    },\n    {\n      \"login\": \"max-schu\",\n      \"name\": \"Max Schulmeister\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/15388185?v=4\",\n      \"profile\": \"http://www.maxschulmeister.com\",\n      \"contributions\": [\"ideas\"]\n    },\n    {\n      \"login\": \"tipsy\",\n      \"name\": \"David\",\n      \"avatar_url\": \"https://avatars3.githubusercontent.com/u/1521451?v=4\",\n      \"profile\": \"https://davidaase.com\",\n      \"contributions\": [\"ideas\"]\n    },\n    {\n      \"login\": \"pierrehenri220\",\n      \"name\": \"Pierre-Henri Lavigne\",\n      \"avatar_url\": \"https://avatars3.githubusercontent.com/u/19267400?v=4\",\n      \"profile\": \"https://github.com/pierrehenri220\",\n      \"contributions\": [\"ideas\"]\n    },\n    {\n      \"login\": \"lsbyerley\",\n      \"name\": \"lsbyerley\",\n      \"avatar_url\": \"https://avatars0.githubusercontent.com/u/3066258?v=4\",\n      \"profile\": \"https://github.com/lsbyerley\",\n      \"contributions\": [\"ideas\"]\n    },\n    {\n      \"login\": \"theamnesic\",\n      \"name\": \"Guillaume M.\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/242203?v=4\",\n      \"profile\": \"http://gmorisseau.com/\",\n      \"contributions\": [\"ideas\"]\n    },\n    {\n      \"login\": \"oscarotero\",\n      \"name\": \"Oscar Otero\",\n      \"avatar_url\": \"https://avatars3.githubusercontent.com/u/377873?v=4\",\n      \"profile\": \"https://oscarotero.com\",\n      \"contributions\": [\"ideas\"]\n    },\n    {\n      \"login\": \"nicooprat\",\n      \"name\": \"Nico Prat\",\n      \"avatar_url\": \"https://avatars0.githubusercontent.com/u/645641?v=4\",\n      \"profile\": \"http://twitter.com/nicooprat\",\n      \"contributions\": [\"ideas\"]\n    },\n    {\n      \"login\": \"dwightjack\",\n      \"name\": \"Marco Solazzi\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/104721?v=4\",\n      \"profile\": \"http://marco.solazzi.me/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"atoupet-toki\",\n      \"name\": \"atoupet-toki\",\n      \"avatar_url\": \"https://avatars3.githubusercontent.com/u/38693082?v=4\",\n      \"profile\": \"https://github.com/atoupet-toki\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"josias-r\",\n      \"name\": \"Josias\",\n      \"avatar_url\": \"https://avatars1.githubusercontent.com/u/11424820?v=4\",\n      \"profile\": \"https://github.com/josias-r\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"OksanaRomaniv\",\n      \"name\": \"Oksana Romaniv\",\n      \"avatar_url\": \"https://avatars1.githubusercontent.com/u/5724727?v=4\",\n      \"profile\": \"https://github.com/OksanaRomaniv\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"oguilleux\",\n      \"name\": \"Olivier Guilleux\",\n      \"avatar_url\": \"https://avatars3.githubusercontent.com/u/5804006?v=4\",\n      \"profile\": \"https://www.olivier-guilleux.com\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"Liroo\",\n      \"name\": \"Liroo Pierre ᵈᵉᵛ\",\n      \"avatar_url\": \"https://avatars3.githubusercontent.com/u/11197281?v=4\",\n      \"profile\": \"http://liroopierre.com\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"lmartins\",\n      \"name\": \"Luis Martins\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/151981?v=4\",\n      \"profile\": \"https://github.com/lmartins\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"matthewjumpsoffbuildings\",\n      \"name\": \"Matthew\",\n      \"avatar_url\": \"https://avatars0.githubusercontent.com/u/41524?v=4\",\n      \"profile\": \"https://arraytheband.com.au\",\n      \"contributions\": [\"ideas\", \"question\"]\n    },\n    {\n      \"login\": \"Slgoetz\",\n      \"name\": \"Simon Goetz\",\n      \"avatar_url\": \"https://avatars0.githubusercontent.com/u/393000?v=4\",\n      \"profile\": \"http://slgoetz.com\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"luis-pt\",\n      \"name\": \"Luís Carvalho\",\n      \"avatar_url\": \"https://avatars3.githubusercontent.com/u/14956453?v=4\",\n      \"profile\": \"https://luis.pt\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"mrsamse\",\n      \"name\": \"Samuel Berisha\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/20925205?v=4\",\n      \"profile\": \"https://github.com/mrsamse\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"andersonleite\",\n      \"name\": \"Anderson Leite\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/52427?v=4\",\n      \"profile\": \"https://github.com/andersonleite\",\n      \"contributions\": [\"question\", \"bug\"]\n    },\n    {\n      \"login\": \"JayBox325\",\n      \"name\": \"Jay Collett\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/13233809?v=4\",\n      \"profile\": \"https://jaycollett.co/\",\n      \"contributions\": [\"question\", \"bug\"]\n    },\n    {\n      \"login\": \"timgates42\",\n      \"name\": \"Tim Gates\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/47873678?v=4\",\n      \"profile\": \"https://github.com/timgates42\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"nicolas-cusan\",\n      \"name\": \"Nicolas Cusan\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/1353931?v=4\",\n      \"profile\": \"https://www.nicolascusan.com/\",\n      \"contributions\": [\"question\", \"bug\", \"code\"]\n    },\n    {\n      \"login\": \"geraldnako\",\n      \"name\": \"Gerald Nako\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/5095859?v=4\",\n      \"profile\": \"https://geraldnako.com/\",\n      \"contributions\": [\"bug\", \"code\"]\n    }\n  ],\n  \"commitConvention\": \"angular\"\n}\n\n"
  },
  {
    "path": ".circleci/config.yml",
    "content": "version: 2\n\ndefaults: &defaults\n  working_directory: ~/repo\n  docker:\n    - image: cimg/node:20.4\n  # Not working: Job \\\"build\\\" has filters configured in the job definition. These filters are incompatible with workflows.\n  # branches:\n  #   only:\n  #     - main\n\njobs:\n  build:\n    <<: *defaults\n    resource_class: large\n    steps:\n      - checkout\n      - restore_cache:\n          name: Restore Yarn Package Cache\n          keys:\n            - yarn-packages-{{ checksum \"yarn.lock\" }}\n      - restore_cache:\n          name: Restore Node modules\n          keys:\n            - dependency-cache-{{ checksum \"package.json\" }}\n      - run:\n          name: Install dependencies\n          command: yarn install --frozen-lockfile\n      - save_cache:\n          name: Save Yarn Package Cache\n          key: yarn-packages-{{ checksum \"yarn.lock\" }}\n          paths:\n            - ~/.cache/yarn\n      - save_cache:\n          key: dependency-cache-{{ checksum \"package.json\" }}\n          paths:\n            - node_modules\n      - persist_to_workspace:\n          root: ~/repo\n          paths:\n            - node_modules\n  test:\n    <<: *defaults\n    resource_class: large\n    steps:\n      - checkout\n      - attach_workspace:\n          at: ~/repo\n      - run:\n          name: Lint\n          command: yarn lint\n      - run:\n          name: Bundle\n          command: yarn build\n      - run:\n          name: Test\n          command: yarn unit:ci\n      - run:\n          name: Coverage\n          command: yarn coverage\n      - store_artifacts:\n          path: coverage\n      - persist_to_workspace:\n          root: ~/repo\n          paths:\n            - node_modules\n  docs-build:\n    <<: *defaults\n    steps:\n      - checkout\n      - attach_workspace:\n          at: ~/repo\n      - run:\n          name: Build docs\n          command: yarn doc\n      - persist_to_workspace:\n          root: ~/repo\n          paths: [documentation]\n  docs-deploy:\n    <<: *defaults\n    steps:\n      - checkout\n      - attach_workspace:\n          at: ~/repo\n      - run:\n          name: Install and configure dependencies\n          command: |\n            yarn add gh-pages@2.0.1 -W\n            git config user.email $GH_EMAIL\n            git config user.name $GH_NAME\n      - add_ssh_keys:\n          fingerprints:\n            - '2c:bd:91:1f:35:54:de:94:22:77:fc:3e:68:f9:6b:2f'\n      - run:\n          name: Deploy docs to gh-pages branch\n          command: ./node_modules/.bin/gh-pages -d documentation/api -e api -m 'Deploy docs [ci skip]'\n\nworkflows:\n  version: 2\n  build_and_test:\n    jobs:\n      - build:\n          filters:\n            branches:\n              only:\n                - main\n                - dev\n      - test:\n          requires:\n            - build\n          filters:\n            branches:\n              only:\n                - main\n                - dev\n      - docs-build:\n          requires:\n            - test\n          filters:\n            branches:\n              only:\n                - main\n                - dev\n      - docs-deploy:\n          requires:\n            - docs-build\n          filters:\n            branches:\n              only: main\n"
  },
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\nindent_style = space\nindent_size = 2\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n[*.md]\nindent_size = 4\ntrim_trailing_whitespace = false\n"
  },
  {
    "path": ".eslintrc.js",
    "content": "module.exports = {\n  env: {\n    browser: true,\n    commonjs: true,\n    es6: true,\n    node: true,\n    'cypress/globals': true,\n  },\n  extends: ['eslint:recommended', 'plugin:cypress/recommended'],\n  parser: 'babel-eslint',\n  plugins: ['cypress'],\n  rules: {\n    'accessor-pairs': 2,\n    'array-callback-return': 2,\n    'array-bracket-spacing': 2,\n    'arrow-body-style': 2,\n    'arrow-parens': [2, 'as-needed'],\n    'arrow-spacing': 2,\n    'block-scoped-var': 2,\n    'block-spacing': 2,\n    'brace-style': 2,\n    camelcase: [\n      2,\n      {\n        properties: 'always',\n      },\n    ],\n    'capitalized-comments': [\n      2,\n      'always',\n      {\n        ignoreConsecutiveComments: true,\n      },\n    ],\n    'class-methods-use-this': 2,\n    'comma-dangle': [1, 'always-multiline'],\n    'comma-spacing': 2,\n    'comma-style': 2,\n    'computed-property-spacing': 2,\n    'consistent-return': 2,\n    'consistent-this': 2,\n    curly: 2,\n    'default-case': 2,\n    'dot-location': [1, 'property'],\n    'dot-notation': 2,\n    'eol-last': 2,\n    eqeqeq: 2,\n    'func-call-spacing': 2,\n    'func-name-matching': 2,\n    'func-names': 2,\n    'global-require': 2,\n    'guard-for-in': 2,\n    'id-length': [\n      2,\n      {\n        min: 1,\n        max: 24,\n      },\n    ],\n    indent: [\n      2,\n      2,\n      {\n        SwitchCase: 1,\n        VariableDeclarator: {\n          var: 2,\n          let: 2,\n          const: 3,\n        },\n      },\n    ],\n    'key-spacing': 2,\n    'keyword-spacing': 2,\n    'linebreak-style': 2,\n    'lines-around-comment': [\n      2,\n      {\n        beforeBlockComment: true,\n        afterBlockComment: false,\n        allowBlockStart: true,\n        allowBlockEnd: true,\n        allowObjectStart: true,\n        allowObjectEnd: true,\n        allowArrayStart: true,\n        allowArrayEnd: true,\n      },\n    ],\n    'lines-around-directive': 2,\n    'max-depth': 2,\n    'max-len': [\n      2,\n      {\n        code: 120,\n      },\n    ],\n    'max-nested-callbacks': 2,\n    'max-statements-per-line': [\n      2,\n      {\n        max: 2,\n      },\n    ],\n    'new-cap': 2,\n    'new-parens': 2,\n    'newline-before-return': 2,\n    'newline-per-chained-call': 2,\n    'no-alert': 2,\n    'no-array-constructor': 2,\n    'no-await-in-loop': 2,\n    'no-caller': 2,\n    'no-console': 0,\n    'no-continue': 0,\n    'no-div-regex': 2,\n    'no-duplicate-imports': 2,\n    'no-else-return': 2,\n    'no-empty-function': 2,\n    'no-eq-null': 2,\n    'no-eval': 2,\n    'no-extend-native': 2,\n    'no-extra-bind': 2,\n    'no-extra-label': 2,\n    'no-extra-parens': [\n      2,\n      'all',\n      {\n        nestedBinaryExpressions: false,\n      },\n    ],\n    'no-floating-decimal': 2,\n    'no-global-assign': 2,\n    'no-implicit-coercion': 2,\n    'no-implicit-globals': 2,\n    'no-implied-eval': 2,\n    'no-invalid-this': 2,\n    'no-iterator': 2,\n    'no-labels': 2,\n    'no-lone-blocks': 2,\n    'no-lonely-if': 2,\n    'no-loop-func': 2,\n    'no-magic-numbers': [\n      0,\n      {\n        ignore: [0, 1],\n        ignoreArrayIndexes: true,\n      },\n    ],\n    'no-mixed-operators': 2,\n    'no-mixed-spaces-and-tabs': 2,\n    'no-multi-assign': 2,\n    'no-multi-spaces': 2,\n    'no-multi-str': 2,\n    'no-multiple-empty-lines': [\n      2,\n      {\n        max: 3,\n      },\n    ],\n    'no-negated-condition': 2,\n    'no-nested-ternary': 2,\n    'no-new-func': 2,\n    'no-new-object': 2,\n    'no-new-wrappers': 2,\n    'no-new': 2,\n    'no-octal-escape': 2,\n    'no-param-reassign': 2,\n    'no-plusplus': [\n      2,\n      {\n        allowForLoopAfterthoughts: true,\n      },\n    ],\n    'no-proto': 2,\n    'no-prototype-builtins': 2,\n    'no-restricted-properties': 2,\n    'no-return-assign': 2,\n    'no-return-await': 2,\n    'no-script-url': 2,\n    'no-self-compare': 2,\n    'no-sequences': 2,\n    'no-tabs': 2,\n    'no-template-curly-in-string': 2,\n    'no-throw-literal': 2,\n    'no-trailing-spaces': 2,\n    'no-unsafe-negation': 2,\n    'no-unmodified-loop-condition': 2,\n    'no-unneeded-ternary': 2,\n    'no-unused-expressions': [\n      2,\n      {\n        allowShortCircuit: true,\n      },\n    ],\n    'no-useless-call': 2,\n    'no-useless-computed-key': 2,\n    'no-useless-concat': 2,\n    'no-useless-constructor': 2,\n    'no-useless-escape': 2,\n    'no-useless-rename': 2,\n    'no-useless-return': 2,\n    'no-var': 2,\n    'no-void': 2,\n    'no-warning-comments': 1,\n    'no-whitespace-before-property': 2,\n    'no-with': 2,\n    'object-shorthand': 2,\n    'object-property-newline': 0,\n    'operator-assignment': 2,\n    'operator-linebreak': 2,\n    'padded-blocks': [2, 'never'],\n    'padding-line-between-statements': [\n      2,\n      { blankLine: 'always', prev: ['const', 'let', 'var'], next: '*' },\n      {\n        blankLine: 'any',\n        prev: ['const', 'let', 'var'],\n        next: ['const', 'let', 'var'],\n      },\n    ],\n    'prefer-arrow-callback': 2,\n    'prefer-const': 2,\n    'prefer-destructuring': 2,\n    'prefer-promise-reject-errors': 2,\n    'prefer-rest-params': 2,\n    'prefer-spread': 2,\n    'prefer-template': 2,\n    'quote-props': [2, 'consistent-as-needed'],\n    quotes: [2, 'single'],\n    radix: 2,\n    'require-await': 2,\n    'require-jsdoc': 2,\n    'rest-spread-spacing': 2,\n    semi: 2,\n    'semi-spacing': 2,\n    'space-before-blocks': 2,\n    'space-in-parens': 2,\n    'space-infix-ops': 2,\n    'space-unary-ops': [\n      2,\n      {\n        words: true,\n        nonwords: false,\n      },\n    ],\n    'spaced-comment': 2,\n    strict: 2,\n    'symbol-description': 2,\n    'template-curly-spacing': 2,\n    'valid-jsdoc': 2,\n    'vars-on-top': 2,\n    'wrap-iife': 2,\n    'wrap-regex': 2,\n    yoda: 2,\n  },\n};\n"
  },
  {
    "path": ".github/CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to making participation in our project and\nour community a harassment-free experience for everyone, regardless of age, body\nsize, disability, ethnicity, sex characteristics, gender identity and expression,\nlevel of experience, education, socio-economic status, nationality, personal\nappearance, race, religion, or sexual identity and orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment\ninclude:\n\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or\n advances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic\n address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable\nbehavior and are expected to take appropriate and fair corrective action in\nresponse to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or\nreject comments, commits, code, wiki edits, issues, and other contributions\nthat are not aligned to this Code of Conduct, or to ban temporarily or\npermanently any contributor for other behaviors that they deem inappropriate,\nthreatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces\nwhen an individual is representing the project or its community. Examples of\nrepresenting a project or community include using an official project e-mail\naddress, posting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event. Representation of a project may be\nfurther defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported by contacting the project team at team@barba.dev. All\ncomplaints will be reviewed and investigated and will result in a response that\nis deemed necessary and appropriate to the circumstances. The project team is\nobligated to maintain confidentiality with regard to the reporter of an incident.\nFurther details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good\nfaith may face temporary or permanent repercussions as determined by other\nmembers of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,\navailable at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html\n\n[homepage]: https://www.contributor-covenant.org\n\nFor answers to common questions about this code of conduct, see\nhttps://www.contributor-covenant.org/faq\n"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "content": "# Contributing\n\nThis project uses:\n\n- [TypeScript](http://www.typescriptlang.org/)\n- [Lerna](https://lerna.js.org/)\n- [Commitizen](http://commitizen.github.io/cz-cli/)\n- [EditorConfig](https://editorconfig.org/)\n- [TSLint](https://palantir.github.io/tslint/)\n- [Prettier](https://prettier.io/)\n- [markdownlint](https://github.com/DavidAnson/markdownlint)\n\n> Please, be sure to properly configure your editor…\n\n## Install\n\nMake sure you have `yarn` and `node >= 10.16.0`\n\n- `git clone git@github.com:barbajs/barba.git`\n- `cd barba`\n- `yarn install`\n\n## Testing\n\nRun `yarn test`\n\nFor watching mode, run `yarn run watch`\n\n> Do not pay attention to the few `console.error` logs…<br>\n> In watch mode, you can select a specific package by pressing `l` > :arrow_down: > `space` > :leftwards_arrow_with_hook:\n\n## Comitting\n\nRun `yarn run commit` or install `commitizen` globally and run `cz`.\n\nThis project follows:\n\n- [Conventional Commits](https://conventionalcommits.org) specification for commit \"structure\"\n- [gitmoji](https://gitmoji.carloscuesta.me/) for commit messages\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: xavierfoucrier\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug-report.yml",
    "content": "name: \"🐛 Bug report\"\ndescription: \"Report an issue with BarbaJS\"\ntitle: \"...\"\nlabels:\n  - bug\nbody:\n- type: markdown\n  attributes:\n    value: |\n      By opening an issue, you consider that there is a problem with the library itself, rather than your code. If you are requesting for help, please **use the Slack workspace** in order to ask the whole community. Join using the invite link, read [the developer documentation](https://barba.js.org/docs/getstarted/useful-links/#Developer). Alternatively, I can provide a custom code support for you or your company through [sponsoring/quote](https://github.com/sponsors/xavierfoucrier) depending on the amount of work, don't hesitate to reach me by mail or private message on Slack ✌️🪴.\n- type: input\n  attributes:\n    label: What version are you using?\n    description: Please provide the version of BarbaJS your are using in your project.\n    placeholder: e.g. v2.9.7\n  validations:\n    required: true\n- type: dropdown\n  attributes:\n    label: What package are you using?\n    description: |\n      Please specify the package with which you are having a problem.\n    options:\n      - \"@barba/core\"\n      - \"@barba/router\"\n      - \"@barba/prefetch\"\n      - \"@barba/css\"\n      - \"@barba/head\"\n      - \"@barba/preset\"\n  validations:\n    required: true\n- type: textarea\n  attributes:\n    label: Describe your issue\n    description: |\n      You can use Markdown in this field.\n  validations:\n    required: true\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "contact_links:\n  - name: ✨ Official BarbaJS website\n    url: https://barba.js.org/\n    about: New to BarbaJS? Have a look at the website before opening an issue.\n  - name: 💬 Slack workspace\n    url: https://join.slack.com/t/barbajs/shared_invite/enQtNTU3NTAyMjkxMzAyLTkxYWUwZmM1YWQxMmNlYmE0ZjY4NDQxMGUxYjkwYWFlMzEzOWM4OTRhMWRmYTQyYzFlMmQ3OGFmYmI3MWY0OWY\n    about: Want to discuss or chat with the community? Join using the invite link!\n"
  },
  {
    "path": ".github/stale.yml",
    "content": "# Number of days of inactivity before an issue becomes stale\ndaysUntilStale: 60\n# Number of days of inactivity before a stale issue is closed\ndaysUntilClose: 7\n# Issues with these labels will never be considered stale\nexemptLabels:\n  - pinned\n  - security\n# Label to use when marking an issue as stale\nstaleLabel: wontfix\n# Comment to post when marking an issue as stale. Set to `false` to disable\nmarkComment: >\n  This issue has been automatically marked as stale because it has not had\n  recent activity. It will be closed if no further activity occurs. Thank you\n  for your contributions.\n# Comment to post when closing a stale issue. Set to `false` to disable\ncloseComment: false\n"
  },
  {
    "path": ".gitignore",
    "content": "# Created by https://www.gitignore.io/api/node,macos,linux,windows,visualstudiocode\n\n### Linux ###\n*~\n\n# temporary files which can be created if a process still has a handle open of a deleted file\n.fuse_hidden*\n\n# KDE directory preferences\n.directory\n\n# Linux trash folder which might appear on any partition or disk\n.Trash-*\n\n# .nfs files are created when an open file is removed but is still being accessed\n.nfs*\n\n### macOS ###\n# General\n.DS_Store\n.AppleDouble\n.LSOverride\n\n# Icon must end with two \\r\nIcon\n\n# Thumbnails\n._*\n\n# Files that might appear in the root of a volume\n.DocumentRevisions-V100\n.fseventsd\n.Spotlight-V100\n.TemporaryItems\n.Trashes\n.VolumeIcon.icns\n.com.apple.timemachine.donotpresent\n\n# Directories potentially created on remote AFP share\n.AppleDB\n.AppleDesktop\nNetwork Trash Folder\nTemporary Items\n.apdisk\n\n### Node ###\n# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (https://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# TypeScript v1 declaration files\ntypings/\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variables file\n.env\n\n# parcel-bundler cache (https://parceljs.org/)\n.cache\n\n# next.js build output\n.next\n\n# nuxt.js build output\n.nuxt\n\n# vuepress build output\n.vuepress/dist\n\n# Serverless directories\n.serverless\n\n### VisualStudioCode ###\n.vscode/*\n!.vscode/settings.json\n!.vscode/tasks.json\n!.vscode/launch.json\n!.vscode/extensions.json\n\n### Windows ###\n# Windows thumbnail cache files\nThumbs.db\nehthumbs.db\nehthumbs_vista.db\n\n# Dump file\n*.stackdump\n\n# Folder config file\n[Dd]esktop.ini\n\n# Recycle Bin used on file shares\n$RECYCLE.BIN/\n\n# Windows Installer files\n*.cab\n*.msi\n*.msix\n*.msm\n*.msp\n\n# Windows shortcuts\n*.lnk\n\n\n# End of https://www.gitignore.io/api/node,macos,linux,windows,visualstudiocode\n\n\n### Custom ###\n\n.tmp\ndist\nreport.html\n.rts2*\n# Keep microbundle's mangle.json out until it needs to be there?\nmangle.json\n/cypress/screenshots\n/cypress/videos\n/documentation/api\n/PERSONAL.md\n"
  },
  {
    "path": ".lintstagedrc",
    "content": "{\n  \"src/**/*.ts\": [\"prettier --write\", \"npm run lint\"],\n  \"*.{json,md}\": [\"prettier --write\"]\n}\n"
  },
  {
    "path": ".markdownlint.json",
    "content": "{\n  \"default\": true,\n  \"fenced-code-language\": false,\n  \"first-line-h1\": false,\n  \"line-length\": false,\n  \"no-inline-html\": false,\n  \"no-trailing-punctuation\": {\n    \"punctuation\": \",;:\"\n  },\n  \"ol-prefix\": {\n    \"style\": \"ordered\"\n  },\n  \"ul-indent\": { \"indent\": 2 },\n  \"ul-style\": false\n}\n"
  },
  {
    "path": ".vscode/settings.json",
    "content": "{\n  \"editor.formatOnSave\": true,\n  \"sasslint.enable\": false\n}\n"
  },
  {
    "path": "AUTHORS",
    "content": "Luigi De Rosa <lurukee@gmail.com> (https://luruke.com/)\nThierry Michel <thmichel@gmail.com> (https://www.epic.net/)\nXavier Foucrier <xavier.foucrier@gmail.com> (https://xavierfoucrier.dev/)\n"
  },
  {
    "path": "CI.md",
    "content": "# CI\n\n## @snitch\n\n```\nlanguage: node_js\nnode_js:\n  - \"8\"\nafter_success: 'npm run coverage'\n```\n\n## sassy-beam\n\n`.travis.yml`\n\n```yml\nlanguage: node_js\ncache:\n  directories:\n    - ~/.npm\nnotifications:\n  email: false\nnode_js:\n  - '10'\n  - '9'\n  - '8'\nafter_success:\n  - npm run travis-deploy-once \"npm run semantic-release\"\nbranches:\n  except:\n    - /^v\\d+\\.\\d+\\.\\d+$/\n```\n\n`package.json`\n\n```json\n\"release\": {\n  \"prepare\": [\n    \"@semantic-release/npm\",\n    {\n      \"path\": \"@semantic-release/exec\",\n      \"cmd\": \"npm run doc\"\n    },\n    {\n      \"path\": \"@semantic-release/git\",\n      \"assets\": [\n        \"docs\"\n      ],\n      \"message\": \"docs(release): ${nextRelease.version} [skip ci]\\n\\n${nextRelease.notes}\"\n    }\n  ]\n},\n```\n\n## [Lerna FAQ](https://github.com/lerna/lerna/blob/master/FAQ.md)\n\n`circle.yml`\n\n- https://circleci.com/blog/deploying-documentation-to-github-pages-with-continuous-integration/\n- https://circleci.com/blog/publishing-npm-packages-using-circleci-2-0/\n- https://circleci.com/blog/continuous-package-publishing-part-ii-automated-npm-publishing-with-circleci-and-packagecloud/\n"
  },
  {
    "path": "LICENSE.md",
    "content": "MIT License\n\nCopyright (c) 2024 Luigi De Rosa, Thierry Michel, Xavier Foucrier\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "NOTES.md",
    "content": "# Notes\n\n## Lerna/npm publish\n\n- `yarn run release`\n- `yarn run release:next`\n\n### Beta `publish`\n\n```sh\nyarn test\nlerna publish --canary --preid next --dist-tag next\nlerna publish --github-release --force-publish=*\nlerna publish --github-release\n```\n\nTo be tested: `--github-release`\n\n### Test `publish` with [verdaccio](https://www.npmjs.com/package/verdaccio)\n\n```sh\nnpm adduser --registry http://localhost:4873\nlerna publish --registry http://localhost:4873 --canary --preid next\n```\n"
  },
  {
    "path": "README.md",
    "content": "# barba.js – ![Stability](https://img.shields.io/badge/stability-stable-brightgreen.svg?style=flat-square) [![CircleCI](https://img.shields.io/circleci/project/github/barbajs/barba/main.svg?style=flat-square)](https://circleci.com/gh/barbajs/barba/tree/main) [![Coverage Status](https://img.shields.io/coveralls/github/barbajs/barba/main.svg?style=flat-square)](https://coveralls.io/github/barbajs/barba?branch=main) [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg?style=flat-square)](http://commitizen.github.io/cz-cli/) [![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg?style=flat-square)](https://conventionalcommits.org) [![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg?style=flat-square)](https://lerna.js.org/) [![License](https://img.shields.io/badge/license-MIT-green.svg?style=flat-square)](https://github.com/barbajs/barba/blob/main/LICENSE.md) [![All Contributors](https://img.shields.io/badge/all_contributors-73-orange.svg?style=flat-square)](#contributors) [![Slack workspace](https://img.shields.io/badge/slack-workspace-purple.svg?style=flat-square&logo=slack)](https://join.slack.com/t/barbajs/shared_invite/enQtNTU3NTAyMjkxMzAyLTkxYWUwZmM1YWQxMmNlYmE0ZjY4NDQxMGUxYjkwYWFlMzEzOWM4OTRhMWRmYTQyYzFlMmQ3OGFmYmI3MWY0OWY)\n\nCreate **badass, fluid and smooth transitions** between your website’s pages.\n\n[![barbajs](https://raw.githubusercontent.com/barbajs/.github/main/profile/barbajs.svg \"BarbaJS\")](https://barba.js.org/)\n\n## Intro\n\n**Barba.js** — aka *Barba* —  is a small *(7kb minified and compressed)* and easy-to-use library that helps you create fluid and smooth transitions between your website's pages. It makes your website run like a **SPA** *(Single Page Application)* and help reduce the delay between your pages, minimize browser HTTP requests and enhance your user's web experience.\n\n## Features\nBarba is user friendly, smart, extensible and futureproof. The library provides a bunch of **useful features that will make your website shine** like any other website, ever!\n\n* Simplified API - *written in **TypeScript** and works with `Promises`*\n* Cross-browser support - *[progressive enhancement](https://barba.js.org/docs/getstarted/browser-support/) for modern browsers*\n* DOM flexibility - *custom [markup](https://barba.js.org/docs/getstarted/markup/#DOM-structure), [namespaces](https://barba.js.org/docs/getstarted/markup/#Namespace) and `data` attribute [schema](https://barba.js.org/docs/getstarted/markup/#Schema)*\n* Hook system - *regulars lifecycle [methods](https://barba.js.org/docs/advanced/hooks/) for `Transitions` and `Views`*\n* Transition resolution - *[rules](https://barba.js.org/docs/advanced/transitions/#Rules) that let Barba pick the right transition*\n* Sync mode - *indicates whether leave and enter hooks should [“play together”](https://barba.js.org/docs/advanced/transitions/#Sync-mode)*\n* Page related code - *[custom logic](https://barba.js.org/docs/advanced/views/) attached to a specific `View`*\n* Modern browser strategies - *keep your site run [as fast as possible](https://barba.js.org/docs/advanced/strategies/)*\n* Cook like an expert - *improve your [development workflow](https://barba.js.org/docs/advanced/recipes/)*\n* Built-in utilities - *brought to you with a bunch of [useful methods](https://barba.js.org/docs/advanced/utils/)*\n* Plugin system - *supplied with [useful plugins](https://barba.js.org/docs/plugins/intro/)*\n* Wide community - *more than 980+ [amazing developers](https://barba.js.org/docs/getstarted/useful-links/#Developer) can help build your website!*\n\n## Documentation\nHere you will find the documentation describing **how to use** the library.\n\n1. [Website](https://barba.js.org/) - official Barba website\n2. [User guide](https://barba.js.org/docs/getstarted/intro/) - how to install and use the plugin\n3. [Lessons, courses and videos](https://barba.js.org/docs/getstarted/useful-links/#Learn) - for in-depth learning\n4. [Showcase](https://barba.js.org/showcase/) - selected works made with Barba\n5. [Developer API](https://barba.js.org/api/) - by developers, for developers\n\n> [!NOTE]\n> This guide assumes intermediate knowledge of HTML, CSS, and JavaScript. It is worth mentioning that all code examples use ES6+ syntax. If you are not comfortable with this syntax, we would encourage you to grasp the basics then come back.\n>\n> In case of emergency, check the [\"legacy\" code example](https://barba.js.org/docs/getstarted/legacy/).\n\n## Sponsor\nIf you like this library and want to give some recognition, it is now possible to **become a [Github sponsor](https://www.github.com/sponsors/xavierfoucrier)** and support this project by sponsoring BarbaJS maintainer on Github. Even if it's a small contribution, you participate in the effort of making **open source projects maintained for anyone**, and developers to be rewarded for their work/time.\n\n## Contribute\nIf you want to report a bug or request a new feature/improvement, please **read the project [contributors guidelines](.github/CONTRIBUTING.md) before**.\n\nThanks for taking time to contribute to Barba :tada: :+1:\n\n## Contributors\n\n<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->\n<!-- prettier-ignore-start -->\n<!-- markdownlint-disable -->\n<table>\n  <tbody>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://luruke.com\"><img src=\"https://avatars0.githubusercontent.com/u/61326?v=4?s=100\" width=\"100px;\" alt=\"Luigi De Rosa\"/><br /><sub><b>Luigi De Rosa</b></sub></a><br /><a href=\"#ideas-luruke\" title=\"Ideas, Planning, & Feedback\">🤔</a> <a href=\"https://github.com/barbajs/barba/commits?author=luruke\" title=\"Code\">💻</a> <a href=\"https://github.com/barbajs/barba/commits?author=luruke\" title=\"Documentation\">📖</a> <a href=\"#question-luruke\" title=\"Answering Questions\">💬</a> <a href=\"https://github.com/barbajs/barba/issues?q=author%3Aluruke\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/barbajs/barba/commits?author=luruke\" title=\"Tests\">⚠️</a> <a href=\"https://github.com/barbajs/barba/pulls?q=is%3Apr+reviewed-by%3Aluruke\" title=\"Reviewed Pull Requests\">👀</a> <a href=\"#infra-luruke\" title=\"Infrastructure (Hosting, Build-Tools, etc)\">🚇</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://thierrymichel.net\"><img src=\"https://avatars2.githubusercontent.com/u/806883?v=4?s=100\" width=\"100px;\" alt=\"Thierry Michel\"/><br /><sub><b>Thierry Michel</b></sub></a><br /><a href=\"#ideas-thierrymichel\" title=\"Ideas, Planning, & Feedback\">🤔</a> <a href=\"https://github.com/barbajs/barba/commits?author=thierrymichel\" title=\"Code\">💻</a> <a href=\"https://github.com/barbajs/barba/commits?author=thierrymichel\" title=\"Documentation\">📖</a> <a href=\"#question-thierrymichel\" title=\"Answering Questions\">💬</a> <a href=\"https://github.com/barbajs/barba/issues?q=author%3Athierrymichel\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/barbajs/barba/commits?author=thierrymichel\" title=\"Tests\">⚠️</a> <a href=\"https://github.com/barbajs/barba/pulls?q=is%3Apr+reviewed-by%3Athierrymichel\" title=\"Reviewed Pull Requests\">👀</a> <a href=\"#infra-thierrymichel\" title=\"Infrastructure (Hosting, Build-Tools, etc)\">🚇</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://xavierfoucrier.dev\"><img src=\"https://avatars1.githubusercontent.com/u/2471223?v=4?s=100\" width=\"100px;\" alt=\"Xavier Foucrier\"/><br /><sub><b>Xavier Foucrier</b></sub></a><br /><a href=\"#ideas-xavierfoucrier\" title=\"Ideas, Planning, & Feedback\">🤔</a> <a href=\"https://github.com/barbajs/barba/commits?author=xavierfoucrier\" title=\"Code\">💻</a> <a href=\"https://github.com/barbajs/barba/commits?author=xavierfoucrier\" title=\"Documentation\">📖</a> <a href=\"#question-xavierfoucrier\" title=\"Answering Questions\">💬</a> <a href=\"https://github.com/barbajs/barba/commits?author=xavierfoucrier\" title=\"Tests\">⚠️</a> <a href=\"https://github.com/barbajs/barba/pulls?q=is%3Apr+reviewed-by%3Axavierfoucrier\" title=\"Reviewed Pull Requests\">👀</a> <a href=\"https://github.com/barbajs/barba/issues?q=author%3Axavierfoucrier\" title=\"Bug reports\">🐛</a> <a href=\"#infra-xavierfoucrier\" title=\"Infrastructure (Hosting, Build-Tools, etc)\">🚇</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.thenerodesign.com\"><img src=\"https://avatars2.githubusercontent.com/u/858150?v=4?s=100\" width=\"100px;\" alt=\"Marco Grimaldi\"/><br /><sub><b>Marco Grimaldi</b></sub></a><br /><a href=\"#design-markog85\" title=\"Design\">🎨</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://ihatetomatoes.net\"><img src=\"https://avatars1.githubusercontent.com/u/735672?v=4?s=100\" width=\"100px;\" alt=\"Petr TIchy\"/><br /><sub><b>Petr TIchy</b></sub></a><br /><a href=\"#blog-Ihatetomatoes\" title=\"Blogposts\">📝</a> <a href=\"#tutorial-Ihatetomatoes\" title=\"Tutorials\">✅</a> <a href=\"#video-Ihatetomatoes\" title=\"Videos\">📹</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://studio123.ca\"><img src=\"https://avatars0.githubusercontent.com/u/22644154?v=4?s=100\" width=\"100px;\" alt=\"Cody Marcoux\"/><br /><sub><b>Cody Marcoux</b></sub></a><br /><a href=\"#question-c0mrx\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://philiphussak.com\"><img src=\"https://avatars1.githubusercontent.com/u/3285136?v=4?s=100\" width=\"100px;\" alt=\"Phil.\"/><br /><sub><b>Phil.</b></sub></a><br /><a href=\"#question-wiseoldman\" title=\"Answering Questions\">💬</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.fnool.com\"><img src=\"https://avatars0.githubusercontent.com/u/5812801?v=4?s=100\" width=\"100px;\" alt=\"Giorgio Finulli\"/><br /><sub><b>Giorgio Finulli</b></sub></a><br /><a href=\"#question-gfnool\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://www.thisisnota.studio\"><img src=\"https://avatars2.githubusercontent.com/u/6507123?v=4?s=100\" width=\"100px;\" alt=\"Wouter\"/><br /><sub><b>Wouter</b></sub></a><br /><a href=\"https://github.com/barbajs/barba/issues?q=author%3AWouter125\" title=\"Bug reports\">🐛</a> <a href=\"#question-Wouter125\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://selfaware.studio\"><img src=\"https://avatars2.githubusercontent.com/u/12376535?v=4?s=100\" width=\"100px;\" alt=\"Mike Wagz\"/><br /><sub><b>Mike Wagz</b></sub></a><br /><a href=\"#ideas-mikehwagz\" title=\"Ideas, Planning, & Feedback\">🤔</a> <a href=\"#question-mikehwagz\" title=\"Answering Questions\">💬</a> <a href=\"https://github.com/barbajs/barba/commits?author=mikehwagz\" title=\"Tests\">⚠️</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://www.youtube.com/c/redstapler_channel\"><img src=\"https://avatars0.githubusercontent.com/u/16864380?v=4?s=100\" width=\"100px;\" alt=\"Red Stapler\"/><br /><sub><b>Red Stapler</b></sub></a><br /><a href=\"#tutorial-theredstapler\" title=\"Tutorials\">✅</a> <a href=\"#video-theredstapler\" title=\"Videos\">📹</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.19h47.fr\"><img src=\"https://avatars1.githubusercontent.com/u/11242861?v=4?s=100\" width=\"100px;\" alt=\"Jérémy Levron\"/><br /><sub><b>Jérémy Levron</b></sub></a><br /><a href=\"#question-19h47\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://anhskohbo.github.io/\"><img src=\"https://avatars2.githubusercontent.com/u/1529454?v=4?s=100\" width=\"100px;\" alt=\"Nguyen Van Anh\"/><br /><sub><b>Nguyen Van Anh</b></sub></a><br /><a href=\"https://github.com/barbajs/barba/commits?author=anhskohbo\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.thedanielweber.com\"><img src=\"https://avatars1.githubusercontent.com/u/668910?v=4?s=100\" width=\"100px;\" alt=\"Daniel Weber\"/><br /><sub><b>Daniel Weber</b></sub></a><br /><a href=\"https://github.com/barbajs/barba/commits?author=dlwebdev\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.jmporchet.ch\"><img src=\"https://avatars3.githubusercontent.com/u/3099008?v=4?s=100\" width=\"100px;\" alt=\"Jean-Marie Porchet\"/><br /><sub><b>Jean-Marie Porchet</b></sub></a><br /><a href=\"https://github.com/barbajs/barba/commits?author=jmporchet\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://www.jamesdocherty.com/\"><img src=\"https://avatars1.githubusercontent.com/u/325490?v=4?s=100\" width=\"100px;\" alt=\"James\"/><br /><sub><b>James</b></sub></a><br /><a href=\"https://github.com/barbajs/barba/commits?author=docherty\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://ruggeri.io\"><img src=\"https://avatars0.githubusercontent.com/u/999162?v=4?s=100\" width=\"100px;\" alt=\"Nicholas\"/><br /><sub><b>Nicholas</b></sub></a><br /><a href=\"https://github.com/barbajs/barba/commits?author=nicholasruggeri\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://patrick.wtf\"><img src=\"https://avatars1.githubusercontent.com/u/667029?v=4?s=100\" width=\"100px;\" alt=\"Patrick Arminio\"/><br /><sub><b>Patrick Arminio</b></sub></a><br /><a href=\"https://github.com/barbajs/barba/commits?author=patrick91\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://angelogulina.it\"><img src=\"https://avatars0.githubusercontent.com/u/4223655?v=4?s=100\" width=\"100px;\" alt=\"A (from Sicily)\"/><br /><sub><b>A (from Sicily)</b></sub></a><br /><a href=\"https://github.com/barbajs/barba/commits?author=angelogulina\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/pavel-mazhuga\"><img src=\"https://avatars3.githubusercontent.com/u/29140681?v=4?s=100\" width=\"100px;\" alt=\"Pavel Mazhuga\"/><br /><sub><b>Pavel Mazhuga</b></sub></a><br /><a href=\"#question-pavel-mazhuga\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://dmdcode.it\"><img src=\"https://avatars0.githubusercontent.com/u/7113516?v=4?s=100\" width=\"100px;\" alt=\"Daniele De Matteo\"/><br /><sub><b>Daniele De Matteo</b></sub></a><br /><a href=\"#question-DMDc0de\" title=\"Answering Questions\">💬</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/aswinkumar863\"><img src=\"https://avatars0.githubusercontent.com/u/32381261?v=4?s=100\" width=\"100px;\" alt=\"aswinkumar863\"/><br /><sub><b>aswinkumar863</b></sub></a><br /><a href=\"#question-aswinkumar863\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/BounceIncHQ\"><img src=\"https://avatars0.githubusercontent.com/u/39249876?v=4?s=100\" width=\"100px;\" alt=\"BounceIncHQ\"/><br /><sub><b>BounceIncHQ</b></sub></a><br /><a href=\"#question-BounceIncHQ\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/gordonwes\"><img src=\"https://avatars3.githubusercontent.com/u/10758596?v=4?s=100\" width=\"100px;\" alt=\"gordonwes\"/><br /><sub><b>gordonwes</b></sub></a><br /><a href=\"#question-gordonwes\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/evfleet\"><img src=\"https://avatars2.githubusercontent.com/u/7504632?v=4?s=100\" width=\"100px;\" alt=\"Evan Fleet\"/><br /><sub><b>Evan Fleet</b></sub></a><br /><a href=\"#question-evfleet\" title=\"Answering Questions\">💬</a> <a href=\"https://github.com/barbajs/barba/issues?q=author%3Aevfleet\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.aligator-kom.de\"><img src=\"https://avatars2.githubusercontent.com/u/32126746?v=4?s=100\" width=\"100px;\" alt=\"Jörg\"/><br /><sub><b>Jörg</b></sub></a><br /><a href=\"#example-jd4Aligator\" title=\"Examples\">💡</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.zaak.ch\"><img src=\"https://avatars3.githubusercontent.com/u/12050808?v=4?s=100\" width=\"100px;\" alt=\"ZAAK\"/><br /><sub><b>ZAAK</b></sub></a><br /><a href=\"#example-StudioZAAK\" title=\"Examples\">💡</a> <a href=\"#question-StudioZAAK\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://leap-in.com\"><img src=\"https://avatars1.githubusercontent.com/u/42055102?v=4?s=100\" width=\"100px;\" alt=\"Masahiro Tonomura\"/><br /><sub><b>Masahiro Tonomura</b></sub></a><br /><a href=\"#example-leapincorp\" title=\"Examples\">💡</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/CassiusHR\"><img src=\"https://avatars1.githubusercontent.com/u/24419585?v=4?s=100\" width=\"100px;\" alt=\"CassiusHR\"/><br /><sub><b>CassiusHR</b></sub></a><br /><a href=\"#question-CassiusHR\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.shanemurphy.me\"><img src=\"https://avatars2.githubusercontent.com/u/3694619?v=4?s=100\" width=\"100px;\" alt=\"Shane Murphy\"/><br /><sub><b>Shane Murphy</b></sub></a><br /><a href=\"#question-shanewmurphy\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.dylanreeves.com\"><img src=\"https://avatars3.githubusercontent.com/u/1294637?v=4?s=100\" width=\"100px;\" alt=\"Dylan Reeves\"/><br /><sub><b>Dylan Reeves</b></sub></a><br /><a href=\"#question-watzing\" title=\"Answering Questions\">💬</a> <a href=\"#example-watzing\" title=\"Examples\">💡</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.quentinneyraud.fr\"><img src=\"https://avatars2.githubusercontent.com/u/9378568?v=4?s=100\" width=\"100px;\" alt=\"Quentin Neyraud\"/><br /><sub><b>Quentin Neyraud</b></sub></a><br /><a href=\"#question-quentinneyraud\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/tortilaman\"><img src=\"https://avatars2.githubusercontent.com/u/5018268?v=4?s=100\" width=\"100px;\" alt=\"tortilaman\"/><br /><sub><b>tortilaman</b></sub></a><br /><a href=\"#question-tortilaman\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/psntr\"><img src=\"https://avatars2.githubusercontent.com/u/20617539?v=4?s=100\" width=\"100px;\" alt=\"psntr\"/><br /><sub><b>psntr</b></sub></a><br /><a href=\"#question-psntr\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://thisbailiwick.com\"><img src=\"https://avatars3.githubusercontent.com/u/12637253?v=4?s=100\" width=\"100px;\" alt=\"Kevin Clark\"/><br /><sub><b>Kevin Clark</b></sub></a><br /><a href=\"#question-thisbailiwick\" title=\"Answering Questions\">💬</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://takodesign.one\"><img src=\"https://avatars2.githubusercontent.com/u/26543624?v=4?s=100\" width=\"100px;\" alt=\"Tadeas Kosek\"/><br /><sub><b>Tadeas Kosek</b></sub></a><br /><a href=\"#question-Tedowski\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/gustavo-a\"><img src=\"https://avatars2.githubusercontent.com/u/26806307?v=4?s=100\" width=\"100px;\" alt=\"Gustavo de Andrade\"/><br /><sub><b>Gustavo de Andrade</b></sub></a><br /><a href=\"#question-gustavo-a\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://durkangroup.com/\"><img src=\"https://avatars0.githubusercontent.com/u/25391588?v=4?s=100\" width=\"100px;\" alt=\"Clinton\"/><br /><sub><b>Clinton</b></sub></a><br /><a href=\"#question-crobbinsdg\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://www.spon.io\"><img src=\"https://avatars3.githubusercontent.com/u/3268717?v=4?s=100\" width=\"100px;\" alt=\"Dave Stockley\"/><br /><sub><b>Dave Stockley</b></sub></a><br /><a href=\"#question-magicspon\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://khaiknievel.carbonmade.com\"><img src=\"https://avatars1.githubusercontent.com/u/5792500?v=4?s=100\" width=\"100px;\" alt=\"khaiknievel\"/><br /><sub><b>khaiknievel</b></sub></a><br /><a href=\"#question-khaiknievel\" title=\"Answering Questions\">💬</a> <a href=\"https://github.com/barbajs/barba/issues?q=author%3Akhaiknievel\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.francescomichelini.com/\"><img src=\"https://avatars3.githubusercontent.com/u/5191941?v=4?s=100\" width=\"100px;\" alt=\"Francesco Michelini\"/><br /><sub><b>Francesco Michelini</b></sub></a><br /><a href=\"#question-kekkorider\" title=\"Answering Questions\">💬</a> <a href=\"#example-kekkorider\" title=\"Examples\">💡</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/FistMeNaruto\"><img src=\"https://avatars1.githubusercontent.com/u/13431677?v=4?s=100\" width=\"100px;\" alt=\"Domantas Petrauskas\"/><br /><sub><b>Domantas Petrauskas</b></sub></a><br /><a href=\"#question-FistMeNaruto\" title=\"Answering Questions\">💬</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://kylebrumm.com\"><img src=\"https://avatars3.githubusercontent.com/u/1709677?v=4?s=100\" width=\"100px;\" alt=\"Kyle Brumm\"/><br /><sub><b>Kyle Brumm</b></sub></a><br /><a href=\"#question-kjbrum\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/obelmont\"><img src=\"https://avatars3.githubusercontent.com/u/6540497?v=4?s=100\" width=\"100px;\" alt=\"Oliver Belmont\"/><br /><sub><b>Oliver Belmont</b></sub></a><br /><a href=\"#question-obelmont\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://lunelson.xyz/\"><img src=\"https://avatars1.githubusercontent.com/u/1242864?v=4?s=100\" width=\"100px;\" alt=\"Lu Nelson\"/><br /><sub><b>Lu Nelson</b></sub></a><br /><a href=\"#question-lunelson\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://bierdb.be\"><img src=\"https://avatars1.githubusercontent.com/u/1107185?v=4?s=100\" width=\"100px;\" alt=\"Bram Cordie\"/><br /><sub><b>Bram Cordie</b></sub></a><br /><a href=\"#question-bramcordie\" title=\"Answering Questions\">💬</a> <a href=\"#ideas-bramcordie\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://portfolio.schouman.info\"><img src=\"https://avatars1.githubusercontent.com/u/510652?v=4?s=100\" width=\"100px;\" alt=\"Michael Schouman\"/><br /><sub><b>Michael Schouman</b></sub></a><br /><a href=\"#question-metalmini\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://www.jumplink.eu\"><img src=\"https://avatars2.githubusercontent.com/u/1073989?v=4?s=100\" width=\"100px;\" alt=\"Pascal Garber\"/><br /><sub><b>Pascal Garber</b></sub></a><br /><a href=\"#question-JumpLink\" title=\"Answering Questions\">💬</a> <a href=\"#ideas-JumpLink\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://twitter.com/bfred_it\"><img src=\"https://avatars3.githubusercontent.com/u/1402241?v=4?s=100\" width=\"100px;\" alt=\"Federico Brigante\"/><br /><sub><b>Federico Brigante</b></sub></a><br /><a href=\"#question-bfred-it\" title=\"Answering Questions\">💬</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://coreylee.tokyo/\"><img src=\"https://avatars1.githubusercontent.com/u/1465865?v=4?s=100\" width=\"100px;\" alt=\"Corey Lee\"/><br /><sub><b>Corey Lee</b></sub></a><br /><a href=\"#question-factorzero\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.imls.uzh.ch/research/vonmering/people/milan-simonovic.html\"><img src=\"https://avatars3.githubusercontent.com/u/888008?v=4?s=100\" width=\"100px;\" alt=\"Milan Simonovic\"/><br /><sub><b>Milan Simonovic</b></sub></a><br /><a href=\"#question-mbsimonovic\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://djul.es\"><img src=\"https://avatars1.githubusercontent.com/u/196644?v=4?s=100\" width=\"100px;\" alt=\"Julien Vasseur\"/><br /><sub><b>Julien Vasseur</b></sub></a><br /><a href=\"#question-Djules\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/panwron\"><img src=\"https://avatars2.githubusercontent.com/u/8494786?v=4?s=100\" width=\"100px;\" alt=\"Maciej Wrona\"/><br /><sub><b>Maciej Wrona</b></sub></a><br /><a href=\"#question-panwron\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://terion.name\"><img src=\"https://avatars0.githubusercontent.com/u/1060205?v=4?s=100\" width=\"100px;\" alt=\"Terion\"/><br /><sub><b>Terion</b></sub></a><br /><a href=\"#ideas-terion-name\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/cartogram\"><img src=\"https://avatars2.githubusercontent.com/u/462077?v=4?s=100\" width=\"100px;\" alt=\"Matt Seccafien\"/><br /><sub><b>Matt Seccafien</b></sub></a><br /><a href=\"#ideas-cartogram\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.maxschulmeister.com\"><img src=\"https://avatars2.githubusercontent.com/u/15388185?v=4?s=100\" width=\"100px;\" alt=\"Max Schulmeister\"/><br /><sub><b>Max Schulmeister</b></sub></a><br /><a href=\"#ideas-max-schu\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://davidaase.com\"><img src=\"https://avatars3.githubusercontent.com/u/1521451?v=4?s=100\" width=\"100px;\" alt=\"David\"/><br /><sub><b>David</b></sub></a><br /><a href=\"#ideas-tipsy\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/pierrehenri220\"><img src=\"https://avatars3.githubusercontent.com/u/19267400?v=4?s=100\" width=\"100px;\" alt=\"Pierre-Henri Lavigne\"/><br /><sub><b>Pierre-Henri Lavigne</b></sub></a><br /><a href=\"#ideas-pierrehenri220\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/lsbyerley\"><img src=\"https://avatars0.githubusercontent.com/u/3066258?v=4?s=100\" width=\"100px;\" alt=\"lsbyerley\"/><br /><sub><b>lsbyerley</b></sub></a><br /><a href=\"#ideas-lsbyerley\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://gmorisseau.com/\"><img src=\"https://avatars2.githubusercontent.com/u/242203?v=4?s=100\" width=\"100px;\" alt=\"Guillaume M.\"/><br /><sub><b>Guillaume M.</b></sub></a><br /><a href=\"#ideas-theamnesic\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://oscarotero.com\"><img src=\"https://avatars3.githubusercontent.com/u/377873?v=4?s=100\" width=\"100px;\" alt=\"Oscar Otero\"/><br /><sub><b>Oscar Otero</b></sub></a><br /><a href=\"#ideas-oscarotero\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://twitter.com/nicooprat\"><img src=\"https://avatars0.githubusercontent.com/u/645641?v=4?s=100\" width=\"100px;\" alt=\"Nico Prat\"/><br /><sub><b>Nico Prat</b></sub></a><br /><a href=\"#ideas-nicooprat\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://marco.solazzi.me/\"><img src=\"https://avatars2.githubusercontent.com/u/104721?v=4?s=100\" width=\"100px;\" alt=\"Marco Solazzi\"/><br /><sub><b>Marco Solazzi</b></sub></a><br /><a href=\"https://github.com/barbajs/barba/issues?q=author%3Adwightjack\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/atoupet-toki\"><img src=\"https://avatars3.githubusercontent.com/u/38693082?v=4?s=100\" width=\"100px;\" alt=\"atoupet-toki\"/><br /><sub><b>atoupet-toki</b></sub></a><br /><a href=\"https://github.com/barbajs/barba/issues?q=author%3Aatoupet-toki\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/josias-r\"><img src=\"https://avatars1.githubusercontent.com/u/11424820?v=4?s=100\" width=\"100px;\" alt=\"Josias\"/><br /><sub><b>Josias</b></sub></a><br /><a href=\"https://github.com/barbajs/barba/issues?q=author%3Ajosias-r\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/OksanaRomaniv\"><img src=\"https://avatars1.githubusercontent.com/u/5724727?v=4?s=100\" width=\"100px;\" alt=\"Oksana Romaniv\"/><br /><sub><b>Oksana Romaniv</b></sub></a><br /><a href=\"https://github.com/barbajs/barba/issues?q=author%3AOksanaRomaniv\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://www.olivier-guilleux.com\"><img src=\"https://avatars3.githubusercontent.com/u/5804006?v=4?s=100\" width=\"100px;\" alt=\"Olivier Guilleux\"/><br /><sub><b>Olivier Guilleux</b></sub></a><br /><a href=\"https://github.com/barbajs/barba/issues?q=author%3Aoguilleux\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://liroopierre.com\"><img src=\"https://avatars3.githubusercontent.com/u/11197281?v=4?s=100\" width=\"100px;\" alt=\"Liroo Pierre ᵈᵉᵛ\"/><br /><sub><b>Liroo Pierre ᵈᵉᵛ</b></sub></a><br /><a href=\"https://github.com/barbajs/barba/commits?author=Liroo\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/lmartins\"><img src=\"https://avatars2.githubusercontent.com/u/151981?v=4?s=100\" width=\"100px;\" alt=\"Luis Martins\"/><br /><sub><b>Luis Martins</b></sub></a><br /><a href=\"https://github.com/barbajs/barba/issues?q=author%3Almartins\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://arraytheband.com.au\"><img src=\"https://avatars0.githubusercontent.com/u/41524?v=4?s=100\" width=\"100px;\" alt=\"Matthew\"/><br /><sub><b>Matthew</b></sub></a><br /><a href=\"#ideas-matthewjumpsoffbuildings\" title=\"Ideas, Planning, & Feedback\">🤔</a> <a href=\"#question-matthewjumpsoffbuildings\" title=\"Answering Questions\">💬</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://slgoetz.com\"><img src=\"https://avatars0.githubusercontent.com/u/393000?v=4?s=100\" width=\"100px;\" alt=\"Simon Goetz\"/><br /><sub><b>Simon Goetz</b></sub></a><br /><a href=\"https://github.com/barbajs/barba/issues?q=author%3ASlgoetz\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://luis.pt\"><img src=\"https://avatars3.githubusercontent.com/u/14956453?v=4?s=100\" width=\"100px;\" alt=\"Luís Carvalho\"/><br /><sub><b>Luís Carvalho</b></sub></a><br /><a href=\"#question-luis-pt\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/mrsamse\"><img src=\"https://avatars2.githubusercontent.com/u/20925205?v=4?s=100\" width=\"100px;\" alt=\"Samuel Berisha\"/><br /><sub><b>Samuel Berisha</b></sub></a><br /><a href=\"#question-mrsamse\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/andersonleite\"><img src=\"https://avatars.githubusercontent.com/u/52427?v=4?s=100\" width=\"100px;\" alt=\"Anderson Leite\"/><br /><sub><b>Anderson Leite</b></sub></a><br /><a href=\"#question-andersonleite\" title=\"Answering Questions\">💬</a> <a href=\"https://github.com/barbajs/barba/issues?q=author%3Aandersonleite\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://jaycollett.co/\"><img src=\"https://avatars.githubusercontent.com/u/13233809?v=4?s=100\" width=\"100px;\" alt=\"Jay Collett\"/><br /><sub><b>Jay Collett</b></sub></a><br /><a href=\"#question-JayBox325\" title=\"Answering Questions\">💬</a> <a href=\"https://github.com/barbajs/barba/issues?q=author%3AJayBox325\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/timgates42\"><img src=\"https://avatars.githubusercontent.com/u/47873678?v=4?s=100\" width=\"100px;\" alt=\"Tim Gates\"/><br /><sub><b>Tim Gates</b></sub></a><br /><a href=\"https://github.com/barbajs/barba/issues?q=author%3Atimgates42\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://www.nicolascusan.com/\"><img src=\"https://avatars.githubusercontent.com/u/1353931?v=4?s=100\" width=\"100px;\" alt=\"Nicolas Cusan\"/><br /><sub><b>Nicolas Cusan</b></sub></a><br /><a href=\"#question-nicolas-cusan\" title=\"Answering Questions\">💬</a> <a href=\"https://github.com/barbajs/barba/issues?q=author%3Anicolas-cusan\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/barbajs/barba/commits?author=nicolas-cusan\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://geraldnako.com/\"><img src=\"https://avatars.githubusercontent.com/u/5095859?v=4?s=100\" width=\"100px;\" alt=\"Gerald Nako\"/><br /><sub><b>Gerald Nako</b></sub></a><br /><a href=\"https://github.com/barbajs/barba/issues?q=author%3Ageraldnako\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/barbajs/barba/commits?author=geraldnako\" title=\"Code\">💻</a></td>\n    </tr>\n  </tbody>\n</table>\n\n<!-- markdownlint-restore -->\n<!-- prettier-ignore-end -->\n\n<!-- ALL-CONTRIBUTORS-LIST:END -->\n\n## License\nThe project is developed under the **MIT** license:\n\n- **Permissions**: This software and derivatives may be used for commercial purposes, you may distribute this software, this software may be modified and you may use and modify the software without distributing it.\n- **Conditions**: Include a copy of the license and copyright notice with the code.\n- **Limitations**: Software is provided without warranty and the software author/license owner cannot be held liable for damages.\n\nRead the [full license](LICENSE.md) for more information about your rights.\n"
  },
  {
    "path": "TODO.md",
    "content": "# Todos\n\n- [x][m] Router : allow leading slash ?\n- [x][m] Reload current page\n- [x][m] Prevent `xlink:href` on link enter (eg: SVG)\n- [x][s] No transitions ? weird behavior…\n- [ ][w] BS, how to fix it (definitely)\n- [ ][m] (npm)ignore .DS_Store files\n\n---\n\n- [ ] @barba/\n  - [ ] **transitions** (basic, ready-to-use. e.g.: fade, slide, …)\n  - [ ] **css** (add CSS classes via hooks)\n  - [ ] **loader** ??? (programatically fetch and cache pages - also see [quicklink](https://github.com/GoogleChromeLabs/quicklink))\n- [ ] Tests:\n  - [ ] unit tests\n  - [ ] e2e tests (puppetteer? / cypress?)\n- [ ] Documentation\n  - [ ] Manual (instructions, examples, …)\n  - [ ] Auto generated from code\n- [ ] Builds / releases\n  - [ ] auto-update version(s)\n  - [ ] auto-update changelogs\n  - [ ] auto-update file gzip size (website and readme)\n  - [ ] CI (tests, coverage on push, PR, …)\n  - [ ] Force git commit to follow a certain schema\n- [ ] License (find correct open source license)\n  - > Luigi said: anyone can do what they want, but:\n    >\n    > - they can't resell it as it is\n    > - I have the right in any moment to not allow a specific use\n  - NB: This seems conflicting with open source core principles\n    Following are the most \"restrictive\" :)\n    - [GNU AGPLv3](https://choosealicense.com/licenses/agpl-3.0/)\n    - [Open Software License 3.0](https://choosealicense.com/licenses/osl-3.0/)\n    - [European Union Public License 1.2](https://choosealicense.com/licenses/eupl-1.2/)\n- [ ] Community\n  - [x] Github issue template\n  - [x] Forum / chat -> [Slack](https://barbajs.slack.com)\n- [ ] Other\n  - [ ] Make jest work with `babel.config.js` (global + optional local merge)\n    - https://github.com/babel/babel/issues/7208\n    - https://github.com/facebook/jest/issues/6053#issuecomment-383632515\n    - https://babeljs.io/docs/en/options\n    - https://babeljs.io/docs/en/config-files\n    - ```\n          @barba/core:     import barba from '../src';\n          @barba/core:            ^^^^^\n          @barba/core:     SyntaxError: Unexpected identifier\n          @barba/core:       at ScriptTransformer._transformAndBuildScript (../../node_modules/jest-runtime/build/script_transformer.js:403:17)\n          @barba/core: babel.config.js:root\n          @barba/core: .babelrc.js:core\n      ```\n  - [ ] Repo transfer?\n    - [doc](https://help.github.com/articles/transferring-a-repository/)\n    - [hack post](https://francisco.io/blog/transferring-github-stars/)\n  - VSCode extensions recommendations? settings?\n"
  },
  {
    "path": "commitlint.config.js",
    "content": "module.exports = {\n  extends: ['ccgls'],\n};\n"
  },
  {
    "path": "cypress/fixtures/example.json",
    "content": "{\n  \"name\": \"Using fixtures to represent data\",\n  \"email\": \"hello@cypress.io\",\n  \"body\": \"Fixtures are a great way to mock data for responses to routes\"\n}"
  },
  {
    "path": "cypress/plugins/index.js",
    "content": "// ***********************************************************\n// This example plugins/index.js can be used to load plugins\n//\n// You can change the location of this file or turn off loading\n// the plugins file with the 'pluginsFile' configuration option.\n//\n// You can read more here:\n// https://on.cypress.io/plugins-guide\n// ***********************************************************\n\n// This function is called when a project is opened or re-opened (e.g. due to\n// the project's config changing)\n\n/* eslint-disable consistent-return, no-unused-vars */\nmodule.exports = (on, config) => {\n  // https://github.com/cypress-io/cypress/issues/1872#issuecomment-450807452\n  on('before:browser:launch', (browser = {}, args) => {\n    if (browser.name === 'chrome') {\n      // ^ make sure this is your browser name, you may\n      // be using 'canary' or 'chromium' for example, so change it to match!\n      args.push('--proxy-bypass-list=<-loopback>');\n\n      return args;\n    }\n  });\n};\n/* eslint-enable consistent-return, no-unused-vars */\n"
  },
  {
    "path": "cypress/support/commands.js",
    "content": "// ***********************************************\n// This example commands.js shows you how to\n// create various custom commands and overwrite\n// existing commands.\n//\n// For more comprehensive examples of custom\n// commands please read more here:\n// https://on.cypress.io/custom-commands\n// ***********************************************\n//\n//\n// -- This is a parent command --\n// Cypress.Commands.add(\"login\", (email, password) => { ... })\n//\n//\n// -- This is a child command --\n// Cypress.Commands.add(\"drag\", { prevSubject: 'element'}, (subject, options) => { ... })\n//\n//\n// -- This is a dual command --\n// Cypress.Commands.add(\"dismiss\", { prevSubject: 'optional'}, (subject, options) => { ... })\n//\n//\n// -- This is will overwrite an existing command --\n// Cypress.Commands.overwrite(\"visit\", (originalFn, url, options) => { ... })\n\n// Automatically prepend \"root path\" depending on package\n// TODO: it breaks \"run all\"\nCypress.Commands.overwrite('visit', (originalFn, url, options) => {\n  const r = /^packages\\/([a-z]*)\\/(__e2e__)\\/.*\\.spec.js$/;\n  const root = Cypress.spec.relative.replace(r, '$1/__web__');\n\n  originalFn(root + url, options);\n});\n\nCypress.Commands.add('prepare', (url, title, namespace) => {\n  // 1. Go to home\n  cy.visit(url);\n  // 2. Should have wrapper and container\n  cy.get('[data-barba=wrapper]')\n    .as('wrapper')\n    .should('exist');\n  cy.get('[data-barba=container]').should('exist');\n  // 3. Titles have correct content\n  cy.title().should('contain', title);\n  cy.get('[data-test=title]')\n    .as('h1') // Alias to @h1\n    .should('contain', title);\n  // 4. Aliases current container\n  cy.get('[data-test-container=current]').as('current');\n  // 4. Check namespace if provided\n  if (namespace) {\n    cy.get('@current').should('have.attr', 'data-barba-namespace', namespace);\n  }\n});\n\nCypress.Commands.add('final', (url, title, namespace) => {\n  // 0. Wrapper is the same\n  cy.get('@wrapper').should('have.attr', 'data-test-wrapper', 'current');\n  // 1. URL has changed\n  cy.url().should('include', url);\n  // 2. H1 has changed\n  cy.get('@h1').should('contain', title);\n  // 3. Page title has changed\n  cy.title().should('contain', title);\n  // 4. Current container has been removed\n  cy.get('@current').should('not.exist');\n  // 5. Next container exists\n  cy.get('[data-test-container=next]')\n    .as('next')\n    .should('exist');\n  // 6. Check namespace if provided\n  if (namespace) {\n    cy.get('@next').should('have.attr', 'data-barba-namespace', namespace);\n  }\n});\n"
  },
  {
    "path": "cypress/support/e2e.js",
    "content": "// ***********************************************************\n// This example support/index.js is processed and\n// loaded automatically before your test files.\n//\n// This is a great place to put global configuration and\n// behavior that modifies Cypress.\n//\n// You can change the location of this file or turn off\n// automatically serving support files with the\n// 'supportFile' configuration option.\n//\n// You can read more here:\n// https://on.cypress.io/configuration\n// ***********************************************************\n\n// Import commands.js using ES2015 syntax:\nimport './commands';\n\n// Alternatively you can use CommonJS syntax:\n// require('./commands')\n"
  },
  {
    "path": "cypress.config.ts",
    "content": "import { defineConfig } from 'cypress'\n\nexport default defineConfig({\n  fixturesFolder: './cypress/fixtures',\n  screenshotsFolder: './cypress/screenshots',\n  videosFolder: './cypress/videos',\n  projectId: 'ngfcig',\n  e2e: {\n    // We've imported your old cypress plugins here.\n    // You may want to clean this up later by importing these.\n    setupNodeEvents(on, config) {\n      return require('./cypress/plugins/index.js')(on, config)\n    },\n    baseUrl: 'http://localhost:8111/packages/',\n    specPattern: './packages/**/__e2e__/**/*.spec.js',\n  },\n})\n"
  },
  {
    "path": "documentation/theme/assets/css/override.css",
    "content": ".tsd-signature-symbol {\n  hyphens: auto;\n}\n\n/* Hack: hide layout instructions */\n.tsd-panel > hr:first-child,\n.tsd-panel > hr + p,\n.tsd-panel > hr + p + hr {\n  display: none;\n}\n\nblockquote {\n  border-left: 4px solid #e0e2e5;\n  margin-left: 0;\n  padding-left: 20px;\n  color: #69737d;\n}\n"
  },
  {
    "path": "documentation/theme/layouts/default.hbs",
    "content": "<!doctype html>\n<html class=\"default no-js\">\n\n<head>\n  <meta charset=\"utf-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n  <title>{{#ifCond model.name '==' project.name}}{{project.name}}{{else}}{{model.name}} | {{project.name}}{{/ifCond}}\n  </title>\n  <meta name=\"description\" content=\"\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n  <link rel=\"stylesheet\" href=\"{{relativeURL \"assets/css/main.css\"}}\">\n  <link rel=\"stylesheet\" href=\"{{relativeURL \"assets/css/override.css\"}}\">\n</head>\n\n<body>\n\n  {{> header}}\n\n  <div class=\"container container-main\">\n    <div class=\"row\">\n      <div class=\"col-8 col-content\">\n        {{{contents}}}\n      </div>\n      <div class=\"col-4 col-menu menu-sticky-wrap menu-highlight\">\n        <nav class=\"tsd-navigation primary\">\n          <ul>\n            {{#each navigation.children}}\n            {{> navigation}}\n            {{/each}}\n          </ul>\n        </nav>\n\n        <nav class=\"tsd-navigation secondary menu-sticky\">\n          <ul class=\"before-current\">\n            {{#each toc.children}}\n            {{> toc.root}}\n            {{/each}}\n          </ul>\n        </nav>\n      </div>\n    </div>\n  </div>\n\n  {{> footer}}\n\n  <div class=\"overlay\"></div>\n  <script src=\"{{relativeURL \"assets/js/main.js\"}}\"></script>\n  <script>if (location.protocol == 'file:') document.write('<script src=\"{{relativeURL \"assets/js/search.js\"}}\"><' + '/script>');</script>\n\n  {{> analytics}}\n\n</body>\n\n</html>\n"
  },
  {
    "path": "jest.config.js",
    "content": "module.exports = {\n  collectCoverageFrom: [\n    'packages/**/src/**/*.ts',\n    '!packages/**/src/**/*.d.ts',\n    '!packages/**/src/typings.ts',\n    '!packages/**/src/**/index.ts',\n    '!packages/**/src/polyfills/**.ts',\n    '!packages/core/src/utils/helpers.ts',\n  ],\n  coverageThreshold: {\n    global: {\n      statements: 95,\n      branches: 95,\n      functions: 95,\n      lines: 95,\n    },\n  },\n  preset: 'ts-jest',\n  resetMocks: true,\n  testEnvironment: 'jest-environment-jsdom-global',\n  testMatch: ['**/__tests__/**/*.test.ts'],\n  transformIgnorePatterns: ['<rootDir>.*(node_modules)(?!.*@barba.*).*$'],\n  verbose: true,\n  watchPlugins: ['jest-watch-lerna-packages'],\n};\n"
  },
  {
    "path": "lerna.json",
    "content": "{\n  \"command\": {\n    \"publish\": {\n      \"conventionalCommits\": true,\n      \"message\": \"chore(release): 🔖 publish\",\n      \"npmClient\": \"npm\"\n    },\n    \"version\": {\n      \"allowBranch\": \"main\"\n    }\n  },\n  \"npmClient\": \"yarn\",\n  \"packages\": [\n    \"packages/*\"\n  ],\n  \"version\": \"independent\",\n  \"$schema\": \"node_modules/lerna/schemas/lerna-schema.json\"\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"root\",\n  \"private\": true,\n  \"devDependencies\": {\n    \"@commitlint/cli\": \"^19.3.0\",\n    \"@commitlint/config-conventional\": \"^19.2.2\",\n    \"@commitlint/config-lerna-scopes\": \"^19.0.0\",\n    \"@types/jest\": \"24.9.1\",\n    \"@types/lodash\": \"^4.17.7\",\n    \"all-contributors-cli\": \"^6.26.1\",\n    \"babel-eslint\": \"^10.1.0\",\n    \"commitizen\": \"^4.3.0\",\n    \"commitlint-config-ccgls\": \"1.4.8\",\n    \"coveralls\": \"^3.1.1\",\n    \"cypress\": \"^13.13.2\",\n    \"cz-ccgls\": \"^0.4.6\",\n    \"eslint\": \"^8.57.0\",\n    \"eslint-plugin-cypress\": \"^2.15.2\",\n    \"gzip-size\": \"^7.0.0\",\n    \"http-server\": \"14.1.1\",\n    \"husky\": \"^9.1.4\",\n    \"jest\": \"26.3.0\",\n    \"jest-environment-jsdom-global\": \"^4.0.0\",\n    \"jest-watch-lerna-packages\": \"^1.1.0\",\n    \"lerna\": \"^8.1.7\",\n    \"lint-staged\": \"15.2.7\",\n    \"lodash\": \"^4.17.11\",\n    \"microbundle\": \"0.15.1\",\n    \"npm-run-all\": \"4.1.5\",\n    \"prettier\": \"^3.3.3\",\n    \"rimraf\": \"6.0.1\",\n    \"source-map-explorer\": \"2.5.3\",\n    \"start-server-and-test\": \"^1.15.5\",\n    \"ts-jest\": \"26.3.0\",\n    \"tslint\": \"^6.1.3\",\n    \"typedoc\": \"0.15.8\",\n    \"typedoc-plugin-external-module-name\": \"^4.0.6\",\n    \"typedoc-plugin-sourcefile-url\": \"^1.0.6\",\n    \"typescript\": \"^4.9.5\",\n    \"typescript-tslint-plugin\": \"1.0.2\",\n    \"wait-for-expect\": \"3.0.2\",\n    \"xhr-mock\": \"^2.4.1\"\n  },\n  \"license\": \"MIT\",\n  \"workspaces\": [\n    \"packages/*\"\n  ],\n  \"types\": \"typings\",\n  \"scripts\": {\n    \"prepare\": \"husky\",\n    \"build\": \"lerna run build\",\n    \"build:watch\": \"lerna run build:watch --parallel\",\n    \"clean\": \"rimraf docs && lerna clean\",\n    \"clear\": \"lerna run clear\",\n    \"commit\": \"npx git-cz || exit 0\",\n    \"commit-retry\": \"npx git-cz --retry || exit 0\",\n    \"coverage\": \"cat ./coverage/lcov.info | coveralls\",\n    \"doc\": \"typedoc packages/*/src --tsconfig typedoc.json --sourcefile-url-prefix 'https://github.com/barbajs/barba/tree/main/'\",\n    \"lint\": \"tslint packages/*/src/** packages/*/__tests__/**\",\n    \"ls\": \"lerna ls\",\n    \"prepublish\": \"yarn run build\",\n    \"release\": \"lerna publish && npm run tag:next\",\n    \"release:next\": \"lerna publish --dist-tag next\",\n    \"report\": \"lerna run report\",\n    \"size\": \"lerna run size\",\n    \"tag:latest\": \"lerna run tag:latest --npm-client=npm\",\n    \"tag:next\": \"lerna run tag:next --npm-client=npm\",\n    \"test\": \"npm-run-all lint build unit e2e\",\n    \"unit\": \"yarn jest --coverage\",\n    \"unit:ci\": \"yarn jest --coverage --maxWorkers=2\",\n    \"unit:watch\": \"yarn jest --watch --verbose false\",\n    \"e2e\": \"start-server-and-test cy:server :8111 cy:run\",\n    \"e2e:watch\": \"start-server-and-test cy:server :8111 cy:dev\",\n    \"cy:server\": \"http-server . -p 8111\",\n    \"cy:run\": \"cypress run --browser chrome --record --key 6f43f378-ecdc-4502-9635-b6f5c205429e\",\n    \"cy:dev\": \"cypress open\",\n    \"watch\": \"npm-run-all -p build:watch unit:watch\"\n  },\n  \"husky\": {\n    \"hooks\": {\n      \"pre-commit\": \"lerna run --concurrency 1 --stream precommit\",\n      \"commit-msg\": \"commitlint -E HUSKY_GIT_PARAMS\"\n    }\n  },\n  \"config\": {\n    \"commitizen\": {\n      \"path\": \"./node_modules/cz-ccgls\"\n    }\n  }\n}\n"
  },
  {
    "path": "packages/core/.npmignore",
    "content": "### Custom ###\n/__e2e__\n/__mocks__\n/__tests__\n/__web__\n/jest.config.js\n/mangle.json\n/*.md\n/.rts2*\n!/README.md\n!/CHANGELOG.md\n"
  },
  {
    "path": "packages/core/AUTHORS",
    "content": "Luigi De Rosa <lurukee@gmail.com> (https://luruke.com/)\nThierry Michel <thmichel@gmail.com> (https://www.epic.net/)\nXavier Foucrier <xavier.foucrier@gmail.com> (https://xavierfoucrier.dev/)\n"
  },
  {
    "path": "packages/core/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n## [2.10.3](https://github.com/barbajs/barba/compare/@barba/core@2.10.2...@barba/core@2.10.3) (2024-08-12)\n\n### Bug Fixes\n\n- **core:** :ambulance: hotfix event propagation ([6d35aa4](https://github.com/barbajs/barba/commit/6d35aa431673e6d37161772483f891d611fef8eb)), closes [#746](https://github.com/barbajs/barba/issues/746)\n\n## [2.10.2](https://github.com/barbajs/barba/compare/@barba/core@2.10.0...@barba/core@2.10.2) (2024-08-02)\n\n### Bug Fixes\n\n- **core:** :bug: fix popstate when no link event is present ([680e2e7](https://github.com/barbajs/barba/commit/680e2e73c0a77186ae22112f1cefa2deef9eea04))\n\n# [2.10.0](https://github.com/barbajs/barba/compare/@barba/core@2.9.7...@barba/core@2.10.0) (2024-05-10)\n\n### Bug Fixes\n\n- **core:** :bug: cache first page ([a45bc26](https://github.com/barbajs/barba/commit/a45bc2692802cbb36259604e11ad8cd680e4701f)), closes [#602](https://github.com/barbajs/barba/issues/602)\n- **core:** :bug: fix `data-barba-history=\"replace\"` attribute ([8e38a8f](https://github.com/barbajs/barba/commit/8e38a8f9097f68e92a1a18f42cf88edf1456d637))\n- **core:** :bug: fix container replacement in the dom ([aec3143](https://github.com/barbajs/barba/commit/aec314365942c53497a05b857f7170e9bb0b0a44)), closes [#479](https://github.com/barbajs/barba/issues/479)\n- **core:** :bug: fix DOMParser error on SSR ([cadba05](https://github.com/barbajs/barba/commit/cadba0512eb5459e325f7af82f210a92e05e24d5)), closes [#512](https://github.com/barbajs/barba/issues/512)\n- **core:** :bug: fix request header name case ([167988d](https://github.com/barbajs/barba/commit/167988ddc67654675816ca39d8d28980c423d229))\n- **core:** :bug: prevent `onLinkEnter` prefetch to cache relative URLs ([a7d15ac](https://github.com/barbajs/barba/commit/a7d15acb11f745107a4c11b5d783988a9eca7764))\n- **core:** :bug: prevent assistive technology to read out the entire page ([4baef3e](https://github.com/barbajs/barba/commit/4baef3e8171c0e5b3dd98b8ca886e5ff811a7513)), closes [#681](https://github.com/barbajs/barba/issues/681)\n- **core:** :bug: prevent programmatic prefetch to cache relative URLs ([a021236](https://github.com/barbajs/barba/commit/a021236668082a14d3c3c718acbc30ae0f5e9bdb))\n- **core:** :bug: properly match `self` transition ([f7bd01c](https://github.com/barbajs/barba/commit/f7bd01cfdb333c1d0afad109a7f74d01adcb78f1))\n- **core:** :bug: properly prevent `self` transition ([4c97b59](https://github.com/barbajs/barba/commit/4c97b59c86bc9e5ce9309621334d44849916299c)), closes [#700](https://github.com/barbajs/barba/issues/700)\n- **core:** :pencil2: fix `this.barba` typo ([707c3de](https://github.com/barbajs/barba/commit/707c3de77152dad11e98cb10877a57965e561623))\n- **core:** :pencil2: fix typos in tests ([a748356](https://github.com/barbajs/barba/commit/a748356daf77117a120783eee4750c16e7603ad2))\n- **core:** :rotating_light: align asterisks for jsdoc ([ff837db](https://github.com/barbajs/barba/commit/ff837dbd2569d051164fd6f72cbad2919361cf84))\n- **core:** :rotating_light: fix linter issues inside `core` ([5ae1432](https://github.com/barbajs/barba/commit/5ae1432d34a142154dc4a3928b7ab01a81ff232e))\n- **core:** :rotating_light: fix maxlength line issue ([45df0d6](https://github.com/barbajs/barba/commit/45df0d696f69c2cfbeca6f764d1e5ae465b8d177))\n- **core:** :rotating_light: sort imports alphabetically ([0ccbfda](https://github.com/barbajs/barba/commit/0ccbfdaf5c1a51c60240e4328b062ea8b63e3626))\n- **core:** :rotating_light: sort variables alphabetically ([6c2c3d7](https://github.com/barbajs/barba/commit/6c2c3d70b6f63bb796a95d4778919707f63054a7))\n- **core:** :white_check_mark: fix duplicate expect state ([085794b](https://github.com/barbajs/barba/commit/085794bac6fd32c2082c05c9d59c9135c0320b7f))\n- **core:** :white_check_mark: fix request tests ([151abff](https://github.com/barbajs/barba/commit/151abff58dc8658ef251a96c3fb32db865322f6f))\n- **core:** ✅ fix request tests ([79e207b](https://github.com/barbajs/barba/commit/79e207b4e7ff88c39a33f963d3833cfb9c2ba50b))\n- **core:** 🐛 fix transition with popstate event and query string ([e27736f](https://github.com/barbajs/barba/commit/e27736fc305d0315cbf0a01f74a9209c8337a02e)), closes [#587](https://github.com/barbajs/barba/issues/587)\n- **core:** 🚨 align asterisks for jsdoc ([811b3ab](https://github.com/barbajs/barba/commit/811b3ab0ea67933348228792b39240df01e3fe12))\n- **core:** timeout reload, go to next page instead ([2b8f59a](https://github.com/barbajs/barba/commit/2b8f59a11a1440c4dc9c89126c511fbec4f4bffd))\n\n### Features\n\n- **core:** :sparkles: add `cacheFirstPage` option ([4306972](https://github.com/barbajs/barba/commit/43069722744822853dbc459aea5ab5a4b8bd924f))\n- **core:** :sparkles: add `CacheStatus` to reflect Promise status ([61c28c7](https://github.com/barbajs/barba/commit/61c28c75fff686d19b03da3198776be293399e1b))\n- **core:** :sparkles: add `CacheTarget` type ([a4e9045](https://github.com/barbajs/barba/commit/a4e9045a7ad14cf40dae7bf3084cd8e9a9e89cd7))\n- **core:** :sparkles: add `getTarget` method ([1d187de](https://github.com/barbajs/barba/commit/1d187de72e11b2360b1e1f6c9f19a38d3fd94e97))\n- **core:** :sparkles: add `Headers` module ([141249d](https://github.com/barbajs/barba/commit/141249d3764e5791530e265793ec72722d67958d))\n- **core:** :sparkles: add `IDomSibling` interface ([d3acdb8](https://github.com/barbajs/barba/commit/d3acdb8dec3a494b5a17643312f778921155d22e))\n- **core:** :sparkles: add `IResponse` interface ([c2fa15a](https://github.com/barbajs/barba/commit/c2fa15acfe3d7c8b08659dd0da5d6b409e9609ad))\n- **core:** :sparkles: add a method to retrieve absolute href from URL ([ad96797](https://github.com/barbajs/barba/commit/ad967972a41a324dd9128855225f41bae6142587))\n- **core:** :sparkles: allow `CacheStatus` to be retrieved ([9970f21](https://github.com/barbajs/barba/commit/9970f216c4e629783a7f2a4f828bf8ca707fc70c))\n- **core:** :sparkles: allow custom `data` when adding to history ([2eaab1c](https://github.com/barbajs/barba/commit/2eaab1cf345462692951b9b09418484823e55bbb))\n- **core:** :sparkles: allow custom data in `barba.history` ([920880a](https://github.com/barbajs/barba/commit/920880a8573ee9fc1eb03fd75cce08c872be0d27)), closes [#630](https://github.com/barbajs/barba/issues/630)\n- **core:** :sparkles: allow programmatic `barba.history` management ([e1e4b5f](https://github.com/barbajs/barba/commit/e1e4b5f270cd9e08aa4981a89bb744a8834f41c1)), closes [#601](https://github.com/barbajs/barba/issues/601)\n- **core:** :sparkles: expose `getQuery` and `getHash` methods ([4456f4b](https://github.com/barbajs/barba/commit/4456f4b7d03cd9933a0ea43dd722298be82b9088))\n- **core:** :sparkles: implement `getSibling` method ([4bf2802](https://github.com/barbajs/barba/commit/4bf280265f21e4e5b6a628982d4155be0a6467a9))\n- **core:** :sparkles: pass the trigger event through `hooks` ([a2fef11](https://github.com/barbajs/barba/commit/a2fef11e7947667ff6386bd1e4ef680c30aaadeb)), closes [#622](https://github.com/barbajs/barba/issues/622)\n- **core:** :sparkles: properly manage server response ([ae94e2c](https://github.com/barbajs/barba/commit/ae94e2c929e20ef527f7c91fb2d006da7ae78a19))\n- **core:** :sparkles: resolve `CacheRequest` with `IResponse` instead ([1061245](https://github.com/barbajs/barba/commit/106124553200a6f8c30fe8bdc562c12d38e56b2f))\n- **core:** :sparkles: store `target` in the cache based on server response ([f321926](https://github.com/barbajs/barba/commit/f3219262bd161075d7478be39b60c4a5d3ae59b2))\n- **core:** :sparkles: store response url through `IResponse` interface ([1963609](https://github.com/barbajs/barba/commit/19636096af3128d9ebbf73e7d845a593f13000e2))\n- **core:** :sparkles: update cache `status` to reflect Promise state ([54edab1](https://github.com/barbajs/barba/commit/54edab19834f9e65024f18651c0634ca32f08e0b))\n- **core:** ♻️ add headers type definitions ([5d2f13f](https://github.com/barbajs/barba/commit/5d2f13f098aed2a407dd664a66300c49c62362c2))\n- **core:** ♻️ import `Headers` module ([1b6c418](https://github.com/barbajs/barba/commit/1b6c4181030c1e956fa43708f166f57315d6788d))\n- **core:** ♻️ pass headers to the `request` utility ([60fa820](https://github.com/barbajs/barba/commit/60fa8204ca75c3a925c36d7e8f2c44a550b9c075))\n- **core:** ✨ set custom request headers ([0edbffe](https://github.com/barbajs/barba/commit/0edbffea5d540ed35f1f85094d758c280a6e4d8d))\n\n## [2.9.7](https://github.com/barbajs/barba/compare/@barba/core@2.9.6...@barba/core@2.9.7) (2020-01-16)\n\n### Bug Fixes\n\n- **core:** :bug: fix once only transition resolved for page ([0e52e61](https://github.com/barbajs/barba/commit/0e52e616e9964ad98f28239b1341a71cf1d29f4a)), closes [#483](https://github.com/barbajs/barba/issues/483)\n\n## [2.9.6](https://github.com/barbajs/barba/compare/@barba/core@2.9.5...@barba/core@2.9.6) (2019-12-12)\n\n### Bug Fixes\n\n- **core:** :bug: fix route (object) resolution ([1fb344f](https://github.com/barbajs/barba/commit/1fb344f9f07fbe58c5893b09f59d471704c0c521))\n\n## [2.9.5](https://github.com/barbajs/barba/compare/@barba/core@2.9.4...@barba/core@2.9.5) (2019-12-09)\n\n### Bug Fixes\n\n- **core:** :bug: filter transition errors from request errors ([281c85f](https://github.com/barbajs/barba/commit/281c85fc7bbaf3d51ee58653468c48b2404152ea)), closes [#475](https://github.com/barbajs/barba/issues/475)\n\n## [2.9.4](https://github.com/barbajs/barba/compare/@barba/core@2.9.3...@barba/core@2.9.4) (2019-12-09)\n\n### Bug Fixes\n\n- **core:** :bug: fix cache management with ignore option ([d801813](https://github.com/barbajs/barba/commit/d801813976a130d41b3261e7de8f0bcdf5dcd581)), closes [#470](https://github.com/barbajs/barba/issues/470)\n\n## [2.9.3](https://github.com/barbajs/barba/compare/@barba/core@2.9.2...@barba/core@2.9.3) (2019-12-09)\n\n### Bug Fixes\n\n- **core:** :recycle: refactor history states ([08c83b8](https://github.com/barbajs/barba/commit/08c83b857d8ab3f7826631968afaabf76e1a2e87)), closes [#473](https://github.com/barbajs/barba/issues/473) [#472](https://github.com/barbajs/barba/issues/472)\n\n## [2.9.2](https://github.com/barbajs/barba/compare/@barba/core@2.9.1...@barba/core@2.9.2) (2019-11-25)\n\n### Bug Fixes\n\n- **root:** :art: improve typings for TS ([48f0637](https://github.com/barbajs/barba/commit/48f0637))\n\n## [2.9.1](https://github.com/barbajs/barba/compare/@barba/core@2.9.0...@barba/core@2.9.1) (2019-11-25)\n\n### Bug Fixes\n\n- **core:** :rotating_light: fix TS errors, improve TS defs ([a48acd2](https://github.com/barbajs/barba/commit/a48acd2)), closes [#468](https://github.com/barbajs/barba/issues/468)\n\n# [2.9.0](https://github.com/barbajs/barba/compare/@barba/core@2.8.0...@barba/core@2.9.0) (2019-11-25)\n\n### Bug Fixes\n\n- **core:** :bug: hooks: context can not be undefined ([f6bb536](https://github.com/barbajs/barba/commit/f6bb536)), closes [#468](https://github.com/barbajs/barba/issues/468)\n\n### Features\n\n- **core:** :sparkles: add replace history via data-attribute ([272a43f](https://github.com/barbajs/barba/commit/272a43f)), closes [#460](https://github.com/barbajs/barba/issues/460)\n\n# [2.8.0](https://github.com/barbajs/barba/compare/@barba/core@2.7.2...@barba/core@2.8.0) (2019-11-06)\n\n### Bug Fixes\n\n- **core:** :bug: compare ports for sameUrl prevent check ([e2a84e4](https://github.com/barbajs/barba/commit/e2a84e4)), closes [#463](https://github.com/barbajs/barba/issues/463)\n- **core:** :bug: popstate with unknown state (null) ([3369633](https://github.com/barbajs/barba/commit/3369633)), closes [#456](https://github.com/barbajs/barba/issues/456) [#466](https://github.com/barbajs/barba/issues/466)\n- **core:** :ok_hand: resolve once transitions ([20cafe1](https://github.com/barbajs/barba/commit/20cafe1)), closes [#439](https://github.com/barbajs/barba/issues/439)\n\n### Features\n\n- **core:** :loud_sound: add/improve error logs ([e67a17b](https://github.com/barbajs/barba/commit/e67a17b)), closes [#447](https://github.com/barbajs/barba/issues/447)\n\n## [2.7.2](https://github.com/barbajs/barba/compare/@barba/core@2.7.1...@barba/core@2.7.2) (2019-11-05)\n\n### Bug Fixes\n\n- **core:** :heavy_minus_sign: remove 'path' for URL resolution ([3875d0c](https://github.com/barbajs/barba/commit/3875d0c)), closes [#465](https://github.com/barbajs/barba/issues/465)\n- **root:** :bug: fix context for views and add to transitions ([9054673](https://github.com/barbajs/barba/commit/9054673)), closes [#467](https://github.com/barbajs/barba/issues/467)\n\n## [2.7.1](https://github.com/barbajs/barba/compare/@barba/core@2.7.0...@barba/core@2.7.1) (2019-10-27)\n\n**Note:** Version bump only for package @barba/core\n\n# [2.7.0](https://github.com/barbajs/barba/compare/@barba/core@2.6.1...@barba/core@2.7.0) (2019-10-27)\n\n### Bug Fixes\n\n- **core:** :bug: fix container + dom sibling insertion ([7f349a7](https://github.com/barbajs/barba/commit/7f349a7)), closes [#449](https://github.com/barbajs/barba/issues/449)\n- **core:** :ok_hand: move after hooks ([42742ea](https://github.com/barbajs/barba/commit/42742ea)), closes [#455](https://github.com/barbajs/barba/issues/455)\n\n### Features\n\n- **core:** :sparkles: add preventRunning option ([93f0b50](https://github.com/barbajs/barba/commit/93f0b50)), closes [#414](https://github.com/barbajs/barba/issues/414)\n\n## [2.6.1](https://github.com/barbajs/barba/compare/@barba/core@2.6.0...@barba/core@2.6.1) (2019-10-22)\n\n### Bug Fixes\n\n- **core:** :ambulance: fix URL with query/hash ([f5e639c](https://github.com/barbajs/barba/commit/f5e639c)), closes [#445](https://github.com/barbajs/barba/issues/445)\n- **core:** :recycle: improve url/href/path management ([159afdc](https://github.com/barbajs/barba/commit/159afdc))\n\n# [2.6.0](https://github.com/barbajs/barba/compare/@barba/core@2.5.1...@barba/core@2.6.0) (2019-08-22)\n\n### Features\n\n- **core:** :alembic: store scroll position in history ([0fb28e2](https://github.com/barbajs/barba/commit/0fb28e2))\n\n## [2.5.1](https://github.com/barbajs/barba/compare/@barba/core@2.5.0...@barba/core@2.5.1) (2019-08-22)\n\n### Bug Fixes\n\n- **core:** :bug: keep container position ([5482154](https://github.com/barbajs/barba/commit/5482154))\n\n# [2.5.0](https://github.com/barbajs/barba/compare/@barba/core@2.4.0...@barba/core@2.5.0) (2019-08-22)\n\n### Features\n\n- **core:** :ok_hand: replace popstate with back/forward ([c665052](https://github.com/barbajs/barba/commit/c665052))\n\n# [2.4.0](https://github.com/barbajs/barba/compare/@barba/core@2.3.16...@barba/core@2.4.0) (2019-08-02)\n\n### Features\n\n- **core:** :sparkles: add history size ([3b8d7fd](https://github.com/barbajs/barba/commit/3b8d7fd))\n\n## [2.3.16](https://github.com/barbajs/barba/compare/@barba/core@2.3.15...@barba/core@2.3.16) (2019-08-01)\n\n### Bug Fixes\n\n- **core:** :bug: Fix global hooks (before|afterEnter) on first load ([e948166](https://github.com/barbajs/barba/commit/e948166)), closes [#393](https://github.com/barbajs/barba/issues/393)\n\n## [2.3.15](https://github.com/barbajs/barba/compare/@barba/core@2.3.14...@barba/core@2.3.15) (2019-07-17)\n\n### Bug Fixes\n\n- **core:** :ok_hand: view hook on page load ([c631b54](https://github.com/barbajs/barba/commit/c631b54)), closes [#393](https://github.com/barbajs/barba/issues/393)\n\n## [2.3.14](https://github.com/barbajs/barba/compare/@barba/core@2.3.13...@barba/core@2.3.14) (2019-07-16)\n\n### Bug Fixes\n\n- **root:** :mute: remove print version ([be5aa73](https://github.com/barbajs/barba/commit/be5aa73)), closes [#415](https://github.com/barbajs/barba/issues/415)\n\n## [2.3.13](https://github.com/barbajs/barba/compare/@barba/core@2.3.12...@barba/core@2.3.13) (2019-07-16)\n\n### Bug Fixes\n\n- **core:** :bug: Clean url extend ([7667a8d](https://github.com/barbajs/barba/commit/7667a8d))\n- **core:** :bug: fix link with no href attribute ([e434ecb](https://github.com/barbajs/barba/commit/e434ecb))\n\n## [2.3.12](https://github.com/barbajs/barba/compare/@barba/core@2.3.11...@barba/core@2.3.12) (2019-06-26)\n\n### Bug Fixes\n\n- **core:** :ok_hand: improve support of SVG links ([19e7e5d](https://github.com/barbajs/barba/commit/19e7e5d))\n\n## [2.3.11](https://github.com/barbajs/barba/compare/@barba/core@2.3.10...@barba/core@2.3.11) (2019-06-25)\n\n### Bug Fixes\n\n- **core:** :bug: make page hook async ([10e66d9](https://github.com/barbajs/barba/commit/10e66d9))\n\n## [2.3.10](https://github.com/barbajs/barba/compare/@barba/core@2.3.9...@barba/core@2.3.10) (2019-06-11)\n\n### Bug Fixes\n\n- **core:** :bug: remove \"force repaint\" when new container is added ([5a34322](https://github.com/barbajs/barba/commit/5a34322))\n- **core:** :construction: fix \"glitch\" when new container added ([1286bf9](https://github.com/barbajs/barba/commit/1286bf9))\n\n## [2.3.9](https://github.com/barbajs/barba/compare/@barba/core@2.3.8...@barba/core@2.3.9) (2019-04-29)\n\n**Note:** Version bump only for package @barba/core\n\n## [2.3.8](https://github.com/barbajs/barba/compare/@barba/core@2.3.7...@barba/core@2.3.8) (2019-04-29)\n\n### Bug Fixes\n\n- **core:** :bug: fix sameUrl with query params ([fa79a6a](https://github.com/barbajs/barba/commit/fa79a6a)), closes [#389](https://github.com/barbajs/barba/issues/389)\n\n## [2.3.7](https://github.com/barbajs/barba/compare/@barba/core@2.3.6...@barba/core@2.3.7) (2019-04-29)\n\n### Bug Fixes\n\n- **core:** :bug: fix glitch on containers add/remove ([374660c](https://github.com/barbajs/barba/commit/374660c))\n\n## [2.3.6](https://github.com/barbajs/barba/compare/@barba/core@2.3.5...@barba/core@2.3.6) (2019-04-29)\n\n**Note:** Version bump only for package @barba/core\n\n## [2.3.5](https://github.com/barbajs/barba/compare/@barba/core@2.3.4...@barba/core@2.3.5) (2019-04-29)\n\n### Bug Fixes\n\n- **core:** :construction: fix history ([36d3393](https://github.com/barbajs/barba/commit/36d3393))\n\n## [2.3.4](https://github.com/barbajs/barba/compare/@barba/core@2.3.3...@barba/core@2.3.4) (2019-04-29)\n\n### Bug Fixes\n\n- **core:** :bug: fix object rule with no value ([4014fd8](https://github.com/barbajs/barba/commit/4014fd8))\n\n## [2.3.3](https://github.com/barbajs/barba/compare/@barba/core@2.3.2...@barba/core@2.3.3) (2019-04-23)\n\n### Bug Fixes\n\n- **core:** :bug: update title with \"next\" ([f8c1940](https://github.com/barbajs/barba/commit/f8c1940)), closes [#384](https://github.com/barbajs/barba/issues/384)\n\n## [2.3.2](https://github.com/barbajs/barba/compare/@barba/core@2.3.1...@barba/core@2.3.2) (2019-04-20)\n\n### Bug Fixes\n\n- **core:** :bug: remove current container at the end ([f6fab91](https://github.com/barbajs/barba/commit/f6fab91))\n\n## [2.3.1](https://github.com/barbajs/barba/compare/@barba/core@2.3.0...@barba/core@2.3.1) (2019-04-16)\n\n### Bug Fixes\n\n- **core:** :bug: do not cache rendered HTML ([0cc4b86](https://github.com/barbajs/barba/commit/0cc4b86)), closes [#383](https://github.com/barbajs/barba/issues/383)\n\n# [2.3.0](https://github.com/barbajs/barba/compare/@barba/core@2.2.0...@barba/core@2.3.0) (2019-04-14)\n\n### Features\n\n- **core:** :sparkles: add programmatically prefetch ([7b95ffd](https://github.com/barbajs/barba/commit/7b95ffd))\n\n# [2.2.0](https://github.com/barbajs/barba/compare/@barba/core@2.1.3...@barba/core@2.2.0) (2019-04-14)\n\n### Features\n\n- **core:** :art: allow global hooks to be asynchronous ([be5dccf](https://github.com/barbajs/barba/commit/be5dccf))\n\n## [2.1.3](https://github.com/barbajs/barba/compare/@barba/core@2.1.2...@barba/core@2.1.3) (2019-04-13)\n\n### Bug Fixes\n\n- **core:** :loud_sound: print version ([24dd2ea](https://github.com/barbajs/barba/commit/24dd2ea))\n\n### Reverts\n\n- **root:** :bug: revert failed release ([2b8a1ef](https://github.com/barbajs/barba/commit/2b8a1ef))\n\n## [2.1.3](https://github.com/barbajs/barba/compare/@barba/core@2.1.2...@barba/core@2.1.3) (2019-04-13)\n\n### Bug Fixes\n\n- **core:** :loud_sound: print version ([24dd2ea](https://github.com/barbajs/barba/commit/24dd2ea))\n\n## [2.1.2](https://github.com/barbajs/barba/compare/@barba/core@2.1.1...@barba/core@2.1.2) (2019-04-13)\n\n### Bug Fixes\n\n- **core:** :mute: remove debug logs ([f4ce952](https://github.com/barbajs/barba/commit/f4ce952))\n\n## [2.1.1](https://github.com/barbajs/barba/compare/@barba/core@2.1.0...@barba/core@2.1.1) (2019-04-13)\n\n### Bug Fixes\n\n- **core:** :bug: fix cache not working ([a01e122](https://github.com/barbajs/barba/commit/a01e122))\n- **core:** :bug: fix hook order ([716b062](https://github.com/barbajs/barba/commit/716b062))\n- **core:** :bug: fix hooks order in sync mode true ([b3c92d1](https://github.com/barbajs/barba/commit/b3c92d1))\n- **core:** :bug: fix popstate navigation ([f78ee11](https://github.com/barbajs/barba/commit/f78ee11)), closes [#359](https://github.com/barbajs/barba/issues/359)\n- **core:** :bug: fix sameUrl + anchors ([039f5d9](https://github.com/barbajs/barba/commit/039f5d9)), closes [#359](https://github.com/barbajs/barba/issues/359)\n- **core:** :bug: fix timeout error ([70b7805](https://github.com/barbajs/barba/commit/70b7805)), closes [#373](https://github.com/barbajs/barba/issues/373)\n- **core:** :bug: fix view.beforeEnter on barba ready ([5a09470](https://github.com/barbajs/barba/commit/5a09470)), closes [#360](https://github.com/barbajs/barba/issues/360)\n- **core:** :bug: fix wrong combo namespace / view hooks ([3c775a3](https://github.com/barbajs/barba/commit/3c775a3)), closes [#351](https://github.com/barbajs/barba/issues/351)\n- **core:** :checkered_flag: fix InvalidStateError on IE ([b9eece9](https://github.com/barbajs/barba/commit/b9eece9)), closes [#371](https://github.com/barbajs/barba/issues/371)\n- **core:** :green_apple: fix img[srcset] parsing ([8afe945](https://github.com/barbajs/barba/commit/8afe945)), closes [#362](https://github.com/barbajs/barba/issues/362)\n- **core:** :ok_hand: add Accept header ([94962ef](https://github.com/barbajs/barba/commit/94962ef))\n- **core:** :ok_hand: fix `beforeEnter` view hook ([0d11e44](https://github.com/barbajs/barba/commit/0d11e44))\n- **core:** :ok_hand: make main transition hooks public ([2c0cc28](https://github.com/barbajs/barba/commit/2c0cc28))\n- **core:** :ok_hand: make onRequestError public ([61193ad](https://github.com/barbajs/barba/commit/61193ad))\n\n# 2.1.0 (2019-03-17)\n\n### Bug Fixes\n\n- **core:** :bug: append next container correctly on sync mode ([dc62bd3](https://github.com/barbajs/barba/commit/dc62bd3)), closes [#4](https://github.com/barbajs/barba/issues/4)\n- **core:** :bug: fix `xlink:href` with SVG ([19ecd81](https://github.com/barbajs/barba/commit/19ecd81)), closes [#1](https://github.com/barbajs/barba/issues/1)\n- **css:** :bug: fix css with next tick ([63642bf](https://github.com/barbajs/barba/commit/63642bf))\n- **prefetch:** :bug: fix requestError ([33c213b](https://github.com/barbajs/barba/commit/33c213b))\n- **root:** :bug: force publish ([ddb8798](https://github.com/barbajs/barba/commit/ddb8798))\n- **root:** :ok_hand: replace error with warning when no transition ([661801e](https://github.com/barbajs/barba/commit/661801e))\n- :bug: fix case issues ([c6adcb3](https://github.com/barbajs/barba/commit/c6adcb3))\n\n### Features\n\n- **core:** :sparkles: add prevent custom + update README ([2fb4ec6](https://github.com/barbajs/barba/commit/2fb4ec6))\n- **css:** :recycle: add transitionend logic + big refactoring ([b775358](https://github.com/barbajs/barba/commit/b775358))\n- **css:** :tada: initial commit ([aed8206](https://github.com/barbajs/barba/commit/aed8206))\n- **root:** :sparkles: add logger + fixes ([6db3875](https://github.com/barbajs/barba/commit/6db3875))\n- **router:** :sparkles: add multiple properties to `route` ([4e92c83](https://github.com/barbajs/barba/commit/4e92c83))\n"
  },
  {
    "path": "packages/core/LICENSE",
    "content": "MIT License\n\nCopyright (c) 2024 Luigi De Rosa, Thierry Michel, Xavier Foucrier\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 all\ncopies 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 THE\nSOFTWARE.\n"
  },
  {
    "path": "packages/core/README.md",
    "content": "# @barba/core\n\n[![NPM version](https://img.shields.io/npm/v/@barba/core?style=flat-square)](https://www.npmjs.com/package/@barba/core)\n[![Dependencies](https://img.shields.io/librariesio/release/npm/@barba/core?style=flat-square)](https://github.com/barbajs/barba/network/dependencies)\n\n> TBD ([GitHub repo](https://github.com/barbajs/barba.js))\n\n## Install\n\nUsing npm:\n\n```sh\nnpm install --save-dev @barba/core\n```\n\nor using yarn:\n\n```sh\nyarn add @barba/core --dev\n```\n"
  },
  {
    "path": "packages/core/__e2e__/container.spec.js",
    "content": "/* eslint-disable cypress/no-unnecessary-waiting */\ndescribe('Transition', () => {\n  it('adds container at the right place', () => {\n    cy.prepare('/container.html', 'container', 'container');\n    cy.get('[data-test=sibling]').as('sibling');\n    cy.get('[data-test=link]').click();\n    cy.final('/page.html', 'page', 'page');\n    cy.get('@wrapper')\n      .children()\n      .eq(1)\n      .should('have.attr', 'data-test-container', 'next');\n    cy.get('@wrapper')\n      .children()\n      .eq(2)\n      .should('have.attr', 'data-test', 'sibling');\n  });\n\n  it('adds container at the right place [sync]', () => {\n    cy.prepare('/container.html', 'container', 'container');\n    cy.get('[data-test=sibling]').as('sibling');\n    cy.get('[data-test=\"link.sync\"]').click();\n    cy.final('/page.html', 'page', 'page');\n    cy.get('@wrapper')\n      .children()\n      .eq(1)\n      .should('have.attr', 'data-test-container', 'next');\n    cy.get('@wrapper')\n      .children()\n      .eq(2)\n      .should('have.attr', 'data-test', 'sibling');\n  });\n});\n"
  },
  {
    "path": "packages/core/__e2e__/default.spec.js",
    "content": "/* eslint-disable cypress/no-unnecessary-waiting */\ndescribe('Transition', () => {\n  it('works', () => {\n    cy.prepare('/index.html', 'home', 'home');\n    cy.wait(1000); // Wait for once complete\n    // Click link\n    cy.get('[data-test=link]').click();\n    cy.final('/page.html', 'page', 'page');\n  });\n});\n"
  },
  {
    "path": "packages/core/__e2e__/hooks.spec.js",
    "content": "/* eslint-disable no-mixed-operators, cypress/no-unnecessary-waiting */\nconst onceHooks = [\n  'global:beforeEnter',\n  // 'global:before',\n  // 'before',\n  'global:beforeOnce',\n  'beforeOnce',\n  'global:once',\n  'once',\n  'global:afterOnce',\n  'afterOnce',\n  // 'global:after',\n  // 'after',\n  'global:afterEnter',\n];\nconst hooksDefault = [\n  ...onceHooks,\n  'global:before',\n  'before',\n  'global:beforeLeave',\n  'beforeLeave',\n  'global:leave',\n  'leave',\n  'global:afterLeave',\n  'afterLeave',\n  'global:beforeEnter',\n  'beforeEnter',\n  'global:enter',\n  'enter',\n  'global:afterEnter',\n  'afterEnter',\n  'global:after',\n  'after',\n];\nconst hooksSync = [\n  ...onceHooks,\n  'global:before',\n  'before',\n  'global:beforeLeave',\n  'beforeLeave',\n  'global:beforeEnter',\n  'beforeEnter',\n  'global:leave',\n  'global:enter',\n  'leave',\n  'enter',\n  'global:afterLeave',\n  'afterLeave',\n  'global:afterEnter',\n  'afterEnter',\n  'global:after',\n  'after',\n];\n\nbeforeEach(() => {\n  cy.prepare('/index.html', 'home', 'home');\n  cy.get('[data-test=\"hooks-list\"]').as('hooks'); // Alias to @hooks\n});\nafterEach(() => {\n  cy.final('/page.html', 'page', 'page');\n});\n\ndescribe('Hooks', () => {\n  it('have default order', () => {\n    cy.wait(1000); // Wait for once complete\n    // Click link\n    cy.get('[data-test=\"link.hooks\"]').click();\n\n    // Checks…\n    hooksDefault.forEach((name, i) => {\n      cy.get('@hooks')\n        .find(`:nth-child(${i + 1})`)\n        .should('contain', name);\n    });\n  });\n  it('have sync order', () => {\n    cy.wait(1000); // Wait for once complete\n    // Click link\n    cy.get('[data-test=\"link.hooks-sync\"]').click();\n\n    // Checks…\n    hooksSync.forEach((name, i) => {\n      cy.get('@hooks')\n        .find(`:nth-child(${i + 1})`)\n        .should('contain', name);\n    });\n  });\n});\n"
  },
  {
    "path": "packages/core/__e2e__/href.spec.js",
    "content": "/* eslint-disable cypress/no-unnecessary-waiting */\ndescribe('Transition', () => {\n  const origin = 'http://localhost:8111';\n  const prefix = 'packages/core/__web__';\n  const page = 'page.html';\n  const query = '?query=string';\n  const hash = '#hash';\n\n  it('default URL', () => {\n    cy.prepare('/href.html', 'href', 'href');\n    cy.get('[data-test=link]').click();\n\n    cy.location().should(loc => {\n      expect(loc.href).to.eq(`${origin}/${prefix}/${page}`);\n      expect(loc.toString()).to.eq(`${origin}/${prefix}/${page}`);\n      expect(loc.pathname).to.eq(`/${prefix}/${page}`);\n    });\n    cy.final('/page.html', 'page', 'page');\n  });\n\n  it('query string URL', () => {\n    cy.prepare('/href.html', 'href', 'href');\n    cy.get('[data-test=query]').click();\n\n    cy.location().should(loc => {\n      expect(loc.href).to.eq(`${origin}/${prefix}/${page}${query}`);\n      expect(loc.toString()).to.eq(`${origin}/${prefix}/${page}${query}`);\n      expect(loc.pathname).to.eq(`/${prefix}/${page}`);\n      expect(loc.search).to.eq(query);\n    });\n    cy.final('/page.html', 'page', 'page');\n  });\n\n  it('hash URL', () => {\n    cy.prepare('/href.html', 'href', 'href');\n    cy.get('[data-test=hash]').click();\n\n    cy.location().should(loc => {\n      expect(loc.href).to.eq(`${origin}/${prefix}/${page}${hash}`);\n      expect(loc.toString()).to.eq(`${origin}/${prefix}/${page}${hash}`);\n      expect(loc.pathname).to.eq(`/${prefix}/${page}`);\n      expect(loc.hash).to.eq(hash);\n    });\n    cy.final('/page.html', 'page', 'page');\n  });\n\n  it('hash + query URL', () => {\n    cy.prepare('/href.html', 'href', 'href');\n    cy.get('[data-test=complex]').click();\n\n    cy.location().should(loc => {\n      expect(loc.href).to.eq(`${origin}/${prefix}/${page}${query}${hash}`);\n      expect(loc.toString()).to.eq(\n        `${origin}/${prefix}/${page}${query}${hash}`\n      );\n      expect(loc.pathname).to.eq(`/${prefix}/${page}`);\n      expect(loc.search).to.eq(query);\n      expect(loc.hash).to.eq(hash);\n    });\n    cy.final('/page.html', 'page', 'page');\n  });\n});\n"
  },
  {
    "path": "packages/core/__e2e__/views.spec.js",
    "content": "/* eslint-disable no-mixed-operators, cypress/no-unnecessary-waiting */\nconst loadHooks = ['beforeEnter', 'afterEnter'];\nconst transitionHooks = [\n  'beforeLeave',\n  'afterLeave',\n  'beforeEnter',\n  'afterEnter',\n];\n\nbeforeEach(() => {\n  cy.prepare('/views.html', 'home', 'home');\n  cy.get('[data-test=\"hooks-list\"]').as('hooks'); // Alias to @hooks\n});\nafterEach(() => {\n  cy.final('/page.html', 'page', 'page');\n});\n\ndescribe('Views hooks', () => {\n  it('have default order', () => {\n    cy.wait(1000); // Wait for once complete\n\n    // Checks…\n    loadHooks.forEach((name, i) => {\n      cy.get('@hooks')\n        .find(`:nth-child(${i + 1})`)\n        .should('contain', name);\n    });\n\n    // Click link\n    cy.get('[data-test=\"link.hooks\"]').click();\n\n    // Checks…\n    transitionHooks.forEach((name, i) => {\n      const j = i + loadHooks.length;\n\n      cy.get('@hooks')\n        .find(`:nth-child(${j + 1})`)\n        .should('contain', name);\n    });\n  });\n  // it('have sync order', () => {\n  //   cy.wait(1000); // Wait for once complete\n  //   // Click link\n  //   cy.get('[data-test=\"link.hooks-sync\"]').click();\n\n  //   // Checks…\n  //   hooksSync.forEach((name, i) => {\n  //     cy.get('@hooks')\n  //       .find(`:nth-child(${i + 1})`)\n  //       .should('contain', name);\n  //   });\n  // });\n});\n"
  },
  {
    "path": "packages/core/__mocks__/barba.ts",
    "content": "import barba from '../src';\nimport { ITransitionPage } from '../src/defs';\n\n/**\n * Init barba with basic DOM for testing\n */\nexport function init(transitions: ITransitionPage[] = []): any {\n  const wrapper = document.createElement('div');\n  const container = document.createElement('div');\n  const link = document.createElement('a');\n  const span = document.createElement('span');\n  const namespace = 'current';\n  const mouseover = document.createEvent('HTMLEvents');\n  const click = document.createEvent('HTMLEvents');\n\n  wrapper.dataset.barba = 'wrapper';\n  container.dataset.barba = 'container';\n  container.dataset.barbaNamespace = namespace;\n\n  document.title = 'Current page';\n  document.body.appendChild(wrapper);\n  wrapper.appendChild(container);\n  container.appendChild(link);\n  link.appendChild(span);\n  mouseover.initEvent('mouseover', true, false);\n  click.initEvent('click', true, false);\n\n  barba.init({ transitions });\n\n  return { wrapper, container, link, span, mouseover, click };\n}\n"
  },
  {
    "path": "packages/core/__mocks__/transitions.ts",
    "content": "import { ITransitionPage } from '../src/defs';\n\nconst namespace = 'n';\nconst route = 'r';\nconst custom = () => true;\nconst unamed: ITransitionPage[] = [\n  /* 0000 */ {}, // Nothing\n  /* 0010 */ { namespace }, // Namespace\n  /* 0011 */ { from: { namespace } },\n  /* 0012 */ { to: { namespace } },\n  /* 0013 */ { from: { namespace }, to: { namespace } },\n  /* 0100 */ { route }, // Route\n  /* 0101 */ { from: { route } },\n  /* 0102 */ { to: { route } },\n  /* 0103 */ { from: { route }, to: { route } },\n  /* 0110 */ { route, namespace }, // Route + namespace\n  /* 0111 */ { from: { route, namespace } }, // 10\n  /* 0112 */ { to: { route, namespace } },\n  /* 0113 */ { from: { route, namespace }, to: { route, namespace } },\n  /* 1000 */ { custom }, // Custom\n  /* 1001 */ { from: { custom } },\n  /* 1002 */ { to: { custom } },\n  /* 1003 */ { from: { custom }, to: { custom } }, // 16\n  /* 1010 */ { custom, namespace }, // Custom + namespace\n  /* 1011 */ { from: { custom, namespace } },\n  /* 1012 */ { to: { custom, namespace } },\n  /* 1013 */ { from: { custom, namespace }, to: { custom, namespace } },\n  /* 1100 */ { custom, route }, // Custom + route\n  /* 1101 */ { from: { custom, route } },\n  /* 1102 */ { to: { custom, route } },\n  /* 1103 */ { from: { custom, route }, to: { custom, route } },\n  /* 1110 */ { custom, route, namespace }, // Custom + route + namespace\n  /* 1111 */ { from: { custom, route, namespace } },\n  /* 1112 */ { to: { custom, route, namespace } },\n  /* 1113 */ {\n    from: { custom, route, namespace },\n    to: { custom, route, namespace },\n  },\n];\nconst named: ITransitionPage[] = unamed.map((t, i) => {\n  t.name = i.toString();\n\n  return t;\n});\n\nexport default named;\n"
  },
  {
    "path": "packages/core/__tests__/core/core.click.test.ts",
    "content": "import { init } from '../../__mocks__/barba';\nimport barba from '../../src';\n\nconst { link, span, click } = init();\n\n// Mocks\nbarba.page = jest.fn();\n\nafterEach(() => {\n  (global as any).jsdom.reconfigure({ url: 'http://localhost/' });\n});\n\nit('handle link click', () => {\n  link.href = 'foo';\n  span.dispatchEvent(click);\n\n  expect(barba.page).toHaveBeenCalledTimes(1);\n});\n\nit('handle link click with same url', () => {\n  link.href = 'http://localhost/';\n  span.dispatchEvent(click);\n\n  expect(barba.page).toHaveBeenCalledTimes(0);\n});\n\nit('handle link click with prevent', () => {\n  link.href = 'foo';\n  link.dataset.barbaPrevent = '';\n  span.dispatchEvent(click);\n\n  expect(barba.page).toHaveBeenCalledTimes(0);\n});\n\nit('handle link click with transition running', () => {\n  barba.go = jest.fn();\n  barba.transitions.isRunning = true;\n  link.href = 'foo';\n  delete link.dataset.barbaPrevent;\n  barba.preventRunning = false;\n  span.dispatchEvent(click);\n  barba.preventRunning = true;\n  span.dispatchEvent(click);\n\n  expect(barba.go).toHaveBeenCalledTimes(1);\n});\n"
  },
  {
    "path": "packages/core/__tests__/core/core.enter.test.ts",
    "content": "import waitForExpect from 'wait-for-expect';\nimport xhrMock from 'xhr-mock';\nimport { init } from '../../__mocks__/barba';\nimport barba from '../../src';\nimport { IUrlFull } from '../../src/defs';\nimport { parse } from '../../src/utils/url';\n\nconst { link, span, mouseover } = init();\n\nconst sameUrl = 'http://localhost/';\nconst sameHtml = `<html>\n<head>\n  <title>Current page</title>\n</head>\n<body>\n  <div data-barba=\"wrapper\">\n    <div data-barba=\"container\" data-barba-namespace=\"current\"></div>\n  </div>\n</body>\n</html>`;\n\n// Mocks\nlet spyHas: jest.SpyInstance;\nlet spySet: jest.SpyInstance;\n\nbeforeEach(() => {\n  spyHas = jest.spyOn(barba.cache, 'has');\n  spySet = jest.spyOn(barba.cache, 'set');\n  xhrMock.setup();\n  xhrMock.error(() => {}); // tslint:disable-line:no-empty\n});\nafterEach(() => {\n  link.removeAttribute('data-barba-prevent');\n  spyHas.mockRestore();\n  spySet.mockRestore();\n  xhrMock.teardown();\n});\n\nit('handle link enter', () => {\n  link.href = 'foo';\n  span.dispatchEvent(mouseover);\n\n  expect(spyHas).toHaveBeenCalledTimes(1);\n  expect(spySet).toHaveBeenCalledTimes(1);\n});\n\nit('handle link enter with same url', () => {\n  barba.cache.set(sameUrl, Promise.resolve({\n    html: sameHtml,\n    url: {\n      href: sameUrl,\n      ...parse(sameUrl)\n    } as IUrlFull,\n  }), 'init', 'pending');\n  spySet.mockRestore();\n  link.href = sameUrl;\n  span.dispatchEvent(mouseover);\n\n  expect(spyHas).toHaveBeenCalledTimes(1);\n  expect(spySet).toHaveBeenCalledTimes(0);\n});\n\nit('handle bad request', async () => {\n  barba.logger.error = jest.fn();\n  xhrMock.get('http://localhost/bad', (req, res) => res.status(500));\n  xhrMock.error(() => {}); // tslint:disable-line:no-empty\n  link.href = 'bad';\n  span.dispatchEvent(mouseover);\n\n  expect(spyHas).toHaveBeenCalledTimes(1);\n  expect(spySet).toHaveBeenCalledTimes(1);\n  await waitForExpect(() => {\n    expect(barba.logger.error).toHaveBeenCalledTimes(1);\n  });\n});\n\nit('handle link enter with prevent link', () => {\n  link.href = 'foo';\n  link.dataset.barbaPrevent = '';\n  span.dispatchEvent(mouseover);\n\n  expect(spyHas).toHaveBeenCalledTimes(0);\n  expect(spySet).toHaveBeenCalledTimes(0);\n});\n\nit('handle link enter with prevent url', () => {\n  barba.destroy();\n  barba.init({ prefetchIgnore: '/foo' });\n  spyHas = jest.spyOn(barba.cache, 'has');\n  spySet = jest.spyOn(barba.cache, 'set');\n\n  link.href = '/foo';\n  span.dispatchEvent(mouseover);\n\n  expect(spyHas).toHaveBeenCalledTimes(0);\n  expect(spySet).toHaveBeenCalledTimes(0);\n});\n"
  },
  {
    "path": "packages/core/__tests__/core/core.force.test.ts",
    "content": "import barba from '../../src';\n\nit('force url change', () => {\n  Object.defineProperty(window, 'location', {\n    writable: true,\n    value: { assign: jest.fn() }\n  })\n\n  const url = 'http://localhost/foo.html';\n\n  barba.force(url);\n\n  expect(window.location.assign).toHaveBeenCalledTimes(1);\n});\n"
  },
  {
    "path": "packages/core/__tests__/core/core.go.test.ts",
    "content": "/* tslint:disable:no-empty no-string-literal */\nimport { init } from '../../__mocks__/barba';\nimport barba from '../../src';\nimport { hooks } from '../../src/hooks';\nimport { schemaAttribute } from '../../src/schemas/attribute';\n\n// Needed for \"request\" module\n(global as any).Headers = class {};\n\nconst namespace = 'next';\nconst nextUrl = 'http://localhost/foo';\n\n// Mocks\nlet spyHistory: jest.SpyInstance;\n\nbeforeEach(() => {\n  init();\n  // barba.init();\n\n  self.fetch = jest.fn().mockImplementation(() => ({\n    status: 200,\n    text: () =>\n      Promise.resolve(`<html>\n    <body>\n      <div data-barba=\"wrapper\">\n        <div data-barba=\"container\" data-barba-namespace=\"${namespace}\"></div>\n      </div>\n    </body>\n  </html>`),\n  }));\n});\nafterEach(() => {\n  barba.destroy();\n  spyHistory && spyHistory.mockRestore();\n  (global as any).jsdom.reconfigure({ url: 'http://localhost/' });\n});\n\nit('do go', async () => {\n  barba.page = jest.fn();\n\n  await barba.go('http://localhost/foo');\n\n  expect(barba.page).toHaveBeenCalledWith(\n    'http://localhost/foo',\n    'barba',\n    undefined,\n    false\n  );\n});\n\nit('force when manager running', async () => {\n  barba.force = jest.fn();\n  barba.page = jest.fn();\n  hooks.do = jest.fn();\n\n  barba.transitions.store.add('transition', { leave() {}, enter() {} });\n  barba.transitions['_running'] = true;\n  await barba.go(nextUrl, 'barba');\n\n  expect(barba.force).toHaveBeenCalledTimes(1);\n  expect(hooks.do).not.toHaveBeenCalled();\n  expect(barba.page).not.toHaveBeenCalled();\n\n  barba.transitions['_running'] = false;\n});\n\nit('prevent same url with no self transition', async () => {\n  barba.page = jest.fn();\n\n  await barba.go('http://localhost/');\n\n  expect(barba.page).not.toHaveBeenCalled();\n});\n\nit('use self transition on same url [barba]', async () => {\n  barba.page = jest.fn();\n  barba.transitions.store.add('transition', { name: 'self' });\n\n  await barba.go('http://localhost/');\n\n  expect(barba.page).toHaveBeenCalledWith(\n    'http://localhost/',\n    'barba',\n    undefined,\n    true\n  );\n});\n\nit('use self transition on same url [popstate]', async () => {\n  barba.page = jest.fn();\n  barba.transitions.store.add('transition', { name: 'self' });\n\n  const event = {\n    state: {\n      index: 0,\n    },\n    stopPropagation() {},\n    preventDefault() {},\n  } as PopStateEvent;\n\n  await barba.go('http://localhost/', 'popstate', event);\n\n  expect(barba.page).toHaveBeenCalledWith(\n    'http://localhost/',\n    'popstate',\n    event,\n    true\n  );\n});\n\nit('add history', async () => {\n  spyHistory = jest.spyOn(barba.history, 'add');\n\n  await barba.go('http://localhost/foo');\n\n  expect(barba.history.add).toHaveBeenCalledWith(\n    'http://localhost/foo',\n    'barba'\n  );\n});\n\nit('change history', async () => {\n  spyHistory = jest.spyOn(barba.history, 'change');\n\n  await barba.prefetch('http://localhost/');\n  await barba.go('http://localhost/foo', 'barba');\n  await barba.go('http://localhost/', 'barba');\n\n  expect(barba.history.change).toHaveBeenCalledTimes(2);\n});\n\nit('manage direction', async () => {\n  barba.page = jest.fn();\n\n  const event = {\n    state: {\n      index: 1,\n    },\n    stopPropagation() {},\n    preventDefault() {},\n  } as PopStateEvent;\n\n  await barba.go('http://localhost/foo');\n  await barba.go('http://localhost/bar');\n  await barba.go('http://localhost/foo', 'popstate', event);\n\n  expect(barba.page).toHaveBeenCalledWith(\n    'http://localhost/foo',\n    'back',\n    event,\n    false\n  );\n});\n"
  },
  {
    "path": "packages/core/__tests__/core/core.init.test.ts",
    "content": "/* tslint:disable:no-string-literal */\nimport barba from '../../src';\nimport { PreventCheck } from '../../src/defs';\n\nconst wrapper = document.createElement('div');\nconst container = document.createElement('div');\nconst namespace = 'ns';\n\nwrapper.dataset.barba = 'wrapper';\ncontainer.dataset.barba = 'container';\ncontainer.dataset.barbaNamespace = namespace;\n\n/**\n * Mock init\n */\nfunction init() {\n  barba.init();\n}\n\nbeforeEach(() => {\n  document.body.appendChild(wrapper);\n  wrapper.appendChild(container);\n});\n\nafterEach(() => {\n  document.body.innerHTML = '';\n});\n\nit('needs barba wrapper', () => {\n  wrapper.remove();\n  expect(init).toThrow('No Barba wrapper found');\n});\n\nit('needs barba container', () => {\n  container.remove();\n  expect(init).toThrow('No Barba container found');\n});\n\nit('needs valid prevent custom', () => {\n  const start = () => {\n    barba.init({ prevent: ('bad' as unknown) as PreventCheck });\n  };\n\n  expect(start).toThrow('Prevent should be a function');\n  barba.prevent.add = jest.fn();\n  expect(barba.prevent.add).not.toHaveBeenCalled();\n});\n\nit('adds prevent custom', () => {\n  barba.init({ prevent: () => true });\n  expect(barba.prevent.tests.has('preventCustom')).toBeTruthy();\n});\n\nit('has DOM elements', () => {\n  barba.init();\n  expect(barba.wrapper).toBe(wrapper);\n  expect(barba.data.current.container).toBe(container);\n});\n\nit('has current page content', () => {\n  barba.init();\n  expect(barba.data.current).toBeDefined();\n  expect(barba.data.current.namespace).toBe(namespace);\n  expect(barba.data.current.url).toEqual({\n    hash: undefined,\n    href: 'http://localhost/',\n    path: '/',\n    port: 80,\n    query: {},\n  });\n  expect(barba.data.current.container).toBe(container);\n  expect(barba.data.current.html).toMatch(/^<html>.+<\\/html>$/);\n});\n\nit('init history', () => {\n  barba.init();\n  expect(barba.history.current).toEqual({\n    data: {},\n    ns: 'ns',\n    scroll: {\n      x: 0,\n      y: 0,\n    },\n    url: 'http://localhost/',\n  });\n});\n\nit('calls once', () => {\n  barba.once = jest.fn();\n  barba.init();\n  expect(barba.once).toHaveBeenCalledTimes(1);\n});\n\nit('gets wrapper', () => {\n  barba.init();\n  expect(barba.wrapper).toBe(wrapper);\n});\n\nit('has other options', () => {\n  wrapper.dataset.highway = 'main';\n  container.dataset.highway = 'container';\n\n  barba.init({\n    requestError() {\n      return false;\n    },\n    schema: { prefix: 'data-highway', wrapper: 'main' },\n    timeout: 0,\n    transitions: [],\n    views: [],\n  });\n\n  const requestError = () =>\n    barba['_requestCustomError'](\n      'barba',\n      'click',\n      'foo.html',\n      new Error('test')\n    );\n\n  expect(barba.timeout).toBe(0);\n  expect(requestError()).toBeFalsy();\n  expect(barba.wrapper).toBe(wrapper);\n});\n\nit('cache the first rendered page', () => {\n  barba.init({\n    cacheFirstPage: true,\n  });\n\n  expect(barba.cache.has('http://localhost/')).toBeTruthy();\n});\n"
  },
  {
    "path": "packages/core/__tests__/core/core.logger.test.ts",
    "content": "import { init } from '../../__mocks__/barba';\nimport barba from '../../src';\nimport { Logger } from '../../src/modules/Logger';\n\ninit();\n\nit('has default level log', () => {\n  expect(Logger.getLevel()).toBe(0);\n});\n\nit('has debug level log', () => {\n  barba.init({ debug: true });\n  expect(Logger.getLevel()).toBe(4);\n});\n\nit('has custom level log', () => {\n  barba.init({ logLevel: 'error' });\n  expect(Logger.getLevel()).toBe(1);\n});\n"
  },
  {
    "path": "packages/core/__tests__/core/core.once.test.ts",
    "content": "/* tslint:disable:no-empty */\nimport { init } from '../../__mocks__/barba';\nimport barba from '../../src';\nimport { ITransitionData } from '../../src/defs';\nimport { Logger } from '../../src/modules/Logger';\n\ninit();\n\nconst data: ITransitionData = {\n  ...barba.data,\n  trigger: 'barba',\n};\n\nafterEach(() => {\n  barba.destroy();\n});\n\nit('do once', async () => {\n  const t = { once() {} };\n  const spyOnce = jest.spyOn(barba.transitions, 'doOnce');\n\n  barba.transitions.store.add('transition', t);\n\n  await barba.once(data);\n\n  expect(spyOnce).toHaveBeenCalledTimes(1);\n  spyOnce.mockRestore();\n});\n"
  },
  {
    "path": "packages/core/__tests__/core/core.page.test.ts",
    "content": "/* tslint:disable:no-empty no-string-literal */\nimport xhrMock from 'xhr-mock';\nimport { init } from '../../__mocks__/barba';\nimport barba from '../../src';\nimport { IUrlFull } from '../../src/defs';\nimport { hooks } from '../../src/hooks';\nimport { Logger } from '../../src/modules/Logger';\nimport { schemaAttribute } from '../../src/schemas/attribute';\nimport { parse } from '../../src/utils/url';\n\n// Silence is gold… :)\nLogger.setLevel('off');\n\n// Needed for \"request\" module\n(global as any).Headers = class {};\n\nconst namespace = 'next';\nconst checkDoc = new RegExp(\n  `^<html>[\\\\s\\\\S]+body[\\\\s\\\\S]+${schemaAttribute.wrapper}[\\\\s\\\\S]+${schemaAttribute.container}[\\\\s\\\\S]+${namespace}[\\\\s\\\\S]+</html>$`\n);\nconst t = { leave() {}, enter() {} };\nconst sameUrl = 'http://localhost/';\nconst nextUrl = 'http://localhost/foo';\n\ninit();\n\nlet spyCacheHas: jest.SpyInstance;\nlet spyCacheGet: jest.SpyInstance;\nlet spyCacheSet: jest.SpyInstance;\nlet spyCacheUpdate: jest.SpyInstance;\nlet spyCacheGetAction: jest.SpyInstance;\nlet spyPage: jest.SpyInstance;\n\nconst sameHtml = `<html>\n<head>\n  <title>Current page</title>\n</head>\n<body>\n  <div data-barba=\"wrapper\">\n    <div data-barba=\"container\" data-barba-namespace=\"current\"></div>\n  </div>\n</body>\n</html>`;\n\nbeforeEach(() => {\n  barba.init();\n  xhrMock.setup();\n  xhrMock.get(sameUrl, (req, res) => res.status(200).body(sameHtml));\n  xhrMock.get(nextUrl, (req, res) =>\n    res.status(200).body(`<html>\n    <head>\n      <title>New page</title>\n    </head>\n    <body>\n      <div data-barba=\"wrapper\">\n        <div data-barba=\"container\" data-barba-namespace=\"${namespace}\"></div>\n      </div>\n    </body>\n  </html>`)\n  );\n\n  spyCacheHas = jest.spyOn(barba.cache, 'has');\n  spyCacheGet = jest.spyOn(barba.cache, 'get');\n  spyCacheSet = jest.spyOn(barba.cache, 'set');\n  spyCacheUpdate = jest.spyOn(barba.cache, 'update');\n  spyCacheGetAction = jest.spyOn(barba.cache, 'getAction');\n  spyPage = jest.spyOn(barba.transitions, 'doPage');\n});\nafterEach(() => {\n  spyCacheHas.mockRestore();\n  spyCacheGet.mockRestore();\n  spyCacheSet.mockRestore();\n  spyCacheUpdate.mockRestore();\n  spyCacheGetAction.mockRestore();\n  spyPage.mockRestore();\n  xhrMock.teardown();\n  barba.destroy();\n});\n\nit('do page', async () => {\n  barba.history.update = jest.fn();\n  hooks.do = jest.fn();\n\n  barba.transitions.store.add('transition', t);\n  const data = {\n    ...barba.data,\n    trigger: 'barba',\n  };\n\n  await barba.page(nextUrl, 'barba', undefined, false);\n\n  expect(spyCacheHas).toHaveBeenCalledTimes(1);\n  expect(spyCacheSet).toHaveBeenCalledTimes(1);\n  expect(barba.history.update).toHaveBeenCalledTimes(1);\n  expect(hooks.do).toHaveBeenNthCalledWith(1, 'page', data);\n  expect(hooks.do).toHaveBeenNthCalledWith(2, 'before', data, t);\n  expect(hooks.do).toHaveBeenNthCalledWith(3, 'beforeLeave', data, t);\n  expect(hooks.do).toHaveBeenNthCalledWith(4, 'leave', data, t);\n  expect(hooks.do).toHaveBeenNthCalledWith(5, 'afterLeave', data, t);\n  expect(hooks.do).toHaveBeenNthCalledWith(6, 'nextAdded', data);\n  expect(hooks.do).toHaveBeenNthCalledWith(7, 'beforeEnter', data, t);\n  expect(hooks.do).toHaveBeenNthCalledWith(8, 'enter', data, t);\n  expect(hooks.do).toHaveBeenNthCalledWith(9, 'afterEnter', data, t);\n  expect(hooks.do).toHaveBeenNthCalledWith(10, 'currentRemoved', data);\n  expect(hooks.do).toHaveBeenNthCalledWith(11, 'after', data, t);\n  expect(barba.transitions.doPage).toHaveBeenCalledTimes(1);\n  expect(document.title).toBe('New page');\n});\n\nit('do page [has cache]', async () => {\n  barba.history.add = jest.fn();\n  barba.cache.set(sameUrl, Promise.resolve({\n    html: sameHtml,\n    url: {\n      href: sameUrl,\n      ...parse(sameUrl)\n    } as IUrlFull,\n  }), 'init', 'pending');\n  spyCacheSet.mockRestore();\n\n  // NOTE: as we use \"same URL\" (localhost), we need a \"self\" transition\n  // to avoid prevent \"sameURL\"\n  barba.transitions.store.add('transition', { name: 'self' });\n  barba.transitions.store.add('transition', { leave() {}, enter() {} });\n  await barba.page(sameUrl, 'barba', undefined, false);\n\n  expect(spyCacheHas).toHaveBeenCalledTimes(1);\n  expect(spyCacheUpdate).toHaveBeenCalledTimes(1);\n  expect(spyCacheSet).toHaveBeenCalledTimes(0);\n});\n\nit('do page [waiting]', async () => {\n  // Avoid updating data.next\n  barba['_resetData'] = jest.fn();\n\n  barba.transitions.store.add('transition', {\n    leave() {},\n    enter() {},\n    to: { namespace: 'ns' },\n  });\n  await barba.page(nextUrl, 'barba', undefined, false);\n\n  expect(barba.data.next.html).toMatch(checkDoc);\n});\n\nit('force on error', async () => {\n  expect.assertions(2);\n  barba.force = jest.fn();\n  barba.transitions.logger.error = jest.fn();\n  const errorLeave = new Error('Transition error [page][leave]');\n\n  barba.transitions.store.add('transition', {\n    leave() {\n      throw errorLeave;\n    },\n  });\n\n  await barba.page(nextUrl, 'barba', undefined, false);\n\n  expect(barba.transitions.logger.error).toHaveBeenCalledWith(errorLeave);\n  expect(barba.force).toHaveBeenCalledTimes(1);\n});\n"
  },
  {
    "path": "packages/core/__tests__/core/core.plugin.test.ts",
    "content": "/* tslint:disable:no-empty */\nimport { init } from '../../__mocks__/barba';\nimport barba from '../../src';\nimport { IBarbaOptions, IBarbaPlugin } from '../../src/defs';\n\ninit();\n\nconst plugin = {\n  name: 'p1',\n  version: 'alpha',\n  install() {},\n  init() {},\n};\nconst plugin2 = {\n  name: 'p2',\n  version: 'beta',\n  install() {},\n  init() {},\n};\n\nbeforeEach(() => {\n  barba.plugins = [];\n});\n\nit('store plugin', () => {\n  barba.use(plugin);\n\n  expect(barba.plugins).toHaveLength(1);\n  expect(barba.plugins).toContain(plugin);\n});\n\nit('store same plugin once', () => {\n  barba.use(plugin);\n  barba.use(plugin);\n\n  expect(barba.plugins).toHaveLength(1);\n});\n\nit('store different plugins', () => {\n  barba.use(plugin);\n  barba.use(plugin2);\n\n  expect(barba.plugins).toHaveLength(2);\n  expect(barba.plugins).toContain(plugin);\n  expect(barba.plugins).toContain(plugin2);\n});\n\nit('install method plugin', () => {\n  plugin.install = jest.fn();\n  barba.use(plugin);\n\n  expect(plugin.install).toHaveBeenCalledTimes(1);\n});\n\nit('init plugin', () => {\n  plugin.init = jest.fn();\n  barba.use(plugin);\n  barba.init();\n\n  expect(plugin.init).toHaveBeenCalledTimes(1);\n});\n\nit('warns invalid plugin', () => {\n  barba.logger.warn = jest.fn();\n  barba.use({} as IBarbaPlugin<IBarbaOptions>);\n\n  expect(barba.logger.warn).toHaveBeenCalledTimes(1);\n});\n"
  },
  {
    "path": "packages/core/__tests__/core/core.popstate.test.ts",
    "content": "/* tslint:disable:no-empty no-string-literal */\nimport { init } from '../../__mocks__/barba';\nimport barba from '../../src';\n\ninit();\n\nit('handle popstate change', () => {\n  barba.go = jest.fn();\n  const popstate = document.createEvent('HTMLEvents');\n\n  popstate.initEvent('popstate', true, false);\n  window.dispatchEvent(popstate);\n\n  expect(barba.go).toHaveBeenCalledTimes(1);\n});\n"
  },
  {
    "path": "packages/core/__tests__/core/core.prefetch.test.ts",
    "content": "import waitForExpect from 'wait-for-expect';\nimport xhrMock from 'xhr-mock';\nimport { init } from '../../__mocks__/barba';\nimport barba from '../../src';\n\ninit();\n\n// Mocks\nlet spySet: jest.SpyInstance;\n\nbeforeEach(() => {\n  spySet = jest.spyOn(barba.cache, 'set');\n  xhrMock.setup();\n  xhrMock.error(() => {}); // tslint:disable-line:no-empty\n});\nafterEach(() => {\n  spySet.mockRestore();\n  xhrMock.teardown();\n});\n\nit('prefetch url', () => {\n  const url = 'http://localhost/foo.html';\n\n  barba.prefetch(url);\n\n  expect(spySet).toHaveBeenCalledWith(url, Promise.resolve(), 'prefetch', 'pending');\n});\n\nit('prefetch and cache absolute url only', () => {\n  const url = '/page.html';\n\n  barba.prefetch(url);\n\n  expect(barba.cache.has('/page.html')).toBeFalsy();\n  expect(barba.cache.has('http://localhost/page.html')).toBeTruthy();\n});\n\nit('prefetch wrong url', async () => {\n  const url = 'http://localhost/bad';\n\n  barba.logger.error = jest.fn();\n  xhrMock.get(url, (req, res) => res.status(500));\n  xhrMock.error(() => {}); // tslint:disable-line:no-empty\n\n  barba.prefetch(url);\n\n  expect(spySet).toHaveBeenCalledTimes(1);\n  await waitForExpect(() => {\n    expect(barba.logger.error).toHaveBeenCalledTimes(1);\n  });\n});\n"
  },
  {
    "path": "packages/core/__tests__/core/core.requestError.test.ts",
    "content": "/* tslint:disable:no-string-literal */\nimport { init } from '../../__mocks__/barba';\nimport barba from '../../src';\n\ninit();\nbarba.force = jest.fn();\n\nconst trigger = 'barba';\nconst href = 'url';\nconst error = 'error';\nconst request = Promise.resolve();\n\nit('forces URL on click', () => {\n  barba.cache.set(href, request, 'enter', 'pending');\n  barba.onRequestError(trigger, href, error);\n  expect(barba.force).not.toHaveBeenCalled();\n\n  barba.cache.update(href, { action: 'click' });\n  barba.onRequestError(trigger, href, error);\n  expect(barba.force).toHaveBeenCalled();\n});\n\nit('calls custom request error', () => {\n  barba['_requestCustomError'] = jest.fn();\n  barba.cache.set(href, request, 'click', 'pending');\n  barba.onRequestError(trigger, href, error);\n  expect(barba['_requestCustomError']).toHaveBeenCalledWith(\n    trigger,\n    'click',\n    href,\n    error\n  );\n  expect(barba.force).toHaveBeenCalled();\n});\n\nit('does not force URL with falsy custom request error', () => {\n  barba['_requestCustomError'] = jest.fn(() => false);\n  barba.cache.set(href, request, 'click', 'pending');\n  barba.onRequestError(trigger, href, error);\n  expect(barba['_requestCustomError']).toHaveBeenCalledWith(\n    trigger,\n    'click',\n    href,\n    error\n  );\n  expect(barba.force).not.toHaveBeenCalled();\n});\n"
  },
  {
    "path": "packages/core/__tests__/core/core.test.ts",
    "content": "import { init } from '../../__mocks__/barba';\nimport { version } from '../../package.json';\nimport barba from '../../src';\nimport { hooks } from '../../src/hooks';\nimport { Logger } from '../../src/modules/Logger';\nimport { schemaPage } from '../../src/schemas/page';\nimport { dom, helpers, request, url } from '../../src/utils';\n\nit('has defaults', () => {\n  expect(barba.version).toBe(version);\n  expect(barba.schemaPage).toBe(schemaPage);\n  expect(barba.hooks).toBe(hooks);\n  expect(barba.Logger).toBe(Logger);\n  expect(barba.logger).toBeInstanceOf(Logger);\n  expect(barba.dom).toBe(dom);\n  expect(barba.helpers).toBe(helpers);\n  expect(barba.request).toBe(request);\n  expect(barba.url).toBe(url);\n  expect(barba.plugins).toHaveLength(0);\n});\n"
  },
  {
    "path": "packages/core/__tests__/hooks/hooks.test.ts",
    "content": "import { HooksAll } from '../../src/defs';\nimport { hooks } from '../../src/hooks';\n\nconst [hookName] = hooks.all;\n\nafterEach(() => {\n  hooks.clear();\n});\n\nit('has defaults', () => {\n  expect(hooks.all).toBeDefined();\n  expect(hooks.registered.size).toBe(0);\n  expect(hooks[hookName]).toBeDefined();\n});\n\nit('register hooks', () => {\n  const ctx = {};\n  const fn = jest.fn();\n  const fn2 = jest.fn();\n\n  hooks[hookName](fn, ctx);\n\n  expect(hooks.registered.has(hookName)).toBeTruthy();\n  expect(hooks.registered.get(hookName).size).toBe(1);\n\n  hooks[hookName](fn2);\n\n  expect(hooks.registered.get(hookName).size).toBe(2);\n\n  const values = hooks.registered.get(hookName).values();\n  const v1 = values.next().value;\n  const v2 = values.next().value;\n\n  expect(v1.fn).toBe(fn);\n  expect(v1.ctx).toBe(ctx);\n  expect(v2.fn).toBe(fn2);\n  expect(v2.ctx).toMatchObject({});\n});\n\nit('do nothing when no hooks', async () => {\n  const doUnknown = jest.fn(() => hooks.do(('unknown' as unknown) as HooksAll));\n  const doUnregistered = jest.fn(() => hooks.do(hooks.all[1]));\n\n  expect(doUnknown()).resolves.toBeUndefined();\n  expect(doUnregistered()).resolves.toBeUndefined();\n});\n\nit('do registered hooks', async () => {\n  const fn = jest.fn();\n  const fn2 = jest.fn();\n\n  hooks[hookName](fn);\n  hooks[hookName](fn2);\n\n  await hooks.do(hookName);\n\n  expect(fn).toHaveBeenCalledTimes(1);\n  expect(fn2).toHaveBeenCalledTimes(1);\n});\n\nit('do with arguments', async () => {\n  const expected = 'arg';\n  const fn = jest.fn((...args) => args);\n\n  hooks.init();\n\n  hooks[hookName](fn);\n  await hooks.do(hookName, expected);\n\n  expect(fn).toHaveReturnedWith([expected]);\n});\n\nit('do with context', async () => {\n  interface ICtx {\n    prop: string;\n    fn(): string;\n  }\n  const ctx: ICtx = {\n    fn: jest.fn(function(this: ICtx) {\n      return this.prop;\n    }),\n    prop: 'foo',\n  };\n\n  hooks.init();\n\n  hooks[hookName](ctx.fn, ctx);\n  await hooks.do(hookName);\n\n  expect(ctx.fn).toHaveReturnedWith(ctx.prop);\n});\n\nit('print help', () => {\n  hooks.logger.info = jest.fn();\n\n  hooks.init();\n  hooks[hookName]();\n  hooks.help();\n\n  expect(hooks.logger.info).toHaveBeenCalledTimes(2);\n});\n\nit('catch error', async () => {\n  expect.assertions(2);\n  hooks.logger.debug = jest.fn();\n  hooks.logger.error = jest.fn();\n\n  const err = new Error('Test error');\n\n  hooks.init();\n  hooks[hookName](() => {\n    throw err;\n  });\n  await hooks.do(hookName);\n\n  expect(hooks.logger.debug).toHaveBeenCalledWith(`Hook error [${hookName}]`);\n  expect(hooks.logger.error).toHaveBeenCalledWith(err);\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/cache.test.ts",
    "content": "import { Cache } from '../../src/modules/Cache';\n\nconst cache = new Cache(false);\n\nconst key = 'key';\nconst request = Promise.resolve();\nconst action = 'enter';\nconst status = 'pending';\nconst target = key;\nconst data = {\n  action,\n  request,\n  status,\n  target,\n};\n\nit('sets, gets and has', () => {\n  cache.set(key, request, action, status, target);\n\n  expect(cache.has(key)).toBeTruthy();\n  expect(cache.get(key)).toEqual(data);\n});\n\nit('set empty target', () => {\n  cache.set(key, request, action, status);\n\n  expect(cache.getTarget(key)).toBe(key);\n});\n\nit('gets action, request, status and target', () => {\n  expect(cache.getAction(key)).toBe(action);\n  expect(cache.getRequest(key)).toBe(request);\n  expect(cache.getStatus(key)).toBe(status);\n  expect(cache.getTarget(key)).toBe(target);\n});\n\nit('update', () => {\n  cache.update(key, { action: 'click' });\n\n  expect(cache.getAction(key)).toBe('click');\n});\n\nit('deletes', () => {\n  cache.delete(key);\n\n  expect(cache.has(key)).toBeFalsy();\n});\n\nit('checks url', () => {\n  cache.checkHref = jest.fn();\n  cache.has(key);\n\n  expect(cache.checkHref).toHaveBeenCalled();\n});\n\nit('uses cacheIgnore', () => {\n  cache.checkHref = jest.fn().mockImplementation(() => true);\n  const res = cache.has(key);\n\n  expect(res).toBeFalsy();\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/error.test.ts",
    "content": "import { BarbaError } from '../../src/modules/Error';\n\nconst err = new Error('Test error');\n\nit('has defaults', () => {\n  const e = new BarbaError(err);\n\n  expect(e.name).toBe('BarbaError');\n  expect(e.label).toBe('Barba error');\n  expect(e.error).toBe(err);\n});\n\nit('has params', () => {\n  const e = new BarbaError(err, 'Label error', 'Message error');\n\n  expect(e.name).toBe('BarbaError');\n  expect(e.label).toBe('Label error');\n  expect(e.message).toBe('Message error');\n  expect(e.error).toBe(err);\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/headers.test.ts",
    "content": "import { Headers } from '../../src/modules/Headers';\n\nconst headers = new Headers();\n\nconst name = 'header-name';\nconst value = 'header-value';\n\nit('sets, gets and has', () => {\n  headers.set(name, value);\n\n  expect(headers.has(name)).toBeTruthy();\n  expect(headers.get(name)).toEqual(value);\n});\n\nit('deletes a custom header', () => {\n  headers.delete(name);\n\n  expect(headers.has(name)).toBeFalsy();\n});\n\nit('gets all headers and clear them', () => {\n  headers.set(name, value);\n  headers.clear();\n\n  expect(headers.all().size).toEqual(0);\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/ignore.test.ts",
    "content": "import { Ignore } from '../../src/modules/Ignore';\n\nlet ignore: Ignore;\nconst url = 'http://localhost/';\nconst url2 = 'http://localhost/foo.html';\nconst url3 = 'http://localhost/bar/foo.html';\n\nit('ignores none', () => {\n  ignore = new Ignore(false);\n\n  expect(ignore.checkHref(url)).toBeFalsy();\n});\n\nit('ignores all', () => {\n  ignore = new Ignore(true);\n\n  expect(ignore.checkHref(url)).toBeTruthy();\n});\n\nit('ignores URL', () => {\n  ignore = new Ignore('/');\n\n  expect(ignore.checkHref(url)).toBeTruthy();\n  expect(ignore.checkHref(url2)).toBeFalsy();\n});\n\nit('ignores URLs', () => {\n  ignore = new Ignore(['/', '/:segment/foo.html']);\n\n  expect(ignore.checkHref(url)).toBeTruthy();\n  expect(ignore.checkHref(url2)).toBeFalsy();\n  expect(ignore.checkHref(url3)).toBeTruthy();\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/logger.test.ts",
    "content": "/* tslint:disable:no-string-literal */\nimport { Logger, LogLevels } from '../../src/modules/Logger';\n\nlet logger: Logger;\nconst source = 'source';\nconst objects = ['foo', 'bar'];\n\nbeforeEach(() => {\n  logger = new Logger(source);\n});\n\n// it('creates instances', () => {\n//   expect(logger._source).toBeUndefined();\n//   expect(loggerSource._source).toBe(source);\n// });\n\nit('has static log level', () => {\n  expect(Logger.getLevel()).toBe(0);\n\n  Logger.setLevel('error');\n  expect(Logger.getLevel()).toBe(1);\n  Logger.setLevel('warning');\n  expect(Logger.getLevel()).toBe(2);\n  Logger.setLevel('info');\n  expect(Logger.getLevel()).toBe(3);\n  Logger.setLevel('debug');\n  expect(Logger.getLevel()).toBe(4);\n  Logger.setLevel('off');\n  expect(Logger.getLevel()).toBe(0);\n});\n\nit('logs all levels', () => {\n  logger['_log'] = jest.fn();\n\n  logger.error(...objects);\n  logger.warn(...objects);\n  logger.info(...objects);\n  logger.debug(...objects);\n\n  expect(logger['_log']).toHaveBeenNthCalledWith(1, console.error, 1, objects);\n  expect(logger['_log']).toHaveBeenNthCalledWith(2, console.warn, 2, objects);\n  expect(logger['_log']).toHaveBeenNthCalledWith(3, console.info, 3, objects);\n  expect(logger['_log']).toHaveBeenNthCalledWith(4, console.log, 4, objects);\n});\n\nit('logs with source', () => {\n  Logger.setLevel('debug');\n  global.console.log = jest.fn();\n\n  logger.debug(...objects);\n  expect(global.console.log).toHaveBeenCalledWith(`[${source}] `, ...objects);\n});\n\nit('logs all when level is debug', () => {\n  const mock = jest.fn();\n  const levels = ['off', 'error', 'warning', 'info', 'debug'];\n\n  global.console.log = mock;\n  global.console.info = mock;\n  global.console.warn = mock;\n  global.console.error = mock;\n\n  levels.forEach((level, i) => {\n    Logger.setLevel(level as keyof typeof LogLevels);\n\n    logger.debug();\n    logger.info();\n    logger.warn();\n    logger.error();\n\n    expect(mock).toHaveBeenCalledTimes(i);\n    mock.mockReset();\n  });\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/prevent/prevent.blank.test.ts",
    "content": "import { IPreventCheckData, PreventCheck } from '../../../src/defs';\nimport { Prevent } from '../../../src/modules/Prevent';\n\nconst prevent = new Prevent(false);\nlet check: PreventCheck;\nconst el = document.createElement('a');\n\nbeforeEach(() => {\n  check = jest.fn(data => prevent.tests.get('blank')(data));\n  [].slice.call(el.attributes).forEach(attr => el.removeAttribute(attr.name));\n});\n\nit('pass', () => {\n  check({ el } as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(false);\n});\n\nit('pass with different target attribute', () => {\n  el.setAttribute('target', '_self');\n\n  check({ el } as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(false);\n});\n\nit('prevent with target \"_blank\"', () => {\n  el.setAttribute('target', '_blank');\n\n  check({ el } as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(true);\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/prevent/prevent.corsDomain.test.ts",
    "content": "import { IPreventCheckData, PreventCheck } from '../../../src/defs';\nimport { Prevent } from '../../../src/modules/Prevent';\n\nconst prevent = new Prevent(false);\nlet check: PreventCheck;\nconst el = document.createElement('a');\n\nbeforeEach(() => {\n  check = jest.fn(data => prevent.tests.get('corsDomain')(data));\n  [].slice.call(el.attributes).forEach(attr => el.removeAttribute(attr.name));\n});\n\nit('pass', () => {\n  el.href = 'http://localhost';\n\n  check({ el } as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(false);\n});\n\nit('prevent with different protocol', () => {\n  el.href = 'https://localhost';\n\n  check({ el } as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(true);\n});\n\nit('prevent with different hostname', () => {\n  el.href = 'https://domain.com';\n\n  check({ el } as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(true);\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/prevent/prevent.corsPort.test.ts",
    "content": "import { IPreventCheckData, PreventCheck } from '../../../src/defs';\nimport { Prevent } from '../../../src/modules/Prevent';\n\nconst prevent = new Prevent(false);\nlet check: PreventCheck;\nconst el = document.createElement('a');\n\nbeforeEach(() => {\n  check = jest.fn(data => prevent.tests.get('corsPort')(data));\n  [].slice.call(el.attributes).forEach(attr => el.removeAttribute(attr.name));\n});\n\nit('pass', () => {\n  el.href = 'http://localhost';\n\n  check({ el } as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(false);\n});\n\nit('prevent with different port', () => {\n  el.href = 'https://localhost:8888';\n\n  check({ el } as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(true);\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/prevent/prevent.download.test.ts",
    "content": "import { IPreventCheckData, PreventCheck } from '../../../src/defs';\nimport { Prevent } from '../../../src/modules/Prevent';\n\nconst prevent = new Prevent(false);\nlet check: PreventCheck;\nconst el = document.createElement('a');\n\nbeforeEach(() => {\n  check = jest.fn(data => prevent.tests.get('download')(data));\n  [].slice.call(el.attributes).forEach(attr => el.removeAttribute(attr.name));\n});\n\nit('pass', () => {\n  check({ el } as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(false);\n});\n\nit('prevent with download attribute', () => {\n  el.setAttribute('download', 'true');\n\n  check({ el } as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(true);\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/prevent/prevent.exists.test.ts",
    "content": "import { IPreventCheckData, PreventCheck } from '../../../src/defs';\nimport { Prevent } from '../../../src/modules/Prevent';\n\nconst prevent = new Prevent(false);\nlet check: PreventCheck;\n\nbeforeEach(() => {\n  check = jest.fn(data => prevent.tests.get('exists')(data));\n});\n\nit('pass (with element and href)', () => {\n  check(({ el: true, href: true } as unknown) as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(false);\n});\n\nit('prevent with no element and no href', () => {\n  check(({ el: false, href: false } as unknown) as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(true);\n});\n\nit('prevent with element but no href', () => {\n  check(({ el: true, href: false } as unknown) as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(true);\n});\n\nit('prevent with no element but href', () => {\n  check(({ el: false, href: true } as unknown) as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(true);\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/prevent/prevent.newTab.test.ts",
    "content": "import { IPreventCheckData, PreventCheck } from '../../../src/defs';\nimport { Prevent } from '../../../src/modules/Prevent';\n\nconst prevent = new Prevent(false);\nlet check: PreventCheck;\n\nbeforeEach(() => {\n  check = jest.fn(data => prevent.tests.get('newTab')(data));\n});\n\nit('pass', () => {\n  check({\n    event: ({\n      altKey: false,\n      ctrlKey: false,\n      metaKey: false,\n      shiftKey: false,\n      which: 0,\n    } as unknown) as Event,\n  } as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(false);\n});\n\nit('prevent with \"which\"', () => {\n  check({ event: ({ which: 2 } as unknown) as Event } as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(true);\n});\n\nit('prevent with \"metaKey\"', () => {\n  check({\n    event: ({ metaKey: true } as unknown) as Event,\n  } as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(true);\n});\n\nit('prevent with \"ctrlKey\"', () => {\n  check({\n    event: ({ ctrlKey: true } as unknown) as Event,\n  } as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(true);\n});\n\nit('prevent with \"shiftKey\"', () => {\n  check({\n    event: ({ shiftKey: true } as unknown) as Event,\n  } as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(true);\n});\n\nit('prevent with \"altKey\"', () => {\n  check({ event: ({ altKey: true } as unknown) as Event } as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(true);\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/prevent/prevent.preventAll.test.ts",
    "content": "import { IPreventCheckData, PreventCheck } from '../../../src/defs';\nimport { Prevent } from '../../../src/modules/Prevent';\n\nconst prevent = new Prevent(false);\nlet check: PreventCheck;\nconst el = document.createElement('a');\nconst parent = document.createElement('div');\n\nparent.appendChild(el);\n\nbeforeEach(() => {\n  check = jest.fn(data => prevent.tests.get('preventAll')(data));\n  [].slice.call(el.attributes).forEach(attr => el.removeAttribute(attr.name));\n});\n\nit('pass', () => {\n  check({ el } as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(false);\n});\n\nit('prevent with data-barba-prevent=\"all\"', () => {\n  parent.dataset.barbaPrevent = 'all';\n\n  check({ el } as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(true);\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/prevent/prevent.preventSelf.test.ts",
    "content": "import { IPreventCheckData, PreventCheck } from '../../../src/defs';\nimport { Prevent } from '../../../src/modules/Prevent';\n\nconst prevent = new Prevent(false);\nlet check: PreventCheck;\nconst el = document.createElement('a');\n\nbeforeEach(() => {\n  check = jest.fn(data => prevent.tests.get('preventSelf')(data));\n  [].slice.call(el.attributes).forEach(attr => el.removeAttribute(attr.name));\n});\n\nit('pass', () => {\n  check({ el } as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(false);\n});\n\nit('prevent with data-barba-prevent', () => {\n  el.dataset.barbaPrevent = '';\n\n  check({ el } as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(true);\n});\n\nit('prevent with data-barba-prevent=\"self\"', () => {\n  el.dataset.barbaPrevent = 'self';\n\n  check({ el } as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(true);\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/prevent/prevent.sameUrl.test.ts",
    "content": "import { IPreventCheckData, PreventCheck } from '../../../src/defs';\nimport { Prevent } from '../../../src/modules/Prevent';\n\nconst prevent = new Prevent(false);\nlet check: PreventCheck;\n\nbeforeEach(() => {\n  check = jest.fn(data => prevent.tests.get('sameUrl')(data));\n});\n\nit('pass', () => {\n  check({ href: 'somewhere' } as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(false);\n});\n\nit('prevent with same url', () => {\n  check({ href: window.location.href } as IPreventCheckData);\n\n  expect(check).toHaveReturnedWith(true);\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/prevent/prevent.test.ts",
    "content": "import { Prevent } from '../../../src/modules/Prevent';\n\nconst prevent = new Prevent(false);\n\nit('adds test', () => {\n  const name = 'fake';\n  const check = () => true;\n\n  prevent.add(name, check);\n\n  expect(prevent.tests.get(name)).toBe(check);\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/store/store.add.test.ts",
    "content": "/* tslint:disable:no-string-literal */\nimport { Store } from '../../../src/modules/Store';\n\nlet store: Store;\n\nbeforeEach(() => {\n  store = new Store();\n});\n\nit('add rule', () => {\n  const nb = store['_rules'].length;\n  const r = {\n    name: 'test',\n    type: 'strings',\n  };\n\n  store.add('rule', {\n    value: r,\n  });\n  expect(store['_rules']).toHaveLength(nb + 1);\n  expect(store['_rules'][0]).toBe(r);\n});\n\nit('add rule with position', () => {\n  const nb = store['_rules'].length;\n  const r = {\n    name: 'test',\n    type: 'strings',\n  };\n\n  store.add('rule', {\n    position: 1,\n    value: r,\n  });\n  expect(store['_rules']).toHaveLength(nb + 1);\n  expect(store['_rules'][1]).toBe(r);\n});\n\nit('add transition', () => {\n  const nb = store.all.length;\n  const t = {};\n\n  store.add('transition', t);\n  expect(store.all).toHaveLength(nb + 1);\n  expect(store.all[0]).toBe(t);\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/store/store.addPriority.test.ts",
    "content": "/* tslint:disable:no-string-literal */\nimport { IRule, ITransitionPage } from '../../../src/defs';\nimport { Store } from '../../../src/modules/Store';\n\nconst store = new Store();\nconst rules: IRule[] = [\n  ({ name: 'tens', type: 'strings' } as unknown) as IRule,\n  ({ name: 'hundreds', type: 'strings' } as unknown) as IRule,\n];\n\nstore['_rules'] = rules;\n\nit('add priority 0', () => {\n  expect(store['_addPriority']({}).priority).toBe(0);\n});\n\nit('add priority 10', () => {\n  expect(\n    store['_addPriority'](({ tens: true } as unknown) as ITransitionPage)\n      .priority\n  ).toBe(10);\n});\n\nit('add priority 11', () => {\n  expect(\n    store['_addPriority'](({\n      from: { tens: true },\n    } as unknown) as ITransitionPage).priority\n  ).toBe(11);\n});\n\nit('add priority 12', () => {\n  expect(\n    store['_addPriority'](({\n      to: { tens: true },\n    } as unknown) as ITransitionPage).priority\n  ).toBe(12);\n});\n\nit('add priority 13', () => {\n  expect(\n    store['_addPriority'](({\n      from: { tens: true },\n      to: { tens: true },\n    } as unknown) as ITransitionPage).priority\n  ).toBe(13);\n});\n\nit('add priority 100', () => {\n  expect(\n    store['_addPriority'](({ hundreds: true } as unknown) as ITransitionPage)\n      .priority\n  ).toBe(100);\n});\n\nit('add priority 101', () => {\n  expect(\n    store['_addPriority'](({\n      from: { hundreds: true },\n    } as unknown) as ITransitionPage).priority\n  ).toBe(101);\n});\n\nit('add priority 102', () => {\n  expect(\n    store['_addPriority'](({\n      to: { hundreds: true },\n    } as unknown) as ITransitionPage).priority\n  ).toBe(102);\n});\n\nit('add priority 103', () => {\n  expect(\n    store['_addPriority'](({\n      from: { hundreds: true },\n      to: { hundreds: true },\n    } as unknown) as ITransitionPage).priority\n  ).toBe(103);\n});\n\nit('add priority 110', () => {\n  expect(\n    store['_addPriority'](({\n      hundreds: true,\n      tens: true,\n    } as unknown) as ITransitionPage).priority\n  ).toBe(110);\n});\n\nit('add priority 112', () => {\n  expect(\n    store['_addPriority'](({\n      from: { tens: true, hundreds: true },\n    } as unknown) as ITransitionPage).priority\n  ).toBe(112);\n});\n\nit('add priority 114', () => {\n  expect(\n    store['_addPriority'](({\n      to: { tens: true, hundreds: true },\n    } as unknown) as ITransitionPage).priority\n  ).toBe(114);\n});\n\nit('add priority 116', () => {\n  expect(\n    store['_addPriority'](({\n      from: { tens: true, hundreds: true },\n      to: { tens: true, hundreds: true },\n    } as unknown) as ITransitionPage).priority\n  ).toBe(116);\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/store/store.check.test.ts",
    "content": "/* tslint:disable:no-string-literal */\nimport {\n  IRule,\n  ISchemaPage,\n  ITransitionData,\n  ITransitionPage,\n} from '../../../src/defs';\nimport { Store } from '../../../src/modules/Store';\nimport { schemaPage } from '../../../src/schemas/page';\n\nlet match = {};\nconst store = new Store();\n\nstore.add('rule', {\n  position: 1,\n  value: {\n    name: 'route',\n    type: 'object',\n  },\n});\n\nschemaPage.route = { name: '', params: {} };\nconst mockData: ITransitionData = {\n  current: schemaPage,\n  next: schemaPage,\n  trigger: 'barba',\n};\n\nbeforeEach(() => {\n  match = {};\n});\n\n/**\n * Check rules\n *\n * Based on rule type: strings | object | function\n * 1. transition has no rule \"property\":\n *    - always returns true\n * 2. transition has rule \"property\":\n *     - \"strings\" should be present on both side (transition + view) and match\n *     - \"function\" should return true\n */\n\n/**\n * Run \"strings\" check test\n */\nfunction runStrings(\n  transition: ITransitionPage,\n  rule: IRule,\n  data: ITransitionData,\n  direction?: 'from' | 'to'\n) {\n  const fail = store['_check'](transition, rule, mockData, match, direction);\n\n  expect(fail).toBeFalsy();\n  expect(match).toMatchObject({});\n\n  const ok = store['_check'](transition, rule, data, match, direction);\n\n  expect(ok).toBeTruthy();\n  expect(match).toMatchObject(transition);\n}\n\n/**\n * Run \"object\" check test\n */\nfunction runObject(\n  transition: ITransitionPage,\n  rule: IRule,\n  data: ITransitionData,\n  direction?: 'from' | 'to'\n) {\n  const fail = store['_check'](transition, rule, mockData, match, direction);\n\n  expect(fail).toBeFalsy();\n  expect(match).toMatchObject({});\n\n  const ok = store['_check'](transition, rule, data, match, direction);\n\n  expect(ok).toBeTruthy();\n  expect(match).toMatchObject(transition);\n}\n\n/**\n * Run \"function\" check test\n */\nfunction runFunction(\n  falsy: ITransitionPage,\n  truthy: ITransitionPage,\n  rule: IRule,\n  direction?: 'from' | 'to'\n) {\n  const fail = store['_check'](falsy, rule, mockData, match, direction);\n\n  expect(fail).toBeFalsy();\n  expect(match).toMatchObject({});\n\n  const ok = store['_check'](truthy, rule, mockData, match, direction);\n\n  expect(ok).toBeTruthy();\n  expect(match).toMatchObject(truthy);\n}\n\n// \"strings\" type\n\nit('check valid for inexisting rule \"strings\"', () => {\n  const [rule] = store['_rules'].filter(r => r.name === 'namespace');\n  const expected = store['_check'](\n    {},\n    rule,\n    ({ namespace: 'ns' } as unknown) as ITransitionData,\n    match\n  );\n\n  expect(expected).toBeTruthy();\n  expect(match).toMatchObject({});\n});\n\nit('check single \"strings\"', () => {\n  const transition = { namespace: 'ns' };\n  const [rule] = store['_rules'].filter(r => r.name === 'namespace');\n  const data = { current: { namespace: 'ns' } };\n\n  runStrings(transition, rule, (data as unknown) as ITransitionData);\n});\n\nit('check single \"strings\" with \"from\"', () => {\n  const transition = { from: { namespace: 'ns' } };\n  const [rule] = store['_rules'].filter(r => r.name === 'namespace');\n  const data = { current: { namespace: 'ns' } };\n\n  runStrings(transition, rule, (data as unknown) as ITransitionData, 'from');\n});\n\nit('check single \"strings\" with \"to\"', () => {\n  const transition = { to: { namespace: 'ns' } };\n  const [rule] = store['_rules'].filter(r => r.name === 'namespace');\n  const data = { next: { namespace: 'ns' } };\n\n  runStrings(transition, rule, (data as unknown) as ITransitionData, 'to');\n});\n\nit('check array \"strings\"', () => {\n  const transition = { namespace: ['ns'] };\n  const [rule] = store['_rules'].filter(r => r.name === 'namespace');\n  const data = { current: { namespace: 'ns' } };\n\n  runStrings(transition, rule, (data as unknown) as ITransitionData);\n});\n\nit('check array \"strings\" with \"from\"', () => {\n  const transition = { from: { namespace: ['ns'] } };\n  const [rule] = store['_rules'].filter(r => r.name === 'namespace');\n  const data = { current: { namespace: 'ns' } };\n\n  runStrings(transition, rule, (data as unknown) as ITransitionData, 'from');\n});\n\nit('check array \"strings\" with \"to\"', () => {\n  const transition = { to: { namespace: ['ns'] } };\n  const [rule] = store['_rules'].filter(r => r.name === 'namespace');\n  const data = { next: { namespace: 'ns' } };\n\n  runStrings(transition, rule, (data as unknown) as ITransitionData, 'to');\n});\n\n// \"object\" type\nit('check valid for inexisting rule \"object\"', () => {\n  const [rule] = store['_rules'].filter(r => r.name === 'route');\n  const expected = store['_check'](\n    {},\n    rule,\n    ({ route: 'r' } as unknown) as ITransitionData,\n    match\n  );\n\n  expect(expected).toBeTruthy();\n  expect(match).toMatchObject({});\n});\n\nit('check invalid for non matching rule \"object\"', () => {\n  const transition = { route: 'r' };\n  const [rule] = store['_rules'].filter(r => r.name === 'route');\n  const data = { current: { route: null } as ISchemaPage };\n  const expected = store['_check'](\n    transition,\n    rule,\n    (data as unknown) as ITransitionData,\n    match\n  );\n\n  expect(expected).toBeFalsy();\n  expect(match).toMatchObject({});\n});\n\nit('check single \"object\"', () => {\n  const transition = { route: 'r' };\n  const [rule] = store['_rules'].filter(r => r.name === 'route');\n  const data = { current: { route: { name: 'r' } } };\n\n  runObject(transition, rule, (data as unknown) as ITransitionData);\n});\n\nit('check single \"object\" with \"from\"', () => {\n  const transition = { from: { route: 'r' } };\n  const [rule] = store['_rules'].filter(r => r.name === 'route');\n  const data = { current: { route: { name: 'r' } } };\n\n  runObject(transition, rule, (data as unknown) as ITransitionData, 'from');\n});\n\nit('check single \"object\" with \"to\"', () => {\n  const transition = { to: { route: 'r' } };\n  const [rule] = store['_rules'].filter(r => r.name === 'route');\n  const data = { next: { route: { name: 'r' } } };\n\n  runObject(transition, rule, (data as unknown) as ITransitionData, 'to');\n});\n\nit('check array \"object\"', () => {\n  const transition = { route: ['r'] };\n  const [rule] = store['_rules'].filter(r => r.name === 'route');\n  const data = { current: { route: { name: 'r' } } };\n\n  runObject(transition, rule, (data as unknown) as ITransitionData);\n});\n\nit('check array \"object\" with \"from\"', () => {\n  const transition = { from: { route: ['r'] } };\n  const [rule] = store['_rules'].filter(r => r.name === 'route');\n  const data = { current: { route: { name: 'r' } } };\n\n  runObject(transition, rule, (data as unknown) as ITransitionData, 'from');\n});\n\nit('check array \"object\" with \"to\"', () => {\n  const transition = { to: { route: ['r'] } };\n  const [rule] = store['_rules'].filter(r => r.name === 'route');\n  const data = { next: { route: { name: 'r' } } };\n\n  runObject(transition, rule, (data as unknown) as ITransitionData, 'to');\n});\n\n// \"function\" type\n\nit('check valid for inexisting rule \"function\"', () => {\n  const [rule] = store['_rules'].filter(r => r.name === 'custom');\n  const expected = store['_check'](\n    {},\n    rule,\n    ({} as unknown) as ITransitionData,\n    match\n  );\n\n  expect(expected).toBeTruthy();\n  expect(match).toMatchObject({});\n});\n\nit('check \"function\"', () => {\n  const falsy = { custom: () => false };\n  const truthy = { custom: () => true };\n  const [rule] = store['_rules'].filter(r => r.name === 'custom');\n\n  runFunction(falsy, truthy, rule);\n});\n\nit('check \"function\" with \"from\"', () => {\n  const falsy = { from: { custom: () => false } };\n  const truthy = { from: { custom: () => true } };\n  const [rule] = store['_rules'].filter(r => r.name === 'custom');\n\n  runFunction(falsy, truthy, rule, 'from');\n});\n\nit('check \"function\" with \"to\"', () => {\n  const falsy = { to: { custom: () => false } };\n  const truthy = { to: { custom: () => true } };\n  const [rule] = store['_rules'].filter(r => r.name === 'custom');\n\n  runFunction(falsy, truthy, rule, 'to');\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/store/store.log.test.ts",
    "content": "import { Logger } from '../../../src/modules/Logger';\nimport { Store } from '../../../src/modules/Store';\nimport { schemaPage } from '../../../src/schemas/page';\n\nit('has debug info', () => {\n  const store = new Store([]);\n  Logger.setLevel('info');\n\n  store.logger.info = jest.fn();\n  store.resolve({\n    current: schemaPage,\n    next: schemaPage,\n    trigger: 'barba',\n  });\n\n  expect(store.logger.info).toHaveBeenCalledTimes(1);\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/store/store.resolve.once.test.ts",
    "content": "import { ITransitionData, ITransitionOnce } from '../../../src/defs';\nimport { Store } from '../../../src/modules/Store';\n\nconst tOnce: ITransitionOnce = { once: () => Promise.resolve() };\nconst tOnceNs: ITransitionOnce = {\n  namespace: 'ns',\n  once: () => Promise.resolve(),\n};\nconst tOnceCustom: ITransitionOnce = {\n  once: () => Promise.resolve(),\n  custom({ current }) {\n    return current.namespace === 'custom';\n  },\n};\nconst store = new Store([tOnce, tOnceNs, tOnceCustom]);\n\nit('has no transition', async () => {\n  const emptyStore = new Store();\n\n  emptyStore.logger.info = jest.fn();\n  emptyStore.resolve(({} as unknown) as ITransitionData, { once: true });\n\n  expect(emptyStore.logger.info).toHaveBeenCalledWith(\n    'No transition found [once]'\n  );\n});\n\nit('get \"once\" transition', () => {\n  const result = store.resolve(\n    ({\n      current: { namespace: 'none' },\n    } as unknown) as ITransitionData,\n    { once: true }\n  );\n\n  expect(result).toBe(tOnce);\n});\n\nit('get \"once/ns\" transition', () => {\n  const result = store.resolve(\n    ({\n      current: { namespace: 'ns' },\n    } as unknown) as ITransitionData,\n    { once: true }\n  );\n\n  expect(result).toBe(tOnceNs);\n});\n\nit('get \"once/custom\" transition', () => {\n  const result = store.resolve(\n    ({\n      current: { namespace: 'custom' },\n    } as unknown) as ITransitionData,\n    { once: true }\n  );\n\n  expect(result).toBe(tOnceCustom);\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/store/store.resolve.page.test.ts",
    "content": "/* tslint:disable:no-empty */\nimport { ITransitionData } from '../../../src/defs';\nimport { Store } from '../../../src/modules/Store';\n\nconst t = { enter() {} };\nconst tNs = { enter() {}, namespace: 'ns' };\nconst tNsFrom = { enter() {}, from: { namespace: 'nsFrom' } };\nconst tNsTo = { enter() {}, to: { namespace: 'nsTo' } };\nconst tNsFromTo = {\n  enter() {},\n  from: { namespace: 'nsFrom' },\n  to: { namespace: 'nsTo' },\n};\nconst tSelf = { enter() {}, name: 'self' };\n\nconst store = new Store([t, tNs, tNsFrom, tNsTo, tNsFromTo, tSelf]);\n\nit('has no transition', async () => {\n  const emptyStore = new Store();\n\n  emptyStore.logger.info = jest.fn();\n  emptyStore.resolve(({} as unknown) as ITransitionData);\n\n  expect(emptyStore.logger.info).toHaveBeenCalledWith(\n    'No transition found [page]'\n  );\n});\n\nit('get \"page\" transition', () => {\n  const result = store.resolve(({\n    current: true,\n    next: true,\n  } as unknown) as ITransitionData);\n\n  expect(result).toBe(t);\n});\n\nit('get \"page/ns\" transition', () => {\n  const result = store.resolve(({\n    current: { namespace: 'ns' },\n    next: {},\n  } as unknown) as ITransitionData);\n\n  expect(result).toBe(tNs);\n});\n\nit('get \"page/from\" transition', () => {\n  const result = store.resolve(({\n    current: { namespace: 'nsFrom' },\n    next: {},\n  } as unknown) as ITransitionData);\n\n  expect(result).toBe(tNsFrom);\n});\n\nit('get \"page/to\" transition', () => {\n  const result = store.resolve(({\n    current: {},\n    next: { namespace: 'nsTo' },\n  } as unknown) as ITransitionData);\n\n  expect(result).toBe(tNsTo);\n});\n\nit('get \"page/fromTo\" transition', () => {\n  const result = store.resolve(({\n    current: { namespace: 'nsFrom' },\n    next: { namespace: 'nsTo' },\n  } as unknown) as ITransitionData);\n\n  expect(result).toBe(tNsFromTo);\n});\n\nit('get \"self\" transition', () => {\n  const result = store.resolve(\n    ({\n      current: { namespace: 'nsFrom' },\n      next: { namespace: 'nsTo' },\n    } as unknown) as ITransitionData,\n    { self: true }\n  );\n\n  expect(result).toBe(tSelf);\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/store/store.test.ts",
    "content": "import { Store } from '../../../src/modules/Store';\n\nlet store: Store;\n\nit('has defaults', () => {\n  store = new Store([]);\n\n  expect(store.all).toHaveLength(0);\n  expect(store.once).toHaveLength(0);\n});\n\nit('adds transitions', () => {\n  store = new Store([{}]);\n  expect(store.all).toHaveLength(1);\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/store/store.update.sort.test.ts",
    "content": "import shuffle from 'lodash/shuffle';\nimport transitions from '../../../__mocks__/transitions';\nimport { Store } from '../../../src/modules/Store';\n\nlet store: Store;\n\nconst expected = transitions.map(t => t.name).reverse();\nconst times = (x: number) => (f: () => void) => {\n  if (x > 0) {\n    f();\n    times(x - 1)(f);\n  }\n};\n\nconst r = {\n  name: 'route',\n  type: 'strings',\n};\n\ntimes(50)(() => {\n  it('sort all', () => {\n    store = new Store(shuffle(transitions));\n    store.add('rule', {\n      position: 1,\n      value: r,\n    });\n\n    expect(store.all).toHaveLength(transitions.length);\n    expect(store.all.map(t => t.name)).toEqual(expected);\n  });\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/store/store.update.test.ts",
    "content": "/* tslint:disable:no-empty */\nimport { Store } from '../../../src/modules/Store';\n\nlet store: Store;\nlet nb: number;\n\nbeforeEach(() => {\n  nb = 0;\n});\n\nit('update all', () => {\n  store = new Store([{}]);\n  expect(store.all).toHaveLength(nb + 1);\n  expect(store.once).toHaveLength(0);\n});\n\nit('update once', () => {\n  store = new Store([{ once() {} }]);\n  expect(store.all).toHaveLength(nb + 1);\n  expect(store.once).toHaveLength(nb + 1);\n});\n\nit('update page', () => {\n  store = new Store([{ enter() {} }]);\n  expect(store.all).toHaveLength(nb + 1);\n  expect(store.once).toHaveLength(0);\n});\n\nit('update once and page', () => {\n  store = new Store([{ once() {}, enter() {} }]);\n  expect(store.all).toHaveLength(nb + 1);\n  expect(store.once).toHaveLength(nb + 1);\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/transitions/transitions.async.test.ts",
    "content": "import { ISchemaPage, ITransitionData } from '../../../src/defs';\nimport { hooks } from '../../../src/hooks';\nimport { Transitions } from '../../../src/modules/Transitions';\n\nconst transitions = new Transitions();\n// Mocks\nconst enter = jest.fn();\n\n// Shared\nconst div = document.createElement('div');\nconst wrapper = div.cloneNode() as HTMLElement;\nconst currentContainer = div.cloneNode() as HTMLElement;\nconst nextContainer = div.cloneNode() as HTMLElement;\n// Data\nconst data: ITransitionData = {\n  current: {\n    container: currentContainer,\n  } as ISchemaPage,\n  next: {\n    container: nextContainer,\n  } as ISchemaPage,\n  trigger: 'barba',\n};\nconst payload = 'payload';\n\n/**\n * Just do page…\n */\nasync function doPage(leave: any) {\n  await transitions.doPage({\n    data,\n    page: Promise.resolve(),\n    transition: { leave, enter },\n    wrapper,\n  });\n}\n\nbeforeEach(() => {\n  hooks.init();\n});\n\nit('returns with \"promise\"', async () => {\n  expect.assertions(1);\n\n  const leavePromise = () => Promise.resolve(payload);\n\n  await doPage(leavePromise);\n  expect(enter).toHaveBeenCalledWith(data, payload);\n});\n\nit('returns with \"callback\"', async () => {\n  expect.assertions(1);\n\n  const ctx: any = {\n    leaveCallback() {\n      const done = this.async();\n\n      done(null, payload);\n    },\n  };\n\n  await doPage(ctx.leaveCallback);\n  expect(enter).toHaveBeenCalledWith(data, payload);\n});\n\nit('returns with \"sync\"', async () => {\n  expect.assertions(1);\n\n  const leaveSync = () => payload;\n\n  await doPage(leaveSync);\n  expect(enter).toHaveBeenCalledWith(data, payload);\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/transitions/transitions.context.test.ts",
    "content": "import {\n  ISchemaPage,\n  ITransitionData,\n  ITransitionOnce,\n} from '../../../src/defs';\nimport { Logger } from '../../../src/modules/Logger';\nimport { Transitions } from '../../../src/modules/Transitions';\n\n// Silence is gold… :)\nLogger.setLevel('off');\nconst transitions = new Transitions([]);\n\n// Data\nlet data: ITransitionData;\n\nbeforeEach(() => {\n  data = {\n    current: {} as ISchemaPage,\n    next: {} as ISchemaPage,\n    trigger: 'barba',\n  };\n});\n\nit('calls methods', async () => {\n  const t = {\n    bar: jest.fn(),\n    once() {\n      this.bar(this.foo);\n    },\n    foo: 'foo',\n  };\n\n  await transitions.doOnce({\n    data,\n    transition: (t as any) as ITransitionOnce,\n  });\n\n  expect(t.bar).toHaveBeenCalledWith(t.foo);\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/transitions/transitions.get.test.ts",
    "content": "import { ISchemaPage, ITransitionData } from '../../../src/defs';\nimport { Transitions } from '../../../src/modules/Transitions';\n\nconst once = {\n  once: () => Promise.resolve(),\n};\nconst enter = {\n  enter: () => Promise.resolve(),\n};\nconst transitions = new Transitions([once, enter]);\n\nconst data: ITransitionData = {\n  current: {} as ISchemaPage,\n  next: {} as ISchemaPage,\n  trigger: 'barba',\n};\n\nit('gets page transition', () => {\n  expect(transitions.get(data)).toBe(enter);\n});\n\nit('gets once transition', () => {\n  expect(transitions.get(data, { once: true })).toBe(once);\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/transitions/transitions.once.test.ts",
    "content": "import {\n  ISchemaPage,\n  ITransitionData,\n  ITransitionOnce,\n} from '../../../src/defs';\nimport { hooks } from '../../../src/hooks';\nimport { Logger } from '../../../src/modules/Logger';\nimport { Transitions } from '../../../src/modules/Transitions';\n\n// Silence is gold… :)\nLogger.setLevel('off');\nconst transitions = new Transitions([]);\n\n// Mocks\nconst beforeOnce = jest.fn();\nconst once = jest.fn();\nconst afterOnce = jest.fn();\n\nhooks.do = jest.fn();\n\n// Data\nlet data: ITransitionData;\n\nbeforeEach(() => {\n  data = {\n    current: {} as ISchemaPage,\n    next: {} as ISchemaPage,\n    trigger: 'barba',\n  };\n});\n\nit('does not need once', async () => {\n  expect.assertions(1);\n\n  await transitions.doOnce({\n    data,\n    transition: undefined as ITransitionOnce,\n  });\n  expect(hooks.do).toHaveBeenNthCalledWith(2, 'once', data, {});\n});\n\nit('calls methods', async () => {\n  expect.assertions(9);\n\n  await transitions.doOnce({\n    data,\n    transition: { beforeOnce, once, afterOnce },\n  });\n\n  expect(beforeOnce).toHaveBeenCalledTimes(1);\n  expect(beforeOnce).toHaveBeenCalledWith(data);\n\n  expect(once).toHaveBeenCalledTimes(1);\n  expect(once).toHaveBeenCalledWith(data);\n\n  expect(afterOnce).toHaveBeenCalledTimes(1);\n  expect(afterOnce).toHaveBeenCalledWith(data);\n\n  await transitions.doOnce({ data, transition: { once } });\n\n  expect(beforeOnce).toHaveBeenCalledTimes(1);\n  expect(once).toHaveBeenCalledTimes(2);\n  expect(afterOnce).toHaveBeenCalledTimes(1);\n});\n\nit('calls hooks', async () => {\n  expect.assertions(4);\n\n  const t = { once: () => Promise.resolve() };\n\n  await transitions.doOnce({ data, transition: t });\n\n  expect(hooks.do).toHaveBeenCalledTimes(3);\n  expect(hooks.do).toHaveBeenNthCalledWith(1, 'beforeOnce', data, t);\n  expect(hooks.do).toHaveBeenNthCalledWith(2, 'once', data, t);\n  expect(hooks.do).toHaveBeenNthCalledWith(3, 'afterOnce', data, t);\n});\n\nit('catches error', async () => {\n  expect.assertions(2);\n  transitions.logger.debug = jest.fn();\n  transitions.logger.error = jest.fn();\n\n  const err = new Error('Test');\n  const onceError = () => {\n    throw err;\n  };\n  const t = { once: onceError };\n\n  await transitions.doOnce({\n    data,\n    transition: t,\n  });\n\n  expect(transitions.logger.debug).toHaveBeenCalledWith(\n    'Transition error [before/after/once]'\n  );\n  expect(transitions.logger.error).toHaveBeenCalledWith(err);\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/transitions/transitions.page.test.ts",
    "content": "/* tslint:disable:no-empty */\nimport { init } from '../../../__mocks__/barba';\nimport barba from '../../../src';\nimport { IResponse, ISchemaPage, ITransitionData } from '../../../src/defs';\nimport { hooks } from '../../../src/hooks';\nimport { Logger } from '../../../src/modules/Logger';\nimport { Transitions } from '../../../src/modules/Transitions';\n\n// Silence is gold… :)\nLogger.setLevel('off');\nconst transitions = new Transitions([]);\n\n// Mocks\nconst before = jest.fn();\nconst after = jest.fn();\nconst beforeLeave = jest.fn();\nconst leave = jest.fn();\nconst afterLeave = jest.fn();\nconst beforeEnter = jest.fn();\nconst enter = jest.fn();\nconst afterEnter = jest.fn();\n\nhooks.do = jest.fn();\n\n// Dom\nconst { wrapper, container: currentContainer } = init();\n\n// const div = document.createElement('div');\n// const wrapper = div.cloneNode() as HTMLElement;\n// const currentContainer = div.cloneNode() as HTMLElement;\n// const nextContainer = div.cloneNode() as HTMLElement;\nconst nextContainer = currentContainer.cloneNode() as HTMLElement;\nconst nextHtml = `<html>\n  <body>\n    <div data-barba=\"wrapper\">\n      <div data-barba=\"container\" data-barba-namespace=\"next\">\n        Next page\n      </div>\n    </div>\n  </body>\n</html>`;\n\n// Data\nlet data: ITransitionData;\n\nbeforeEach(() => {\n  nextContainer.remove();\n  wrapper.appendChild(currentContainer);\n\n  data = {\n    current: {\n      container: currentContainer,\n      html: undefined,\n      url: {},\n    } as ISchemaPage,\n    next: {\n      container: nextContainer,\n      html: undefined,\n      url: {},\n    } as ISchemaPage,\n    trigger: 'barba',\n  };\n});\n\nconst page = Promise.resolve({\n  html: nextHtml,\n  url: {},\n} as IResponse);\n\nit('leaves falsy', async () => {\n  expect.assertions(1);\n\n  await transitions.doPage({\n    data,\n    page,\n    transition: { leave: () => Promise.resolve(false) },\n    wrapper,\n  });\n  expect(beforeEnter).not.toHaveBeenCalled();\n});\n\nfor (let i = 0; i < 2; i++) {\n  const sync = i === 0;\n\n  it('calls methods', async () => {\n    expect.assertions(20);\n\n    const t = {\n      after,\n      afterEnter,\n      afterLeave,\n      before,\n      beforeEnter,\n      beforeLeave,\n      enter,\n      leave,\n      sync,\n    };\n\n    await transitions.doPage({\n      data,\n      page,\n      transition: t,\n      wrapper,\n    });\n\n    expect(before).toHaveBeenCalledTimes(1);\n    expect(before).toHaveBeenCalledWith(data);\n\n    expect(beforeLeave).toHaveBeenCalledTimes(1);\n    expect(beforeLeave).toHaveBeenCalledWith(data);\n\n    expect(leave).toHaveBeenCalledTimes(1);\n    expect(leave).toHaveBeenCalledWith(data);\n\n    expect(afterLeave).toHaveBeenCalledTimes(1);\n    expect(afterLeave).toHaveBeenCalledWith(data);\n\n    expect(beforeEnter).toHaveBeenCalledTimes(1);\n    expect(beforeEnter).toHaveBeenCalledWith(data);\n\n    expect(enter).toHaveBeenCalledTimes(1);\n    expect(enter).toHaveBeenCalledWith(data, undefined);\n\n    expect(afterEnter).toHaveBeenCalledTimes(1);\n    expect(afterEnter).toHaveBeenCalledWith(data);\n\n    expect(after).toHaveBeenCalledTimes(1);\n    expect(after).toHaveBeenCalledWith(data);\n\n    await transitions.doPage({\n      data,\n      page: Promise.resolve(),\n      transition: { leave, enter },\n      wrapper,\n    });\n\n    expect(before).toHaveBeenCalledTimes(1);\n    expect(leave).toHaveBeenCalledTimes(2);\n    expect(enter).toHaveBeenCalledTimes(2);\n    expect(after).toHaveBeenCalledTimes(1);\n  });\n}\n\nit('calls hooks (sync: false)', async () => {\n  expect.assertions(11);\n\n  const t = {\n    enter,\n    leave,\n    sync: false,\n  };\n\n  await transitions.doPage({\n    data,\n    page,\n    transition: t,\n    wrapper,\n  });\n\n  expect(hooks.do).toHaveBeenCalledTimes(10);\n  expect(hooks.do).toHaveBeenNthCalledWith(1, 'before', data, t);\n  expect(hooks.do).toHaveBeenNthCalledWith(2, 'beforeLeave', data, t);\n  expect(hooks.do).toHaveBeenNthCalledWith(3, 'leave', data, t);\n  expect(hooks.do).toHaveBeenNthCalledWith(4, 'afterLeave', data, t);\n  expect(hooks.do).toHaveBeenNthCalledWith(5, 'nextAdded', data);\n  expect(hooks.do).toHaveBeenNthCalledWith(6, 'beforeEnter', data, t);\n  expect(hooks.do).toHaveBeenNthCalledWith(7, 'enter', data, t);\n  expect(hooks.do).toHaveBeenNthCalledWith(8, 'afterEnter', data, t);\n  expect(hooks.do).toHaveBeenNthCalledWith(9, 'currentRemoved', data);\n  expect(hooks.do).toHaveBeenNthCalledWith(10, 'after', data, t);\n});\n\nit('calls hooks (sync: true)', async () => {\n  expect.assertions(11);\n\n  const t = {\n    enter,\n    leave,\n    sync: true,\n  };\n\n  await transitions.doPage({\n    data,\n    page,\n    transition: t,\n    wrapper,\n  });\n\n  expect(hooks.do).toHaveBeenCalledTimes(10);\n  expect(hooks.do).toHaveBeenNthCalledWith(1, 'before', data, t);\n  expect(hooks.do).toHaveBeenNthCalledWith(2, 'nextAdded', data);\n  expect(hooks.do).toHaveBeenNthCalledWith(3, 'beforeLeave', data, t);\n  expect(hooks.do).toHaveBeenNthCalledWith(4, 'beforeEnter', data, t);\n  expect(hooks.do).toHaveBeenNthCalledWith(5, 'leave', data, t);\n  expect(hooks.do).toHaveBeenNthCalledWith(6, 'enter', data, t);\n  expect(hooks.do).toHaveBeenNthCalledWith(7, 'afterLeave', data, t);\n  expect(hooks.do).toHaveBeenNthCalledWith(8, 'afterEnter', data, t);\n  expect(hooks.do).toHaveBeenNthCalledWith(9, 'currentRemoved', data);\n  expect(hooks.do).toHaveBeenNthCalledWith(10, 'after', data, t);\n});\n\nit('catches error (leave, sync: false)', async () => {\n  expect.assertions(4);\n\n  const leaveError = () => {\n    throw new Error('test');\n  };\n  const t = { leave: leaveError };\n\n  try {\n    await transitions.doPage({\n      data,\n      page,\n      transition: t,\n      wrapper,\n    });\n  } catch (e) {\n    expect(e.name).toEqual('BarbaError');\n    expect(e.label).toEqual('Transition error [before/after/leave]');\n    expect(e.error).toEqual(new Error('test'));\n    expect(transitions.isRunning).toBeFalsy();\n  }\n});\n\nit('catches error (enter, sync: false)', async () => {\n  expect.assertions(4);\n\n  const enterError = () => {\n    throw new Error('test');\n  };\n  const t = {\n    leave() {\n      return Promise.resolve('foo');\n    },\n    enter: enterError,\n  };\n\n  try {\n    await transitions.doPage({\n      data,\n      page,\n      transition: t,\n      wrapper,\n    });\n  } catch (e) {\n    expect(e.name).toEqual('BarbaError');\n    expect(e.label).toEqual('Transition error [before/after/enter]');\n    expect(e.error).toEqual(new Error('test'));\n    expect(transitions.isRunning).toBeFalsy();\n  }\n});\n\nit('catches error (leave, sync: true)', async () => {\n  expect.assertions(3);\n\n  const leaveError = () => {\n    throw new Error('test');\n  };\n  const t = { sync: true, leave: leaveError, enter() {} };\n\n  try {\n    await transitions.doPage({\n      data,\n      page,\n      transition: t,\n      wrapper,\n    });\n  } catch (e) {\n    expect(e.name).toEqual('BarbaError');\n    expect(e.label).toEqual('Transition error [sync]');\n    expect(e.error).toEqual(new Error('test'));\n  }\n});\n\nit('catches error (enter, sync: true)', async () => {\n  expect.assertions(3);\n\n  const enterError = () => {\n    throw new Error('test');\n  };\n  const t = { sync: true, leave() {}, enter: enterError };\n\n  try {\n    await transitions.doPage({\n      data,\n      page,\n      transition: t,\n      wrapper,\n    });\n  } catch (e) {\n    expect(e.name).toEqual('BarbaError');\n    expect(e.label).toEqual('Transition error [sync]');\n    expect(e.error).toEqual(new Error('test'));\n  }\n});\n\nit('catches \"global\" error (before)', async () => {\n  expect.assertions(2);\n\n  const err = new Error('Test');\n  const beforeError = () => {\n    throw err;\n  };\n  const t = { sync: true, leave() {}, enter() {}, before: beforeError };\n\n  try {\n    await transitions.doPage({\n      data,\n      page,\n      transition: t,\n      wrapper,\n    });\n  } catch (e) {\n    expect(e.name).toEqual('Error');\n    expect(e).toEqual(err);\n  }\n});\n\nit('ignores \"non transition\" errors', async () => {\n  expect.assertions(3);\n  const tError = new Error('Weird transition error');\n\n  const leaveError1 = () => {\n    throw new Error('Timeout error');\n  };\n  const leaveError2 = () => {\n    throw new Error('Fetch error');\n  };\n  const enterError3 = () => {\n    const err = new Error('Request error');\n\n    delete err.message;\n    (err as any).status = 500;\n    throw err;\n  };\n  const leaveError4 = () => {\n    delete tError.message;\n    throw tError;\n  };\n  const t1 = { sync: true, leave: leaveError1, enter() {} };\n  const t2 = { leave: leaveError2, enter() {} };\n  const t3 = { leave() {}, enter: enterError3 };\n  const t4 = { leave: leaveError4, enter() {} };\n\n  await transitions.doPage({\n    data,\n    page,\n    transition: t1,\n    wrapper,\n  });\n  await transitions.doPage({\n    data,\n    page,\n    transition: t2,\n    wrapper,\n  });\n  await transitions.doPage({\n    data,\n    page,\n    transition: t3,\n    wrapper,\n  });\n\n  try {\n    await transitions.doPage({\n      data,\n      page,\n      transition: t4,\n      wrapper,\n    });\n  } catch (e) {\n    expect(e.name).toEqual('BarbaError');\n    expect(e.label).toEqual('Transition error [before/after/leave]');\n    expect(e.error).toEqual(tError);\n  }\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/transitions/transitions.test.ts",
    "content": "import { Transitions } from '../../../src/modules/Transitions';\n\nlet transitions: Transitions;\n\nit('has defaults', () => {\n  transitions = new Transitions();\n  expect(transitions.hasOnce).toBeFalsy();\n  expect(transitions.shouldWait).toBeFalsy();\n  expect(transitions.isRunning).toBeFalsy();\n  expect(transitions.store).toBeDefined();\n});\n\nit('has once', () => {\n  transitions = new Transitions([{ once: () => Promise.resolve() }]);\n  expect(transitions.hasOnce).toBeTruthy();\n});\n\nit('should wait', () => {\n  transitions = new Transitions([{ to: { namespace: 'ns' } }]);\n  expect(transitions.shouldWait).toBeTruthy();\n  transitions = new Transitions([{ sync: true }]);\n  expect(transitions.shouldWait).toBeTruthy();\n});\n"
  },
  {
    "path": "packages/core/__tests__/modules/views.test.ts",
    "content": "import { IView } from '../../src/defs';\nimport { hooks } from '../../src/hooks';\nimport { Views } from '../../src/modules/Views';\n\nlet views: Views;\n\n// beforeEach(() => {\n//   hooks.init();\n// });\n\nafterEach(() => {\n  hooks.clear();\n});\n\nconst beforeLeave = jest.fn();\nconst afterLeave = jest.fn();\nconst beforeEnter = jest.fn();\nconst afterEnter = jest.fn();\n\nit('has defaults', () => {\n  views = new Views([]);\n\n  expect(views.byNamespace.size).toBe(0);\n});\n\nit('init views', () => {\n  views = new Views([\n    { namespace: 'foo', name: 'overriden' },\n    { namespace: 'foo', name: 'ok' },\n    { namespace: 'bar', name: 'ok' },\n  ]);\n  expect(views.byNamespace.get('foo')).toEqual({\n    name: 'ok',\n    namespace: 'foo',\n  });\n  expect(views.byNamespace.get('bar')).toEqual({\n    name: 'ok',\n    namespace: 'bar',\n  });\n});\n\nit('register hooks', () => {\n  // No views, no hooks\n  views = new Views([]);\n  expect(hooks.registered.get('beforeLeave')).toBeUndefined();\n  expect(hooks.registered.get('afterLeave')).toBeUndefined();\n  expect(hooks.registered.get('beforeEnter')).toBeUndefined();\n  expect(hooks.registered.get('afterEnter')).toBeUndefined();\n\n  views = new Views([{ namespace: 'baz' }]);\n  expect(hooks.registered.get('beforeLeave').size).toBe(1);\n  expect(hooks.registered.get('afterLeave').size).toBe(1);\n  expect(hooks.registered.get('beforeEnter').size).toBe(1);\n  expect(hooks.registered.get('afterEnter').size).toBe(1);\n});\n\n/* tslint:disable:object-literal-sort-keys */\nit('do existing hooks for existing namespace', async () => {\n  views = new Views([\n    {\n      namespace: 'success',\n      beforeLeave,\n      afterLeave,\n      beforeEnter,\n      afterEnter,\n    },\n  ]);\n  /* tslint:enable:object-literal-sort-keys */\n\n  const success = {\n    current: { namespace: 'success' },\n    next: { namespace: 'success' },\n  };\n\n  await hooks.do('beforeLeave', success);\n  await hooks.do('afterLeave', success);\n  await hooks.do('beforeEnter', success);\n  await hooks.do('afterEnter', success);\n\n  expect(beforeLeave).toHaveBeenCalledWith(success);\n  expect(afterLeave).toHaveBeenCalledWith(success);\n  expect(beforeEnter).toHaveBeenCalledWith(success);\n  expect(afterEnter).toHaveBeenCalledWith(success);\n});\n\nit('do nothing for missing hooks', () => {\n  views = new Views([{ namespace: 'success' }]);\n\n  const success = {\n    current: { namespace: 'success' },\n    next: { namespace: 'success' },\n  };\n\n  hooks.do('beforeLeave', success);\n  hooks.do('afterLeave', success);\n  hooks.do('beforeEnter', success);\n  hooks.do('afterEnter', success);\n\n  expect(beforeLeave).not.toHaveBeenCalled();\n  expect(afterLeave).not.toHaveBeenCalled();\n  expect(beforeEnter).not.toHaveBeenCalled();\n  expect(afterEnter).not.toHaveBeenCalled();\n});\n\nit('do nothing for missing namespace', () => {\n  views = new Views([\n    { namespace: 'success', beforeLeave, afterLeave, beforeEnter, afterEnter },\n  ]);\n  const fail = { current: { namespace: 'fail' }, next: { namespace: 'fail' } };\n\n  hooks.do('beforeLeave', fail);\n  hooks.do('afterLeave', fail);\n  hooks.do('beforeEnter', fail);\n  hooks.do('afterEnter', fail);\n\n  expect(beforeLeave).not.toHaveBeenCalled();\n  expect(afterLeave).not.toHaveBeenCalled();\n  expect(beforeEnter).not.toHaveBeenCalled();\n  expect(afterEnter).not.toHaveBeenCalled();\n});\n\nit('has right context', async () => {\n  const v = {\n    bar: jest.fn(),\n    beforeEnter() {\n      this.bar(this.foo);\n    },\n    foo: 'foo',\n    namespace: 'success',\n  };\n\n  views = new Views([v]);\n\n  const success = {\n    next: { namespace: 'success' },\n  };\n\n  await hooks.do('beforeEnter', success);\n\n  expect(v.bar).toHaveBeenCalledWith(v.foo);\n});\n"
  },
  {
    "path": "packages/core/__tests__/utils/dom.test.ts",
    "content": "/* tslint:disable:no-string-literal */\nimport { schemaAttribute } from '../../src/schemas/attribute';\nimport { dom } from '../../src/utils';\n\n// Init\nconst attr = schemaAttribute;\n\n// Dom\nconst namespace = 'ns';\nconst currentContainer = document.createElement('div');\nconst nextContainer = document.createElement('div');\nconst wrapper = document.createElement('div');\nconst link = document.createElement('a');\nconst svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n\n// const svgLink = document.createElement('a');\nconst svgLink = document.createElementNS('http://www.w3.org/2000/svg', 'a');\nconst svgXlink = document.createElementNS('http://www.w3.org/2000/svg', 'a');\n\nsvg.appendChild(svgLink);\nsvg.appendChild(svgXlink);\n\ncurrentContainer.setAttribute(attr.prefix, attr.container);\ncurrentContainer.setAttribute(`${attr.prefix}-${attr.namespace}`, namespace);\n\nwrapper.setAttribute(attr.prefix, attr.wrapper);\n\n// Expected\nconst checkDoc = new RegExp(\n  // tslint:disable-next-line:max-line-length\n  `^<html>[\\\\s\\\\S]+body[\\\\s\\\\S]+${dom['_attr'].wrapper}[\\\\s\\\\S]+${dom['_attr'].container}[\\\\s\\\\S]+${namespace}[\\\\s\\\\S]+</html>$`\n);\nconst checkHref = 'http://localhost/page.html';\n\nafterEach(() => {\n  wrapper.innerHTML = '';\n  document.body.innerHTML = '';\n});\n\nit('has attributeSchema', () => {\n  expect(dom['_attr']).toBe(schemaAttribute);\n});\n\nit('stringifies DOM', () => {\n  expect(typeof dom.toString(currentContainer)).toBe('string');\n});\n\n// see https://github.com/barbajs/barba/issues/362\n// it('parses string to Doc', () => {\n//   expect(dom.toDocument('<div></div>') instanceof HTMLDocument).toBeTruthy();\n// });\n\nit('parses string to Element', () => {\n  expect(dom.toElement('<div></div>') instanceof HTMLDivElement).toBeTruthy();\n});\n\nit('get html', () => {\n  wrapper.appendChild(currentContainer);\n  document.body.appendChild(wrapper);\n\n  expect(dom.getHtml()).toMatch(checkDoc);\n  expect(dom.getHtml(document)).toMatch(checkDoc);\n});\n\nit('get wrapper', () => {\n  expect(dom.getWrapper()).toBeNull();\n\n  wrapper.appendChild(currentContainer);\n  document.body.appendChild(wrapper);\n\n  expect(dom.getWrapper()).toBe(wrapper);\n  expect(dom.getWrapper(document.body)).toBe(wrapper);\n});\n\nit('get container', () => {\n  expect(dom.getContainer()).toBeNull();\n\n  wrapper.appendChild(currentContainer);\n  document.body.appendChild(wrapper);\n\n  expect(dom.getContainer()).toBe(currentContainer);\n  expect(dom.getContainer(wrapper)).toBe(currentContainer);\n});\n\nit('get namespace', () => {\n  expect(dom.getNamespace()).toBeNull();\n\n  wrapper.appendChild(currentContainer);\n  document.body.appendChild(wrapper);\n\n  expect(dom.getNamespace()).toBe(namespace);\n  expect(dom.getNamespace(wrapper)).toBe(namespace);\n});\n\nit('get href [link / absolute]', () => {\n  link.setAttribute('href', 'http://localhost/page.html');\n\n  expect(dom.getHref(link)).toBe(checkHref);\n});\n\nit('get href [link / relative]', () => {\n  link.setAttribute('href', 'page.html');\n\n  expect(dom.getHref(link)).toBe(checkHref);\n});\n\nit('get href [svg / absolute]', () => {\n  const val = 'http://localhost/page.html';\n\n  svgLink.setAttribute('href', val);\n  svgXlink.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', val);\n\n  expect(dom.getHref(svgLink)).toBe(checkHref);\n  expect(dom.getHref(svgXlink)).toBe(checkHref);\n});\n\nit('get href [svg / absolute no protocol]', () => {\n  const val = '//localhost/page.html';\n\n  svgLink.setAttribute('href', val);\n  svgXlink.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', val);\n\n  expect(dom.getHref(svgLink)).toBe(checkHref);\n  expect(dom.getHref(svgXlink)).toBe(checkHref);\n});\n\nit('get href [svg / relative root]', () => {\n  const val = '/page.html';\n\n  svgLink.setAttribute('href', val);\n  svgXlink.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', val);\n\n  expect(dom.getHref(svgLink)).toBe(checkHref);\n  expect(dom.getHref(svgXlink)).toBe(checkHref);\n});\n\nit('get href [svg / relative simple]', () => {\n  const val = 'page.html';\n\n  svgLink.setAttribute('href', val);\n  svgXlink.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', val);\n\n  expect(dom.getHref(svgLink)).toBe(checkHref);\n  expect(dom.getHref(svgXlink)).toBe(checkHref);\n});\n\nit('get href [svg / relative same]', () => {\n  const val = './page.html';\n\n  svgLink.setAttribute('href', val);\n  svgXlink.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', val);\n\n  expect(dom.getHref(svgLink)).toBe(checkHref);\n  expect(dom.getHref(svgXlink)).toBe(checkHref);\n});\n\nit('get href [svg / relative level]', () => {\n  (global as any).jsdom.reconfigure({ url: 'http://localhost/foo/' });\n  const val = '../page.html';\n\n  svgLink.setAttribute('href', val);\n  svgXlink.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', val);\n\n  expect(dom.getHref(svgLink)).toBe(checkHref);\n  expect(dom.getHref(svgXlink)).toBe(checkHref);\n});\n\nit('get href [svg / relative level]', () => {\n  const url = 'http://localhost/foo.html';\n  const val = '#hash';\n\n  (global as any).jsdom.reconfigure({ url });\n\n  svgLink.setAttribute('href', val);\n  svgXlink.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', val);\n\n  expect(dom.getHref(svgLink)).toBe(url + val);\n  expect(dom.getHref(svgXlink)).toBe(url + val);\n});\n\nit('remove container', () => {\n  document.body.appendChild(wrapper);\n\n  dom.removeContainer(currentContainer);\n\n  expect(wrapper.children.length).toBe(0);\n});\n\nit('add container', () => {\n  wrapper.appendChild(currentContainer);\n  document.body.appendChild(wrapper);\n\n  dom.addContainer(nextContainer, wrapper);\n  dom.removeContainer(currentContainer);\n\n  expect(wrapper.children.length).toBe(1);\n});\n\nit('add container with container sibling', () => {\n  wrapper.appendChild(currentContainer);\n  document.body.appendChild(wrapper);\n\n  dom.addContainer(nextContainer, wrapper);\n\n  expect(wrapper.children.length).toBe(2);\n  expect(nextContainer.previousElementSibling).toBe(currentContainer);\n  expect(dom.getContainer()).toBe(currentContainer);\n});\n\nit('add container with before sibling', () => {\n  const before = document.createElement('div');\n\n  wrapper.appendChild(before);\n  wrapper.appendChild(currentContainer);\n  document.body.appendChild(wrapper);\n\n  dom.removeContainer(currentContainer);\n  dom.addContainer(nextContainer, wrapper);\n\n  expect(wrapper.children.length).toBe(2);\n  expect(nextContainer.previousElementSibling).toBe(before);\n  expect(dom.getSibling().before).not.toBeNull();\n});\n\nit('add container with after sibling', () => {\n  const after = document.createElement('div');\n\n  wrapper.appendChild(currentContainer);\n  wrapper.appendChild(after);\n  document.body.appendChild(wrapper);\n\n  dom.removeContainer(currentContainer);\n  dom.addContainer(nextContainer, wrapper);\n\n  expect(wrapper.children.length).toBe(2);\n  expect(nextContainer.nextElementSibling).toBe(after);\n  expect(dom.getSibling().after).not.toBeNull();\n});\n\nit('add container with parent sibling', () => {\n  const parent = document.createElement('div');\n\n  parent.appendChild(currentContainer);\n  wrapper.appendChild(parent);\n  document.body.appendChild(wrapper);\n\n  dom.removeContainer(currentContainer);\n  dom.addContainer(nextContainer, wrapper);\n\n  expect(wrapper.children.length).toBe(1);\n  expect(nextContainer.parentNode).toBe(parent);\n  expect(dom.getSibling().parent).not.toBeNull();\n});\n"
  },
  {
    "path": "packages/core/__tests__/utils/history.test.ts",
    "content": "import { history } from '../../src/utils/history';\n\nconst first = {\n  data: {},\n  ns: 'ns1',\n  scroll: {\n    x: 0,\n    y: 0,\n  },\n  url: 'url1',\n};\nconst second = {\n  data: {},\n  ns: 'ns2',\n  scroll: {\n    x: 0,\n    y: 0,\n  },\n  url: 'url2',\n};\nconst tmp = {\n  ...second,\n  ns: 'tmp',\n};\nconst triggerPush = document.createElement('a');\nconst triggerReplace = document.createElement('a');\n\ntriggerReplace.dataset.barbaHistory = 'replace';\n\nconst e = {\n  state: {\n    index: 1,\n  },\n} as PopStateEvent;\n\nconst h = {\n  b: (global as any).window.history.back = jest.fn(),\n  ps: (global as any).window.history.pushState = jest.fn(),\n  rs: (global as any).window.history.replaceState = jest.fn(),\n};\n\nconst data = {\n  custom: 'data',\n};\n\nafterEach(() => {\n  history.clear();\n});\n\nit('has no history', () => {\n  expect(history.current).toBeUndefined();\n});\n\nit('init state and has current', () => {\n  history.init(first.url, first.ns);\n\n  expect(history.current).toEqual(first);\n  expect(history.previous).toBeNull();\n  expect(h.rs).toHaveBeenCalledTimes(1);\n});\n\nit('adds state and has previous', () => {\n  history.init(first.url, first.ns);\n  history.change(second.url, 'barba');\n\n  expect(history.current).toEqual(tmp);\n  expect(history.previous).toEqual(first);\n});\n\nit('pushes history', () => {\n  history.change(first.url, triggerPush);\n  history.change(second.url, triggerReplace);\n  history.change(second.url, 'popstate', e);\n\n  expect(h.ps).toHaveBeenCalledTimes(1);\n});\n\nit('replaces history', () => {\n  history.change(first.url, triggerReplace);\n  history.change(second.url, triggerPush);\n  history.change(second.url, 'popstate', e);\n\n  expect(h.rs).toHaveBeenCalledTimes(1);\n});\n\nit('removes state', () => {\n  history.init(first.url, first.ns);\n  history.change(second.url, 'barba');\n  history.remove();\n\n  expect(history.current).toEqual(first);\n  expect(history.previous).toBeNull();\n\n  history.change(second.url, 'barba');\n  history.remove(1);\n\n  expect(history.current).toEqual(first);\n  expect(history.previous).toBeNull();\n});\n\nit('gets state(s)', () => {\n  history.init(first.url, first.ns);\n  history.change(second.url, 'barba');\n  const state1 = history.get(0);\n  const state2 = history.get(1);\n  const state = history.current;\n\n  expect(state1).toEqual(first);\n  expect(state2).toEqual(tmp);\n  expect(state).toEqual(tmp);\n});\n\nit('gets directions', () => {\n  history.init(first.url, first.ns);\n  history.change(second.url, 'barba');\n\n  const back = history.change(first.url, 'popstate', {\n    state: { index: 0 },\n  } as PopStateEvent);\n  expect(back).toEqual('back');\n\n  const forward = history.change(second.url, 'popstate', {\n    state: { index: 1 },\n  } as PopStateEvent);\n  expect(forward).toEqual('forward');\n\n  const prev = history.change(second.url, 'popstate', {\n    state: { index: 6 },\n  } as PopStateEvent);\n  expect(prev).toEqual('back');\n\n  const next = history.change(second.url, 'popstate', {\n    state: { index: 0 },\n  } as PopStateEvent);\n  expect(next).toEqual('forward');\n});\n\nit('manage history with \"unknown\" state', async () => {\n  history.change(second.url, 'barba');\n\n  expect(h.rs).toHaveBeenCalledTimes(0);\n  expect(h.ps).toHaveBeenCalledTimes(1);\n});\n\nit('manage history with previous state', async () => {\n  history.change(second.url, 'popstate', e);\n\n  expect(h.ps).toHaveBeenCalledTimes(0);\n  expect(h.rs).toHaveBeenCalledTimes(0);\n});\n\nit('manage history with data-barba-history=\"replace\"', async () => {\n  const link = document.createElement('a');\n\n  link.dataset.barbaHistory = 'replace';\n\n  history.add(second.url, link);\n\n  expect(h.ps).toHaveBeenCalledTimes(0);\n  expect(h.rs).toHaveBeenCalledTimes(1);\n});\n\nit('manage history with programmatic push', async () => {\n  history.add(first.url, 'barba', 'push');\n\n  expect(h.ps).toHaveBeenCalledTimes(1);\n  expect(h.rs).toHaveBeenCalledTimes(0);\n});\n\nit('manage history with programmatic replace', async () => {\n  history.add(first.url, 'barba', 'replace');\n\n  expect(h.ps).toHaveBeenCalledTimes(0);\n  expect(h.rs).toHaveBeenCalledTimes(1);\n});\n\nit('manage history with programmatic push and custom data', async () => {\n  history.add(first.url, 'barba', 'push', data);\n  expect(history.current.data).toEqual(data);\n});\n\nit('manage history with programmatic replace and custom data', async () => {\n  history.add(first.url, 'barba', 'replace', data);\n  expect(history.current.data).toEqual(data);\n});\n\nit('store custom user data', async () => {\n  history.init(first.url, first.ns);\n  history.store(data);\n\n  expect(history.current.data).toEqual(data);\n});\n\nit('store custom user data per state', async () => {\n  const state1 = {\n    state: 1,\n  };\n\n  const state2 = {\n    state: 2,\n  };\n\n  history.init(first.url, first.ns);\n  history.store(state1);\n  history.change(second.url, 'barba');\n  history.store(state2);\n\n  expect(history.previous.data).toEqual(state1);\n  expect(history.current.data).toEqual(state2);\n});\n\nit('merge custom user data with existing one', async () => {\n  const update = {\n    additional: 'data',\n  };\n\n  history.init(first.url, first.ns);\n  history.store(data);\n  history.store(update);\n\n  expect(history.current.data).toEqual({\n    ...data,\n    ...update,\n  });\n});\n"
  },
  {
    "path": "packages/core/__tests__/utils/request.test.ts",
    "content": "import xhrMock from 'xhr-mock';\nimport { init } from '../../__mocks__/barba';\nimport barba from '../../src';\nimport { IResponse, IUrlFull } from '../../src/defs';\nimport { request } from '../../src/utils';\nimport { parse } from '../../src/utils/url';\n\ninit();\n\n(global as any).Headers = class {};\n(global as any).window.clearTimeout = jest.fn();\nconst requestError = jest.fn();\nconst url = 'url';\nconst content = 'content';\nconst response = {\n  html: content,\n  url: {\n    href: url,\n    ...parse(url)\n  } as IUrlFull,\n} as IResponse;\n\nbeforeEach(() => {\n  xhrMock.setup();\n});\nafterEach(() => {\n  delete (global as any).navigator.connection;\n  xhrMock.teardown();\n});\n\nit('set correct headers', async () => {\n  expect.assertions(2);\n\n  xhrMock.get(url, (req, res) => {\n    expect(req.header('Accept')).toEqual(\n      'text/html,application/xhtml+xml,application/xml'\n    );\n    expect(req.header('x-barba')).toEqual('yes');\n\n    return res.status(200);\n  });\n\n  await request(url, 2e3, requestError, barba.cache, barba.headers);\n});\n\nit('set custom request headers', async () => {\n  barba.headers.set('x-custom-header', 'custom-value');\n\n  xhrMock.get(url, (req, res) => {\n    expect(req.header('x-custom-header')).toEqual('custom-value');\n\n    return res.status(200);\n  });\n\n  await request(url, 2e3, requestError, barba.cache, barba.headers);\n});\n\nit('throws fetch error', async () => {\n  const error = new Error('Fetch error');\n\n  xhrMock.get(url, () => Promise.reject(error));\n  xhrMock.error(() => {}); // tslint:disable-line:no-empty\n\n  await expect(request(url, 2e3, requestError, barba.cache, barba.headers)).rejects.toEqual(error);\n  expect(requestError).toHaveBeenCalledWith(url, error);\n  expect(barba.cache.getStatus(url)).toEqual('rejected');\n});\n\nit('throws result error with 404', async () => {\n  const error = {\n    status: 404,\n    statusText: 'Not found',\n  };\n\n  xhrMock.get(url, (req, res) => res.status(404).reason('Not found'));\n\n  await expect(request(url, 2e3, requestError, barba.cache, barba.headers)).rejects.toEqual(error);\n  expect(requestError).toHaveBeenCalledWith(url, error);\n  expect(barba.cache.getStatus(url)).toEqual('rejected');\n});\n\nit('throws timeout error', async () => {\n  const error = new Error('Timeout error [100]');\n\n  xhrMock.get(url, () => new Promise(() => {})); // tslint:disable-line:no-empty\n\n  await expect(request(url, 100, requestError, barba.cache, barba.headers)).rejects.toEqual(error);\n  expect(requestError).toHaveBeenCalledWith(url, error);\n  expect(barba.cache.getStatus(url)).toEqual('rejected');\n}, 1000);\n\nit('fetch text content', async () => {\n  xhrMock.get(url, (req, res) => res.status(200).body(content));\n\n  await expect(request(url, undefined, requestError, barba.cache, barba.headers)).resolves.toStrictEqual(response);\n  // expect((global as any).window.clearTimeout).toHaveBeenCalledTimes(1);\n  expect(requestError).not.toHaveBeenCalled();\n  expect(barba.cache.getStatus(url)).toEqual('fulfilled');\n});\n\n// it('throws bad connection error', async () => {\n//   const error = new Error('Bad connection or reduced data usage mode');\n\n//   global.navigator.connection = {\n//     effectiveType: '2g',\n//     saveData: false,\n//   };\n\n//   await expect(request(url, 2e3, requestError)).rejects.toEqual(error);\n// });\n\n// it('throws reduced data error', async () => {\n//   const error = new Error('Bad connection or reduced data usage mode');\n\n//   global.navigator.connection = {\n//     effectiveType: '3g',\n//     saveData: true,\n//   };\n\n//   await expect(request(url, 2e3, requestError)).rejects.toEqual(error);\n// });\n"
  },
  {
    "path": "packages/core/__tests__/utils/url.test.ts",
    "content": "/* global jsdom */\nimport { url } from '../../src/utils';\n\nit('get href', () => {\n  const href = url.getHref();\n\n  expect(href).toBe(window.location.href);\n});\n\nit('get absolute href', () => {\n  const href1 = url.getAbsoluteHref('/foo.html');\n  const href2 = url.getAbsoluteHref('/foo.html', 'https://barba.js.org');\n\n  expect(href1).toBe('http://localhost/foo.html');\n  expect(href2).toBe('https://barba.js.org/foo.html');\n});\n\nit('get origin', () => {\n  const origin = url.getOrigin();\n\n  expect(origin).toBe(window.location.origin);\n});\n\nit('get port', () => {\n  expect(url.getPort()).toBe(80);\n\n  (global as any).jsdom.reconfigure({ url: 'https://localhost/' });\n  expect(url.getPort()).toBe(443);\n\n  (global as any).jsdom.reconfigure({ url: 'https://localhost:6666/' });\n  expect(url.getPort()).toBe(6666);\n\n  (global as any).jsdom.reconfigure({ url: 'http://localhost/' });\n});\n\nit('get path', () => {\n  expect(url.getPath()).toBe('/');\n\n  (global as any).jsdom.reconfigure({\n    url: 'http://localhost/qux.html?foo=bar#hash',\n  });\n  expect(url.getPath()).toBe('/qux.html');\n\n  const path = url.getPath('http://localhost/foo.html?foo=bar#hash');\n\n  expect(path).toBe('/foo.html');\n});\n\nit('get query', () => {\n  const query = url.getQuery('http://localhost/foo.html?foo=bar#hash');\n  const queryAsString = url.getQuery('http://localhost/foo.html?foo=bar#hash', true);\n\n  expect(query).toEqual({ foo: 'bar' });\n  expect(queryAsString).toEqual('{\"foo\":\"bar\"}');\n});\n\nit('get hash', () => {\n  const hash = url.getHash('http://localhost/foo.html?foo=bar#hash');\n\n  expect(hash).toBe('hash');\n});\n\nit('parse minimal path', () => {\n  const { path, query, hash } = url.parse('/');\n\n  expect(path).toBe('/');\n  expect(query).toEqual({});\n  expect(hash).toBeUndefined();\n});\n\nit('parse full path', () => {\n  const { path, query, hash } = url.parse('/foo?baz=qux#bar');\n\n  expect(path).toBe('/foo');\n  expect(query).toEqual({ baz: 'qux' });\n  expect(hash).toBe('bar');\n});\n\nit('parse simple query', () => {\n  const query = url.parseQuery('foo=bar');\n\n  expect(query).toEqual({ foo: 'bar' });\n});\n\nit('parse complex query', () => {\n  const query = url.parseQuery('foo=bar&baz=qux');\n\n  expect(query).toEqual({ foo: 'bar', baz: 'qux' });\n});\n\nit('clean url', () => {\n  // const result = url.clean('http://localhost/foo', window.location.origin);\n  // expect(result).toBe('/foo');\n  const result = url.clean('http://localhost/foo?bar=baz#qux');\n\n  expect(result).toBe('http://localhost/foo?bar=baz');\n});\n"
  },
  {
    "path": "packages/core/__web__/container.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n  <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n  <title>container</title>\n</head>\n\n<body>\n  <div data-barba=\"wrapper\" data-test-wrapper=\"current\">\n    <ol data-test=\"hooks-list\"></ol>\n    <div data-barba=\"container\" data-barba-namespace=\"container\" data-test-container=\"current\">\n      <h1 data-test=\"title\">container</h1>\n      <a data-test=\"link\" href=\"page.html\">Go to page</a>\n      <a data-test=\"link.sync\" href=\"page.html\">Go to page</a>\n    </div>\n    <pre data-test=\"sibling\">sibling element</pre>\n  </div>\n  <script src=\"../dist/barba.umd.js\"></script>\n  <script src=\"scripts/container.js\" type=\"module\"></script>\n</body>\n\n</html>\n"
  },
  {
    "path": "packages/core/__web__/href.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n  <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n  <title>href</title>\n</head>\n\n<body>\n  <div data-barba=\"wrapper\" data-test-wrapper=\"current\">\n    <ol data-test=\"hooks-list\"></ol>\n    <div data-barba=\"container\" data-barba-namespace=\"href\" data-test-container=\"current\">\n      <h1 data-test=\"title\">href</h1>\n      <a data-test=\"link\" href=\"page.html\">Go to page</a>\n      <br>\n      <a data-test=\"query\" href=\"page.html?query=string\">Go to query</a>\n      <br>\n      <a data-test=\"hash\" href=\"page.html#hash\">Go to hash</a>\n      <br>\n      <a data-test=\"complex\" href=\"page.html?query=string#hash\">Go to complex</a>\n    </div>\n  </div>\n  <script src=\"../dist/barba.umd.js\"></script>\n  <script src=\"scripts/href.js\" type=\"module\"></script>\n</body>\n\n</html>\n"
  },
  {
    "path": "packages/core/__web__/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n    <title>home</title>\n  </head>\n  <body>\n    <div data-barba=\"wrapper\" data-test-wrapper=\"current\">\n      <ol data-test=\"hooks-list\"></ol>\n      <div\n        data-barba=\"container\"\n        data-barba-namespace=\"home\"\n        data-test-container=\"current\"\n      >\n        <h1 data-test=\"title\">home</h1>\n        <a data-test=\"link\" href=\"page.html\">Go to page</a>\n        <a data-test=\"link.hooks\" href=\"page.html\">Test hooks</a>\n        <a data-test=\"link.hooks-sync\" href=\"page.html\">Test hooks sync</a>\n      </div>\n    </div>\n    <script src=\"../dist/barba.umd.js\"></script>\n    <script src=\"scripts/default.js\" type=\"module\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "packages/core/__web__/page.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n    <title>page</title>\n  </head>\n  <body>\n    <div data-barba=\"wrapper\" data-test-wrapper=\"next\">\n      <div\n        data-barba=\"container\"\n        data-barba-namespace=\"page\"\n        data-test-container=\"next\"\n      >\n        <h1 data-test=\"title\">page</h1>\n        <a data-test=\"link\" href=\"index.html\">Go to home</a>\n      </div>\n    </div>\n  </body>\n</html>\n"
  },
  {
    "path": "packages/core/__web__/scripts/container.js",
    "content": "/* eslint-disable no-empty-function */\nconsole.info('🚀 Barba e2e');\n\nconst { barba } = window;\n\nbarba.init({\n  debug: true,\n  transitions: [\n    {\n      leave() {},\n      enter() {},\n    },\n    {\n      sync: true,\n      custom: ({ trigger }) =>\n        trigger.dataset && trigger.dataset.barbaTest === 'link.sync',\n      leave() {},\n      enter() {},\n    },\n  ],\n});\n"
  },
  {
    "path": "packages/core/__web__/scripts/default.js",
    "content": "console.info('🚀 Barba e2e');\nimport { hooks, hooksSync } from './transitions/hooks.js';\n\nconst { barba } = window;\n\nbarba.init({\n  debug: true,\n  transitions: [hooks, hooksSync],\n});\n"
  },
  {
    "path": "packages/core/__web__/scripts/href.js",
    "content": "/* eslint-disable no-empty-function */\nconsole.info('🚀 Barba e2e');\n\nconst { barba } = window;\n\nbarba.init({\n  debug: true,\n  transitions: [\n    {\n      leave() {},\n      enter() {},\n    },\n  ],\n});\n"
  },
  {
    "path": "packages/core/__web__/scripts/transitions/hooks.js",
    "content": "/* eslint-disable newline-before-return */\nconst { barba } = window;\nconst list = document.querySelector('[data-test=\"hooks-list\"]');\n\n/**\n * Append list item\n *\n * @param {*} str List item content\n * @param {string} prefix Prefix for global\n * @returns {void}\n */\nfunction append(str, prefix = '') {\n  const item = document.createElement('li');\n\n  item.textContent = prefix + str;\n  list.appendChild(item);\n}\n\n/**\n * Promisify hooks\n *\n * @returns {Promise} Promise\n */\nfunction sleep() {\n  return new Promise(resolve => {\n    setTimeout(resolve, 100);\n  });\n}\n\nexport const base = {\n  beforeOnce() {\n    append('beforeOnce');\n    return sleep();\n  },\n  once() {\n    append('once');\n    return sleep();\n  },\n  afterOnce() {\n    append('afterOnce');\n    return sleep();\n  },\n  before() {\n    append('before');\n    return sleep();\n  },\n  beforeLeave() {\n    append('beforeLeave');\n    return sleep();\n  },\n  leave() {\n    append('leave');\n    return sleep();\n  },\n  afterLeave() {\n    append('afterLeave');\n    return sleep();\n  },\n  beforeEnter() {\n    append('beforeEnter');\n    return sleep();\n  },\n  enter() {\n    append('enter');\n    return sleep();\n  },\n  afterEnter() {\n    append('afterEnter');\n    return sleep();\n  },\n  after() {\n    append('after');\n    return sleep();\n  },\n};\n\nbarba.hooks.beforeOnce(() => {\n  append('beforeOnce', 'global:');\n});\nbarba.hooks.once(() => {\n  append('once', 'global:');\n});\nbarba.hooks.afterOnce(() => {\n  append('afterOnce', 'global:');\n});\nbarba.hooks.before(() => {\n  append('before', 'global:');\n});\nbarba.hooks.beforeLeave(() => {\n  append('beforeLeave', 'global:');\n});\nbarba.hooks.leave(() => {\n  append('leave', 'global:');\n});\nbarba.hooks.afterLeave(() => {\n  append('afterLeave', 'global:');\n});\nbarba.hooks.beforeEnter(() => {\n  append('beforeEnter', 'global:');\n});\nbarba.hooks.enter(() => {\n  append('enter', 'global:');\n});\nbarba.hooks.afterEnter(() => {\n  append('afterEnter', 'global:');\n});\nbarba.hooks.after(() => {\n  append('after', 'global:');\n});\n\nexport const hooks = {\n  ...base,\n  custom: ({ trigger }) =>\n    trigger === 'barba' ||\n    (trigger.dataset && trigger.dataset.test === 'link.hooks'),\n};\n\nexport const hooksSync = {\n  ...base,\n  sync: true,\n  custom: ({ trigger }) =>\n    trigger.dataset && trigger.dataset.test === 'link.hooks-sync',\n};\n"
  },
  {
    "path": "packages/core/__web__/scripts/views/hooks.js",
    "content": "/* eslint-disable newline-before-return */\nconst list = document.querySelector('[data-test=\"hooks-list\"]');\n\n/**\n * Append list item\n *\n * @param {*} str List item content\n * @param {string} prefix Prefix for global\n * @returns {void}\n */\nfunction append(str, prefix = '') {\n  const item = document.createElement('li');\n\n  item.textContent = prefix + str;\n  list.appendChild(item);\n}\n\nexport const home = {\n  namespace: 'home',\n  beforeLeave() {\n    append('beforeLeave');\n  },\n  afterLeave() {\n    append('afterLeave');\n  },\n  beforeEnter() {\n    append('beforeEnter');\n  },\n  afterEnter() {\n    append('afterEnter');\n  },\n};\n\nexport const page = {\n  namespace: 'page',\n  beforeLeave() {\n    append('beforeLeave');\n  },\n  afterLeave() {\n    append('afterLeave');\n  },\n  beforeEnter() {\n    append('beforeEnter');\n  },\n  afterEnter() {\n    append('afterEnter');\n  },\n};\n"
  },
  {
    "path": "packages/core/__web__/scripts/views.js",
    "content": "console.info('🚀 Barba e2e');\nimport { home, page } from './views/hooks.js';\n\nconst { barba } = window;\n\n// const list = document.querySelector('[data-test=\"hooks-list\"]');\n\n// /**\n//  * Append list item\n//  *\n//  * @param {*} str List item content\n//  * @param {string} prefix Prefix for global\n//  * @returns {void}\n//  */\n// function append(str, prefix = '') {\n//   const item = document.createElement('li');\n\n//   item.textContent = prefix + str;\n//   list.appendChild(item);\n// }\n\n// barba.hooks.beforeEnter(() => {\n//   console.info('global.beforeEnter');\n//   append('global.beforeEnter');\n// });\n// barba.hooks.afterEnter(() => {\n//   console.info('global.afterEnter');\n//   append('global.afterEnter');\n// });\n\nbarba.init({\n  debug: true,\n  views: [home, page],\n});\n"
  },
  {
    "path": "packages/core/__web__/views.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n    <title>home</title>\n  </head>\n  <body>\n    <div data-barba=\"wrapper\" data-test-wrapper=\"current\">\n      <ol data-test=\"hooks-list\"></ol>\n      <div\n        data-barba=\"container\"\n        data-barba-namespace=\"home\"\n        data-test-container=\"current\"\n      >\n        <h1 data-test=\"title\">home</h1>\n        <a data-test=\"link\" href=\"page.html\">Go to page</a>\n        <a data-test=\"link.hooks\" href=\"page.html\">Test views hooks</a>\n      </div>\n    </div>\n    <script src=\"../dist/barba.umd.js\"></script>\n    <script src=\"scripts/views.js\" type=\"module\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "packages/core/jest.config.js",
    "content": "const jestBase = require('../../jest.config.js');\n\nmodule.exports = {\n  ...jestBase,\n};\n"
  },
  {
    "path": "packages/core/package.json",
    "content": "{\n  \"name\": \"@barba/core\",\n  \"version\": \"2.10.3\",\n  \"description\": \"Create badass, fluid and smooth transition between your website's pages\",\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"main\": \"dist/barba.js\",\n  \"umd:main\": \"dist/barba.umd.js\",\n  \"browser\": \"dist/barba.umd.js\",\n  \"unpkg\": \"dist/barba.umd.js\",\n  \"module\": \"dist/barba.mjs\",\n  \"source\": \"src/index.ts\",\n  \"types\": \"dist/core/src/typings\",\n  \"mangle\": {\n    \"regex\": \"^_\"\n  },\n  \"files\": [\n    \"dist\"\n  ],\n  \"keywords\": [\n    \"page\",\n    \"transition\",\n    \"animation\",\n    \"css\",\n    \"router\",\n    \"prefetch\"\n  ],\n  \"homepage\": \"https://github.com/barbajs/barba#readme\",\n  \"bugs\": {\n    \"url\": \"https://github.com/barbajs/barba/issues\"\n  },\n  \"license\": \"MIT\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+ssh://git@github.com/barbajs/barba.git\"\n  },\n  \"scripts\": {\n    \"build\": \"microbundle --name barba --external natives\",\n    \"build:watch\": \"microbundle watch --name barba --external natives\",\n    \"clear\": \"rimraf dist\",\n    \"lint\": \"tslint src/**\",\n    \"precommit\": \"lint-staged\",\n    \"report\": \"source-map-explorer --html ./dist/barba.umd.js > report.html\",\n    \"size\": \"echo '📦 router' && gzip-size ./dist/barba.umd.js\",\n    \"tag:latest\": \"npm dist-tag add @barba/core@$npm_package_version latest\",\n    \"tag:next\": \"npm dist-tag add @barba/core@$npm_package_version next\"\n  },\n  \"dependencies\": {\n    \"is-promise\": \"^4.0.0\",\n    \"path-to-regexp\": \"^6.2.2\"\n  },\n  \"gitHead\": \"33c213bc36a0996f6333185dfc695fcd0d37c9d9\"\n}\n"
  },
  {
    "path": "packages/core/src/core.ts",
    "content": "/**\n * @barba/core\n * <br><br>\n * ## Barba core object\n *\n * Main methods:\n *\n * - `.init()` for initialization with options\n * - `.use()` for plugins\n *\n * @module core\n */\n\n/***/\n\nimport { version } from '../package.json';\n// Definitions\nimport {\n  IBarbaOptions,\n  IBarbaPlugin,\n  IgnoreOption,\n  ISchemaPage,\n  ITransitionData,\n  ITransitionOnce,\n  ITransitionPage,\n  Link,\n  LinkEvent,\n  RequestCustomError,\n  RequestErrorOrResponse,\n  SchemaAttributeValues,\n  Trigger,\n  Wrapper,\n} from './defs';\n// Hooks\nimport { hooks } from './hooks';\n// Modules\nimport { Cache } from './modules/Cache';\nimport { Headers } from './modules/Headers';\nimport { Logger } from './modules/Logger';\nimport { Prevent } from './modules/Prevent';\nimport { Transitions } from './modules/Transitions';\nimport { Views } from './modules/Views';\n// Polyfills\nimport './polyfills';\n// Schemas\nimport { schemaAttribute } from './schemas/attribute';\nimport { schemaPage } from './schemas/page';\n// Utils\nimport { dom, helpers, history, request, url } from './utils';\n\nexport class Core {\n  /**\n   * Version.\n   */\n  public version: string = version;\n  /**\n   * Schemas.\n   */\n  public schemaPage: ISchemaPage = schemaPage;\n  /**\n   * Logger class, allows plugins to create Logger.\n   */\n  public Logger: typeof Logger = Logger;\n  /**\n   * Barba logger.\n   */\n  public logger: Logger = new Logger('@barba/core');\n  /**\n   * Plugins.\n   */\n  public plugins: IBarbaPlugin<any>[] = [];\n  /**\n   * Options\n   */\n  public timeout: number;\n  public cacheIgnore: IgnoreOption;\n  public cacheFirstPage: boolean;\n  public prefetchIgnore: IgnoreOption;\n  public preventRunning: boolean;\n  /**\n   * Hooks\n   */\n  public hooks = hooks;\n  /**\n   * Modules.\n   */\n  // public history: History;\n  public cache: Cache;\n  public headers: Headers;\n  public prevent: Prevent;\n  public transitions: Transitions;\n  public views: Views;\n  /**\n   * Utils.\n   */\n  public dom = dom;\n  public helpers = helpers;\n  public history = history;\n  public request = request;\n  public url = url;\n\n  private _data: ITransitionData;\n  private _requestCustomError: RequestCustomError;\n  private _wrapper: Wrapper;\n  private _linkEvent: LinkEvent;\n\n  /**\n   * ### Init plugin with options.\n   *\n   * See [[IBarbaPlugin]] for more details.\n   */\n  public use<T>(plugin: IBarbaPlugin<T>, options?: T): void {\n    const installedPlugins = this.plugins;\n\n    // Plugin installation\n    if (installedPlugins.indexOf(plugin) > -1) {\n      this.logger.warn(`Plugin [${plugin.name}] already installed.`);\n\n      return;\n    }\n\n    if (typeof plugin.install !== 'function') {\n      this.logger.warn(`Plugin [${plugin.name}] has no \"install\" method.`);\n\n      return;\n    }\n\n    plugin.install(this, options);\n    installedPlugins.push(plugin);\n  }\n\n  /**\n   * ### Init barba with options.\n   *\n   * See [[IBarbaOptions]] for more details.\n   *\n   * Default values are:\n   *\n   * - transitions: `[]`\n   * - views: `[]`\n   * - schema: [[SchemaAttribute]]\n   * - timeout: `2e3`\n   * - cacheIgnore: `false`\n   * - cacheFirstPage: `false`\n   * - prefetchIgnore: `false`\n   * - preventRunning: `false`\n   * - prevent: `null`,\n   * - debug: `false`\n   * - logLevel: `'off'`\n   */\n  public init(\n    /** @ignore */ {\n      transitions = [],\n      views = [],\n      schema = schemaAttribute,\n      requestError,\n      timeout = 2e3,\n      cacheIgnore = false,\n      cacheFirstPage = false,\n      prefetchIgnore = false,\n      /* istanbul ignore next */\n      preventRunning = false,\n      prevent: preventCustom = null,\n      debug = false,\n      logLevel = 'off',\n    }: IBarbaOptions = {}\n  ) {\n    // 0. Set logger level and print version\n    Logger.setLevel(debug === true ? 'debug' : logLevel);\n    this.logger.info(this.version);\n\n    // 1. Manage options\n    Object.keys(schema).forEach(k => {\n      const attr = k as SchemaAttributeValues;\n\n      /* istanbul ignore else */\n      if (schemaAttribute[attr]) {\n        schemaAttribute[attr] = schema[attr];\n      }\n    });\n    this._requestCustomError = requestError;\n    this.timeout = timeout;\n    this.cacheIgnore = cacheIgnore;\n    this.cacheFirstPage = cacheFirstPage;\n    this.prefetchIgnore = prefetchIgnore;\n    this.preventRunning = preventRunning;\n\n    // 2. Get and check wrapper\n    this._wrapper = this.dom.getWrapper();\n    if (!this._wrapper) {\n      throw new Error('[@barba/core] No Barba wrapper found');\n    }\n\n    // 3. Init pages (get \"current\" data)\n    this._resetData();\n\n    const { current } = this.data;\n\n    if (!current.container) {\n      throw new Error('[@barba/core] No Barba container found');\n    }\n\n    // 4. Init other modules\n    this.cache = new Cache(cacheIgnore);\n    this.headers = new Headers();\n    this.prevent = new Prevent(prefetchIgnore);\n    this.transitions = new Transitions(transitions);\n    this.views = new Views(views);\n\n    // Add prevent custom\n    if (preventCustom !== null) {\n      if (typeof preventCustom !== 'function') {\n        throw new Error('[@barba/core] Prevent should be a function');\n      }\n\n      this.prevent.add('preventCustom', preventCustom);\n    }\n\n    // 5. Init history\n    this.history.init(current.url.href, current.namespace);\n\n    // 6. Add to cache\n    if (cacheFirstPage) {\n      this.cache.set(current.url.href, Promise.resolve({\n        html: current.html,\n        url: current.url,\n      }), 'init', 'fulfilled');\n    }\n\n    // 7. Bind context\n    this._onLinkEnter = this._onLinkEnter.bind(this);\n    this._onLinkClick = this._onLinkClick.bind(this);\n    this._onStateChange = this._onStateChange.bind(this);\n    this._bind();\n\n    // 8. Init plugins\n    this.plugins.forEach(plugin => plugin.init());\n\n    // 9. Barba ready\n    // Set next + trigger for once and `beforeEnter`/`afterEnter` view on page load.\n    const onceData = this.data;\n\n    onceData.trigger = 'barba';\n    onceData.next = onceData.current;\n    onceData.current = { ...this.schemaPage };\n    this.hooks.do('ready', onceData);\n\n    // 9. Finally, do once…\n    this.once(onceData);\n\n    // Clean data for first barba transition…\n    this._resetData();\n  }\n\n  public destroy(): void {\n    this._resetData();\n    this._unbind();\n    this.history.clear();\n    this.hooks.clear();\n    this.plugins = [];\n  }\n\n  get data(): ITransitionData {\n    return this._data;\n  }\n\n  get wrapper(): HTMLElement {\n    return this._wrapper;\n  }\n\n  /**\n   * ### Force a page change without Barba transition.\n   */\n  public force(href: string): void {\n    // DEV\n    // Can be used waiting animation cancellation management…\n    window.location.assign(href);\n  }\n\n  /**\n   * ### Go for a Barba transition.\n   *\n   * Manage \"self page\" href:\n   *\n   * - if same url and no self transition, keep default behavior\n   *   - link: reload the page\n   *   - anchor: scroll to\n   * - if same url with self transition, use it\n   * - then start a page transition.\n   */\n  public go(\n    href: string,\n    trigger: Trigger = 'barba',\n    e?: LinkEvent | PopStateEvent\n  ): Promise<void> {\n    this._linkEvent = null;\n\n    // If animation running, force reload\n    if (this.transitions.isRunning) {\n      this.force(href);\n\n      return;\n    }\n\n    let self = false;\n\n    // Check prevent sameURL against current history\n    // + state check\n    // + update trigger with direction\n    if (trigger === 'popstate') {\n      self =\n        this.history.current &&\n        this.url.getPath(this.history.current.url) === this.url.getPath(href) &&\n        this.url.getQuery(this.history.current.url, true) === this.url.getQuery(href, true);\n    } else {\n      self = this.prevent.run('sameUrl', null, null, href);\n    }\n\n    if (self && !this.transitions.hasSelf) {\n      return;\n    }\n\n    trigger = this.history.change(this.cache.has(href) ? this.cache.get(href).target : href, trigger, e);\n\n    if (e) {\n      e.stopPropagation();\n      e.preventDefault();\n    }\n\n    return this.page(href, trigger, e ?? undefined, self);\n  }\n\n  /**\n   * ### Start an \"once\" transition.\n   *\n   * If some registered \"once\" transition,\n   * get the \"resolved\" transition from the store and start it.\n   */\n  public async once(readyData: ITransitionData): Promise<void> {\n    await this.hooks.do('beforeEnter', readyData);\n\n    // Check if once transition\n    if (this.transitions.hasOnce) {\n      const transition = this.transitions.get(readyData, {\n        once: true,\n      }) as ITransitionOnce;\n\n      await this.transitions.doOnce({ transition, data: readyData });\n    }\n\n    await this.hooks.do('afterEnter', readyData);\n  }\n\n  /**\n   * ### Start a \"page\" transition.\n   *\n   * 1. If no running transition, updates data with full URL properties and trigger.\n   * 2. Get page from cache or init request.\n   * 3. Wait if some transitions need \"next\" data (`sync: true`, `to: …`).\n   * 4. Manage the history, depending on trigger.\n   * 5. Get \"data\" and trigger \"go\" hook.\n   * 6. Get the \"resolved\" transition from the store and start it.\n   * 7. Update title and reset data (current, next = undefined).\n   *\n   * > If \"self\", use the \"self\" transition\n   */\n  public async page(\n    href: string,\n    trigger: Trigger,\n    event: LinkEvent | PopStateEvent,\n    self: boolean\n  ): Promise<void> {\n    this.data.next.url = {\n      href,\n      ...this.url.parse(href),\n    };\n    this.data.trigger = trigger;\n    this.data.event = event;\n\n    let page;\n\n    if (this.cache.has(href)) {\n      page = this.cache.update(href, { action: 'click' }).request;\n    } else {\n      const pageRequest = this.request(\n        href,\n        this.timeout,\n        this.onRequestError.bind(this, trigger),\n        this.cache,\n        this.headers\n      );\n\n      // manage 301 server response: replace history\n      pageRequest.then(response => {\n        /* istanbul ignore next: bypass jest since xhr-mock doesn't support custom xhr.responseURL */\n        if (response.url.href !== href) {\n          this.history.add(response.url.href, trigger, 'replace');\n        }\n      });\n\n      page = this.cache.set(href, pageRequest, 'click', 'pending').request;\n    }\n\n    // Need to wait before getting the right transition\n    if (this.transitions.shouldWait) {\n      await helpers.update(page, this.data);\n    }\n\n    const data = this.data;\n\n    // Hook: between trigger and transition\n    // Can be used to resolve \"route\"…\n    await this.hooks.do('page', data);\n\n    try {\n      const transition = this.transitions.get(data, {\n        once: false,\n        self,\n      }) as ITransitionPage;\n\n      await this.transitions.doPage({\n        data,\n        page,\n        transition,\n        wrapper: this._wrapper,\n      });\n\n      this._resetData();\n    } catch (error) {\n      // Something went wrong (rejected promise, error, 404, 505, other…)\n      // TODO: manage / use cases for cancellation\n      // this.logger.debug('Transition cancelled');\n\n      // If transition error and no debug mode, force reload page.\n      /* istanbul ignore else */\n      if (Logger.getLevel() === 0) {\n        this.force(data.next.url.href);\n      }\n    }\n  }\n\n  /**\n   * When a request error occurs.\n   *\n   * Allow the user to manage request error. (E.g: 404)\n   */\n  public onRequestError(trigger: Trigger, ...args: any): boolean {\n    // Cancel transition status\n    this.transitions.isRunning = false;\n\n    const [href, response]: [string, RequestErrorOrResponse] = args;\n    const action = this.cache.getAction(href);\n    this.cache.delete(href);\n\n    // Custom requestError returning false will return here.\n    if (\n      this._requestCustomError &&\n      this._requestCustomError(trigger, action, href, response) === false\n    ) {\n      return false;\n    }\n\n    // Force page change\n    if (action === 'click') {\n      this.force(href);\n    }\n    return false;\n  }\n\n  /**\n   * Programmatically prefetch\n   */\n  public prefetch(href: string) {\n\n    // only prefetch absolute href\n    href = this.url.getAbsoluteHref(href);\n\n    // Already in cache\n    /* istanbul ignore next */\n    if (this.cache.has(href)) {\n      return;\n    }\n\n    this.cache.set(\n      href,\n      this.request(\n        href,\n        this.timeout,\n        this.onRequestError.bind(this, 'barba'),\n        this.cache,\n        this.headers\n      ).catch((error: RequestErrorOrResponse) => {\n        this.logger.error(error);\n      }),\n      'prefetch',\n      'pending'\n    );\n  }\n\n  /**\n   * Bind event listeners.\n   */\n  private _bind(): void {\n    /* istanbul ignore else */\n    if (this.prefetchIgnore !== true) {\n      document.addEventListener('mouseover', this._onLinkEnter);\n      document.addEventListener('touchstart', this._onLinkEnter);\n    }\n    document.addEventListener('click', this._onLinkClick);\n    window.addEventListener('popstate', this._onStateChange);\n  }\n\n  /**\n   * Bind event listeners.\n   */\n  private _unbind(): void {\n    /* istanbul ignore else */\n    if (this.prefetchIgnore !== true) {\n      document.removeEventListener('mouseover', this._onLinkEnter);\n      document.removeEventListener('touchstart', this._onLinkEnter);\n    }\n    document.removeEventListener('click', this._onLinkClick);\n    window.removeEventListener('popstate', this._onStateChange);\n  }\n\n  /**\n   * When a element is entered.\n   *\n   * Get valid link element.\n   * Cache URL if needed.\n   */\n  private _onLinkEnter(e: LinkEvent): void {\n    const link = this._getLinkElement(e);\n\n    if (!link) {\n      return;\n    }\n\n    const href = this.url.getAbsoluteHref(this.dom.getHref(link));\n\n    if (this.prevent.checkHref(href)) {\n      return;\n    }\n\n    // Already in cache\n    if (this.cache.has(href)) {\n      return;\n    }\n\n    this.cache.set(\n      href,\n      this.request(\n        href,\n        this.timeout,\n        this.onRequestError.bind(this, link),\n        this.cache,\n        this.headers\n      ).catch((error: RequestErrorOrResponse) => {\n        this.logger.error(error);\n      }),\n      'enter',\n      'pending'\n    );\n  }\n\n  /**\n   * When an element is clicked.\n   *\n   * Get valid link element.\n   * Prevent same URL.\n   * Go for a Barba transition.\n   */\n  private _onLinkClick(e: LinkEvent): void {\n\n    // This use `prevent.checkLink` under the hood to get eligible link.\n    const link = this._getLinkElement(e);\n\n    if (!link) {\n      return;\n    }\n\n    if (this.transitions.isRunning && this.preventRunning) {\n      e.preventDefault();\n      e.stopPropagation();\n\n      return;\n    }\n\n    this._linkEvent = e;\n\n    this.go(this.dom.getHref(link), link, e);\n  }\n\n  /**\n   * When History state changes.\n   *\n   * Get \"href\" from URL\n   * Go for a Barba transition.\n   */\n  private _onStateChange(e: PopStateEvent): void {\n    this.go(this.url.getHref(), 'popstate', e);\n  }\n\n  /**\n   * Get a valid link ancestor.\n   *\n   * Check for a \"href\" attribute.\n   * Then check if eligible for Barba.\n   */\n  private _getLinkElement(e: LinkEvent): Link {\n    let el = e.target as Link;\n\n    while (el && !this.dom.getHref(el)) {\n      el = (el as HTMLElement).parentNode as Link;\n    }\n\n    // Check prevent\n    if (!el || this.prevent.checkLink(el, e, this.dom.getHref(el))) {\n      return;\n    }\n\n    return el;\n  }\n\n  /**\n   * Reset pages data.\n   *\n   * Set \"current\" and unset \"next\".\n   */\n  private _resetData() {\n    const href = this.url.getHref();\n    const current = {\n      container: this.dom.getContainer(),\n      html: this.dom.getHtml(),\n      namespace: this.dom.getNamespace(),\n      url: {\n        href,\n        ...this.url.parse(href),\n      },\n    };\n\n    this._data = {\n      current,\n      event: undefined,\n      next: { ...this.schemaPage },\n      trigger: undefined,\n    };\n\n    this.hooks.do('reset', this.data);\n  }\n}\n\nconst core = new Core();\n\nexport default core;\n"
  },
  {
    "path": "packages/core/src/defs/barba.ts",
    "content": "/**\n * @module typings/core\n */\n\n// Core\nimport { Core } from '../core';\n// Modules\nimport { LogLevels } from '../modules/Logger';\n// Definitions\nimport {\n  IgnoreOption,\n  ISchemaAttribute,\n  ITransitionPage,\n  IView,\n  PreventCheck,\n  RequestCustomError,\n} from './index';\n\nexport interface IBarbaOptions {\n  /** Array of transitions. */\n  transitions?: ITransitionPage[];\n  /** Array of views. */\n  views?: IView[];\n  /** Request timeout. */\n  timeout?: number;\n  /** Custom request error. */\n  requestError?: RequestCustomError | undefined;\n  /** Disable cache or ignore some routes. */\n  cacheIgnore?: IgnoreOption;\n  /** Disable cache on the first rendered page. */\n  cacheFirstPage?: boolean;\n  /** Disable prefetch or ignore routes. */\n  prefetchIgnore?: IgnoreOption;\n  /** Custom prevent check. */\n  prevent?: PreventCheck | null;\n  /** Prevent click when transition is running. */\n  preventRunning?: boolean;\n  /** Custom [data-attribute]. */\n  schema?: ISchemaAttribute;\n  /** Enable debug mode. */\n  debug?: boolean;\n  /** Log level. */\n  logLevel?: keyof typeof LogLevels;\n}\n\nexport interface IBarbaPlugin<T> {\n  /** Plugin version */\n  version: string;\n  /** Plugin name */\n  name: string;\n  /** Install method */\n  install(barba: Core, options?: T): void;\n  /** Init method */\n  init(): void;\n}\n"
  },
  {
    "path": "packages/core/src/defs/cache.ts",
    "content": "/**\n * @module typings/core\n */\n\nimport { IResponse } from './index';\n\nexport interface ICacheData {\n  action?: CacheAction;\n  request?: CacheRequest;\n  status?: CacheStatus;\n  target?: CacheTarget;\n}\n\nexport type CacheRequest = Promise<IResponse | void>;\nexport type CacheAction = 'init' | 'enter' | 'click' | 'prefetch';\nexport type CacheStatus = 'pending' | 'fulfilled' | 'rejected';\nexport type CacheTarget = string;\n"
  },
  {
    "path": "packages/core/src/defs/dom.ts",
    "content": "/**\n * @module typings/core\n */\n\nexport type Link = HTMLAnchorElement | SVGAElement;\nexport type LinkEvent = MouseEvent | TouchEvent;\nexport type Scope = HTMLElement | HTMLDocument;\nexport type Trigger = Link | 'barba' | 'popstate' | 'back' | 'forward';\nexport type Wrapper = HTMLElement | null;\n\nexport interface IDomSibling {\n  before?: Element;\n  after?: Element;\n  parent?: Element;\n}\n"
  },
  {
    "path": "packages/core/src/defs/global.ts",
    "content": "/**\n * @module typings/core\n */\n\nexport interface IGenericObject {\n  [key: string]: string;\n}\n"
  },
  {
    "path": "packages/core/src/defs/headers.ts",
    "content": "/**\n * @module typings/core\n */\n\nexport type HeaderList = Map<string, string>;\n\nexport interface IHeaderData {\n  name?: string;\n  value?: string;\n}\n"
  },
  {
    "path": "packages/core/src/defs/history.ts",
    "content": "/**\n * @module typings/history\n */\n\nexport type HistoryAction = 'push' | 'replace';\n"
  },
  {
    "path": "packages/core/src/defs/hooks.ts",
    "content": "/**\n * @module typings/core\n */\nimport { ITransitionData, ITransitionPage, IViewData } from './index';\n\nexport type HooksBarba =\n  | 'ready'\n  | 'page'\n  | 'reset'\n  | 'currentAdded'\n  | 'currentRemoved'\n  | 'nextAdded'\n  | 'nextRemoved';\n\nexport type HooksOnce = 'beforeOnce' | 'once' | 'afterOnce';\n\nexport type HooksPage =\n  | 'before'\n  | 'beforeLeave'\n  | 'leave'\n  | 'afterLeave'\n  | 'beforeEnter'\n  | 'enter'\n  | 'afterEnter'\n  | 'after';\n\nexport type HooksBefore = 'beforeOnce' | 'beforeLeave' | 'beforeEnter';\nexport type HooksAfter = 'afterOnce' | 'afterLeave' | 'afterEnter';\n\nexport type HooksTransition = HooksOnce | HooksPage;\nexport type HooksView = HooksBefore | HooksAfter;\nexport type HooksAll = HooksBarba | HooksTransition;\n\n// Allow optional \"dynamically created\" hooks\nexport type HooksTransitionMap = { [key in HooksTransition]?: any };\n\nexport type HookFunction = (\n  data?: ITransitionData | IViewData,\n  t?: ITransitionPage\n) => Promise<void> | void;\n\nexport class HookMethods {\n  public before: (fn: HookFunction, ctx?: any) => void;\n  public beforeLeave: (fn: HookFunction, ctx?: any) => void;\n  public leave: (fn: HookFunction, ctx?: any) => void;\n  public afterLeave: (fn: HookFunction, ctx?: any) => void;\n  public beforeEnter: (fn: HookFunction, ctx?: any) => void;\n  public enter: (fn: HookFunction, ctx?: any) => void;\n  public afterEnter: (fn: HookFunction, ctx?: any) => void;\n  public after: (fn: HookFunction, ctx?: any) => void;\n}\n"
  },
  {
    "path": "packages/core/src/defs/ignore.ts",
    "content": "/**\n * @module typings/core\n */\n\nexport type IgnoreOption = boolean | string | string[];\n"
  },
  {
    "path": "packages/core/src/defs/index.ts",
    "content": "export * from './barba';\n// export * from './core';\nexport * from './headers';\nexport * from './cache';\nexport * from './dom';\nexport * from './global';\nexport * from './ignore';\nexport * from './history';\nexport * from './hooks';\nexport * from './prevent';\nexport * from './request';\nexport * from './rules';\nexport * from './schemas';\nexport * from './transition';\nexport * from './url';\nexport * from './view';\n"
  },
  {
    "path": "packages/core/src/defs/is-promise.d.ts",
    "content": "declare module 'is-promise';\n"
  },
  {
    "path": "packages/core/src/defs/prevent.ts",
    "content": "/**\n * @module typings/core\n */\n\n// Definitions\nimport { Link } from './index';\n\n/**\n * Available data for all prevent checks.\n *\n * - `el`: the clicked link\n * - `event`: the associated event\n * - `href`: the href to use for fetching\n */\nexport interface IPreventCheckData {\n  el: Link;\n  event: Event;\n  href: string;\n}\n\n/**\n * Prevent check.\n *\n * - Receives check data.\n * - If it returns `true`, Barba will prevent the action.\n */\nexport type PreventCheck = (data: IPreventCheckData) => boolean;\n"
  },
  {
    "path": "packages/core/src/defs/request.ts",
    "content": "/**\n * @module typings/core\n */\n\n// Definitions\nimport { IUrlFull, Trigger } from './index';\n\nexport interface IResponse {\n  html: string;\n  url: IUrlFull;\n}\n\nexport type RequestError = (\n  url: string,\n  errorOrResponse: RequestErrorOrResponse\n) => boolean;\n\n// export type RequestErrorBinded = (\n//   trigger: Trigger,\n//   action: string,\n//   ...args: any\n// ) => boolean;\n\nexport type RequestCustomError = (\n  trigger: Trigger,\n  action: string,\n  url: string,\n  response: RequestErrorOrResponse\n) => boolean;\n\nexport interface IXhrResponse {\n  status: number;\n  statusText: string;\n}\n\nexport type RequestErrorOrResponse = Error | IXhrResponse;\n"
  },
  {
    "path": "packages/core/src/defs/rules.ts",
    "content": "/**\n * @module typings/core\n */\n\nexport type RuleName =\n  | IRules['strings']\n  | IRules['object']\n  | IRules['function'];\n\nexport type RuleType = 'strings' | 'object' | 'function';\n\nexport interface IRule {\n  name: RuleName;\n  type: RuleType;\n}\n\nexport interface IRules {\n  strings: 'namespace';\n  object: 'route';\n  function: 'custom';\n}\n"
  },
  {
    "path": "packages/core/src/defs/schemas.ts",
    "content": "/**\n * @module typings/core\n */\n\ninterface IRouteResolved {\n  name: string;\n  params: any;\n}\nimport { IUrlFull } from './index';\n\nexport type SchemaAttributeValues =\n  | 'prefix'\n  | 'wrapper'\n  | 'container'\n  | 'prevent'\n  | 'history'\n  | 'namespace';\n\n/**\n * ### Define HTML `data-attribute` used by Barba.\n *\n * @param prefix data-__prefix__\n * @param wrapper data-prefix=\"__wrapper__\"\n * @param container data-prefix=\"__container__\"\n * @param prevent data-prefix-__prevent__\n * @param history data-prefix-__history__\n * @param namespace data-prefix-__namespace__\n */\nexport interface ISchemaAttribute {\n  prefix?: string;\n  wrapper?: string;\n  container?: string;\n  prevent?: string;\n  history?: string;\n  namespace?: string;\n}\n\n/**\n * ### Define \"page\" data structure.\n *\n * Used by `data.current` and `data.next`.<br>\n * Set to `undefined` until values are available.\n *\n * @param container Barba container element\n * @param html Full stringified HTML\n * @param namespace Namespace\n * @param url URL\n * @param route Route name (with `@barba/router`)\n */\n\nexport interface ISchemaPage {\n  container: HTMLElement;\n  html: string;\n  namespace: string;\n  url: IUrlFull;\n  route?: IRouteResolved | null;\n}\n"
  },
  {
    "path": "packages/core/src/defs/transition.ts",
    "content": "/**\n * @module typings/core\n */\n\n// Definitions\nimport { LinkEvent } from '../defs';\nimport { ISchemaPage, Trigger } from './index';\n\n// Data\nexport interface ITransitionData {\n  current: ISchemaPage;\n  next: ISchemaPage;\n  trigger: Trigger;\n  event?: LinkEvent | PopStateEvent;\n}\n\n// Filter\nexport interface ITransitionFilters {\n  once?: boolean;\n  self?: boolean;\n}\n\n// Rules\nexport interface ITransitionRules {\n  namespace?: string | string[];\n  route?: string | string[];\n  custom?(data: ITransitionData): boolean;\n}\n\n// Transitions\nexport interface ITransitionPage extends ITransitionRules {\n  name?: string;\n  from?: ITransitionRules;\n  to?: ITransitionRules;\n  sync?: boolean;\n  priority?: number;\n  async?: () => (data?: any) => void;\n  beforeOnce?(data: ITransitionData): void;\n  once?(data: ITransitionData): Promise<void> | void;\n  afterOnce?(data: ITransitionData): void;\n  before?(data: ITransitionData): void;\n  beforeLeave?(data: ITransitionData): void;\n  leave?(data: ITransitionData): Promise<any> | void;\n  afterLeave?(data: ITransitionData): void;\n  beforeEnter?(data: ITransitionData): void;\n  enter?(data: ITransitionData): Promise<void> | void;\n  afterEnter?(data: ITransitionData): void;\n  after?(data: ITransitionData): void;\n}\n\nexport interface ITransitionOnce extends ITransitionPage {\n  once?(data: ITransitionData): Promise<void>;\n}\n"
  },
  {
    "path": "packages/core/src/defs/url.ts",
    "content": "/**\n * @module typings/core\n */\n\n// Definitions\nimport { IGenericObject } from './index';\n\nexport interface IUrlBase {\n  path: string | undefined;\n  hash: string | undefined;\n  query: IGenericObject;\n  port: number;\n}\n\nexport interface IUrlFull extends IUrlBase {\n  href: string | undefined;\n}\n"
  },
  {
    "path": "packages/core/src/defs/view.ts",
    "content": "/**\n * @module typings/core\n */\n\n// Definitions\nimport { ISchemaPage, Trigger } from './index';\n\nexport interface IViewData {\n  current: ISchemaPage;\n  next: ISchemaPage;\n  trigger: Trigger;\n}\n\nexport interface IView {\n  namespace: string;\n  name?: string;\n  beforeOnce?(data: IViewData): void;\n  afterOnce?(data: IViewData): void;\n  beforeLeave?(data: IViewData): void;\n  afterLeave?(data: IViewData): void;\n  beforeEnter?(data: IViewData): void;\n  afterEnter?(data: IViewData): void;\n}\n"
  },
  {
    "path": "packages/core/src/hooks.ts",
    "content": "/**\n * @barba/core/modules/hooks\n * <br><br>\n * ## Hooks manager.\n *\n * - Register and trigger hooks\n *\n * Hooks can be easily registered:\n *\n * ```js\n * hooks.leave(callback, context);\n * ```\n *\n * @module core/modules/hooks\n * @preferred\n */\n\n/***/\n\n// Definitions\nimport { HookFunction, HookMethods, HooksAll } from './defs';\n// Modules\nimport { Logger } from './modules/Logger';\n// Utils\nimport { runAsync } from './utils';\n// Types\ninterface IHookInfos {\n  ctx: any;\n  fn: HookFunction;\n}\n\nexport class Hooks extends HookMethods {\n  /**\n   * Allow the use of `hooks[name](cb, ctx)`.\n   */\n  [key: string]: any;\n  // [key in HooksAll]?: any;\n  public logger: Logger = new Logger('@barba/core');\n  /**\n   * All available hooks.\n   *\n   * See [[HooksAll]]\n   */\n  // TODO: get hooks from defs (DRY)?\n  public all: HooksAll[] = [\n    'ready',\n    'page',\n    'reset',\n    'currentAdded',\n    'currentRemoved',\n    'nextAdded',\n    'nextRemoved',\n    'beforeOnce',\n    'once',\n    'afterOnce',\n    'before',\n    'beforeLeave',\n    'leave',\n    'afterLeave',\n    'beforeEnter',\n    'enter',\n    'afterEnter',\n    'after',\n  ];\n  /**\n   * Registered hooks.\n   *\n   * - Unique hook name\n   * - Associated data set(s) (callback + context)\n   */\n  public registered: Map<HooksAll, Set<IHookInfos>> = new Map();\n\n  constructor() {\n    super();\n    this.init();\n  }\n\n  public init() {\n    this.registered.clear();\n    this.all.forEach(hook => {\n      if (!this[hook]) {\n        this[hook] = (fn: HookFunction, ctx?: any) => {\n          if (!this.registered.has(hook)) {\n            this.registered.set(hook, new Set());\n          }\n          const set = this.registered.get(hook);\n\n          set.add({\n            ctx: ctx || {},\n            fn,\n          });\n        };\n      }\n    });\n  }\n\n  /**\n   * Do hook.\n   *\n   * Trigger registered hooks.\n   */\n  public do(name: HooksAll, ...args: any): Promise<any> {\n    if (this.registered.has(name)) {\n      // Let's start a chain of promises\n      let chain = Promise.resolve();\n\n      this.registered.get(name).forEach(hook => {\n        // Chain async hooks promisified\n        chain = chain.then(() => runAsync(hook.fn, hook.ctx)(...args));\n      });\n\n      return chain.catch(error => {\n        this.logger.debug(`Hook error [${name}]`);\n        this.logger.error(error);\n      });\n    }\n\n    return Promise.resolve();\n  }\n\n  public clear(): void {\n    this.all.forEach(hook => {\n      delete this[hook];\n    });\n\n    this.init();\n  }\n\n  /**\n   * Help, print available and registered hooks.\n   */\n  public help(): void {\n    this.logger.info(`Available hooks: ${this.all.join(',')}`);\n    const registered: string[] = [];\n    this.registered.forEach((_value: any, key: string) => registered.push(key));\n    this.logger.info(`Registered hooks: ${registered.join(',')}`);\n  }\n}\n\nconst hooks = new Hooks();\n\nexport { hooks };\n"
  },
  {
    "path": "packages/core/src/index.ts",
    "content": "import * as t from './typings';\nexport { default } from './core';\n"
  },
  {
    "path": "packages/core/src/modules/Cache.ts",
    "content": "/**\n * @barba/core/modules/cache\n * <br><br>\n * ## Cache for storing URL / HTML.\n *\n * @module core/modules/cache\n * @preferred\n */\n\n/***/\n\n// Definitions\nimport { CacheAction, CacheRequest, CacheStatus, CacheTarget, ICacheData, IgnoreOption } from '../defs';\n// Modules\nimport { Ignore } from './Ignore';\n\nexport class Cache extends Ignore {\n  private _state: Map<string, ICacheData> = new Map();\n\n  constructor(ignore: IgnoreOption) {\n    super(ignore);\n  }\n\n  /**\n   * Set value to cache\n   */\n  public set(\n    href: string,\n    request: CacheRequest,\n    action: CacheAction,\n    status: CacheStatus,\n    target?: CacheTarget,\n  ): ICacheData {\n    this._state.set(href, {\n      action,\n      request,\n      status,\n      target: target ?? href,\n    });\n\n    return {\n      action,\n      request,\n      status,\n      target,\n    };\n  }\n\n  /**\n   * Get data from cache\n   */\n  public get(href: string): ICacheData {\n    return this._state.get(href);\n  }\n\n  /**\n   * Get request from cache\n   */\n  public getRequest(href: string): CacheRequest {\n    return this._state.get(href).request;\n  }\n\n  /**\n   * Get action from cache\n   */\n  public getAction(href: string): CacheAction {\n    return this._state.get(href).action;\n  }\n\n  /**\n   * Get status from cache\n   */\n  public getStatus(href: string): CacheStatus {\n    return this._state.get(href).status;\n  }\n\n  /**\n   * Get target from cache\n   */\n  public getTarget(href: string): CacheTarget {\n    return this._state.get(href).target;\n  }\n\n  /**\n   * Check if value exists into cache\n   */\n  public has(href: string): boolean {\n    /* istanbul ignore else */\n    if (this.checkHref(href)) {\n      return false;\n    }\n    return this._state.has(href);\n  }\n\n  /**\n   * Delete value from cache\n   */\n  public delete(href: string): boolean {\n    return this._state.delete(href);\n  }\n\n  /**\n   * Update cache value\n   */\n  public update(href: string, data: ICacheData): ICacheData {\n    const state = {\n      ...this._state.get(href),\n      ...data,\n    };\n    this._state.set(href, state);\n\n    return state;\n  }\n}\n"
  },
  {
    "path": "packages/core/src/modules/Error.ts",
    "content": "// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error\nexport class BarbaError extends Error {\n  /* istanbul ignore next */\n  constructor(\n    public error: Error,\n    public label = 'Barba error',\n    ...params: any[]\n  ) {\n    // Pass remaining arguments (including vendor specific ones) to parent constructor\n    super(...params);\n\n    // Maintains proper stack trace for where our error was thrown (only available on V8)\n    /* istanbul ignore else */\n    if (Error.captureStackTrace) {\n      Error.captureStackTrace(this, BarbaError);\n    }\n\n    this.name = 'BarbaError';\n  }\n}\n"
  },
  {
    "path": "packages/core/src/modules/Headers.ts",
    "content": "/**\n * @barba/core/modules/headers\n * <br><br>\n * ## Manage request Headers.\n *\n * @module core/modules/headers\n * @preferred\n */\n\n/***/\n\n// Definitions\nimport { HeaderList, IHeaderData } from '../defs';\n\nexport class Headers {\n  private _list: HeaderList = new Map();\n\n  /**\n   * Set a new header\n   */\n  public set(name: string, value: string): IHeaderData {\n    this._list.set(name, value);\n\n    return {\n      name: value\n    };\n  }\n\n  /**\n   * Get a specific header\n   */\n  public get(name: string): string {\n    return this._list.get(name);\n  }\n\n  /**\n   * Get all headers\n   */\n  public all(): HeaderList {\n    return this._list;\n  }\n\n  /**\n   * Check if header exists\n   */\n  public has(name: string): boolean {\n    return this._list.has(name);\n  }\n\n  /**\n   * Delete a header\n   */\n  public delete(name: string): boolean {\n    return this._list.delete(name);\n  }\n\n  /**\n   * Clear all headers\n   */\n  public clear(): void {\n    return this._list.clear();\n  }\n}\n"
  },
  {
    "path": "packages/core/src/modules/Ignore.ts",
    "content": "/**\n * @barba/core/modules/ignore\n * <br><br>\n * ## Manage ignore options.\n *\n * - cache\n * - prefetch\n *\n * @module core/modules/ignore\n * @preferred\n */\n\n/***/\n\n// Definitions\nimport { IgnoreOption } from '../defs';\n// Utils\nimport { pathToRegexp } from '../utils/helpers';\nimport { parse } from '../utils/url';\n\nexport class Ignore {\n  private _ignoreAll: boolean;\n  private _ignoreRegexes: RegExp[] = [];\n\n  constructor(ignore: IgnoreOption) {\n    if (typeof ignore === 'boolean') {\n      this._ignoreAll = ignore;\n    } else {\n      const paths = Array.isArray(ignore) ? ignore : [ignore];\n\n      this._ignoreRegexes = paths.map(p => pathToRegexp(p));\n    }\n  }\n\n  public checkHref(href: string): boolean {\n    if (typeof this._ignoreAll === 'boolean') {\n      return this._ignoreAll;\n    }\n\n    const { path } = parse(href);\n\n    return this._ignoreRegexes.some(regex => regex.exec(path) !== null);\n  }\n}\n"
  },
  {
    "path": "packages/core/src/modules/Logger.ts",
    "content": "/**\n * @barba/core/modules/Logger\n * <br><br>\n * ## Logger.\n *\n * - Display informations via the console\n *\n * @module core/modules/Logger\n * @preferred\n */\n\n/***/\n\n/**\n * Log levels, all lower level messages are printed\n *\n * 0. mute\n * 1. error = `console.error()`\n * 2. warning= `console.warn()`\n * 3. info = `console.info()`\n * 4. debug = `console.log()`\n */\nexport enum LogLevels {\n  off = 0,\n  error = 1,\n  warning = 2,\n  info = 3,\n  debug = 4,\n}\n\n/**\n * Global log level\n */\nlet _level: number = LogLevels.off;\n\nexport class Logger {\n  /**\n   * Get global log level.\n   */\n  public static getLevel(): number {\n    return _level;\n  }\n\n  /**\n   * Set global log level.\n   */\n  public static setLevel(name: keyof typeof LogLevels): number {\n    _level = LogLevels[name];\n\n    return _level;\n  }\n\n  /**\n   * Log \"prefix\".\n   */\n  private _source: string;\n\n  /**\n   * Creates an instance of Logger.\n   */\n  constructor(source: string) {\n    this._source = source;\n  }\n\n  /**\n   * Permanent, unremovable log.\n   */\n  // public print(...objects: any[]): void {\n  //   this._log(console.info, LogLevels.off, objects);\n  // }\n\n  /**\n   * Error log.\n   */\n  public error(...objects: any[]): void {\n    this._log(console.error, LogLevels.error, objects);\n  }\n\n  /**\n   * Warn log.\n   */\n  public warn(...objects: any[]): void {\n    this._log(console.warn, LogLevels.warning, objects);\n  }\n\n  /**\n   * Info log.\n   */\n  public info(...objects: any[]): void {\n    this._log(console.info, LogLevels.info, objects);\n  }\n\n  /**\n   * Debug log.\n   */\n  public debug(...objects: any[]): void {\n    this._log(console.log, LogLevels.debug, objects);\n  }\n\n  /**\n   * Internal logger.\n   */\n  private _log(fn: () => void, level: number, objects: any[]): void {\n    if (level <= Logger.getLevel()) {\n      fn.apply(console, ([`[${this._source}] `].concat(objects) as unknown) as [\n\n      ]);\n    }\n  }\n}\n"
  },
  {
    "path": "packages/core/src/modules/Prevent.ts",
    "content": "/**\n * @barba/core/modules/prevent\n * <br><br>\n * ## Prevent checks.\n *\n * - Gathers all the tests that allow Barba to work and play transitions\n *\n * @module core/modules/prevent\n * @preferred\n */\n\n/***/\n\n// Definitions\nimport { IgnoreOption, Link, PreventCheck } from '../defs';\n// Schemas\nimport { schemaAttribute } from '../schemas/attribute';\n// Utils\nimport { url } from '../utils';\n// Modules\nimport { Ignore } from './Ignore';\n\n/**\n * Make sure the browser supports `history.pushState`.\n */\nconst pushState: PreventCheck = () => !window.history.pushState;\n\n/**\n * Make sure there is an `el` and `href`.\n */\nconst exists: PreventCheck = ({ el, href }) => !el || !href;\n\n/**\n * If the user is pressing ctrl + click, the browser will open a new tab.\n */\nconst newTab: PreventCheck = ({ event }) =>\n  (event as KeyboardEvent).which > 1 ||\n  (event as KeyboardEvent).metaKey ||\n  (event as KeyboardEvent).ctrlKey ||\n  (event as KeyboardEvent).shiftKey ||\n  (event as KeyboardEvent).altKey;\n\n/**\n * If the link has `_blank` target.\n */\nconst blank: PreventCheck = ({ el }) =>\n  el.hasAttribute('target') && (el as Link).target === '_blank';\n\n/**\n * If the domain is the same (in order to avoid pushState cross origin security problem).\n * Note: SVGAElement do not have `protocol` neither `hostname` properties.\n */\nconst corsDomain: PreventCheck = ({ el }) =>\n  ((el as HTMLAnchorElement).protocol !== undefined &&\n    window.location.protocol !== (el as HTMLAnchorElement).protocol) ||\n  ((el as HTMLAnchorElement).hostname !== undefined &&\n    window.location.hostname !== (el as HTMLAnchorElement).hostname);\n\n/**\n * If the port is the same.\n * Note: SVGAElement do not have `port` property.\n */\nconst corsPort: PreventCheck = ({ el }) =>\n  (el as HTMLAnchorElement).port !== undefined &&\n  url.getPort() !== url.getPort((el as HTMLAnchorElement).href);\n\n/**\n * If the link has download attribute.\n */\nconst download: PreventCheck = ({ el }) =>\n  el.getAttribute && typeof el.getAttribute('download') === 'string';\n\n/**\n * If the links contains [data-barba-prevent] or [data-barba-prevent=\"self\"].\n */\nconst preventSelf: PreventCheck = ({ el }) =>\n  el.hasAttribute(`${schemaAttribute.prefix}-${schemaAttribute.prevent}`);\n\n/**\n * If some link ancestor contains [data-barba-prevent=\"all\"].\n */\nconst preventAll: PreventCheck = ({ el }) =>\n  Boolean(\n    el.closest(`[${schemaAttribute.prefix}-${schemaAttribute.prevent}=\"all\"]`)\n  );\n\n/**\n * If the link is the current URL.\n *\n * > Not in the test suite.\n */\nconst sameUrl: PreventCheck = ({ href }) =>\n  url.clean(href) === url.clean() && url.getPort(href) === url.getPort();\n\nexport class Prevent extends Ignore {\n  public suite: string[] = [];\n  public tests: Map<string, PreventCheck> = new Map();\n\n  constructor(ignore: IgnoreOption) {\n    super(ignore);\n    this.init();\n  }\n\n  public init(): void {\n    // Add defaults\n    this.add('pushState', pushState);\n    this.add('exists', exists);\n    this.add('newTab', newTab);\n    this.add('blank', blank);\n    this.add('corsDomain', corsDomain);\n    this.add('corsPort', corsPort);\n    this.add('download', download);\n    this.add('preventSelf', preventSelf);\n    this.add('preventAll', preventAll);\n\n    // Outside of the test suite\n    this.add('sameUrl', sameUrl, false);\n  }\n\n  public add(name: string, check: PreventCheck, suite: boolean = true): void {\n    this.tests.set(name, check);\n    suite && this.suite.push(name);\n  }\n\n  /**\n   * Run individual test\n   */\n  public run(name: string, el: Link, event: Event, href: string): boolean {\n    return this.tests.get(name)({\n      el,\n      event,\n      href,\n    });\n  }\n\n  /**\n   * Run test suite\n   */\n  public checkLink(el: Link, event: Event, href: string): boolean {\n    return this.suite.some(name => this.run(name, el, event, href));\n  }\n}\n"
  },
  {
    "path": "packages/core/src/modules/Store.ts",
    "content": "/**\n * @barba/core/modules/store\n * <br><br>\n * ## Transitions store.\n *\n * - Resolve transition\n * - Manage rules\n *\n * @module core/modules/store\n * @preferred\n */\n\n/***/\n\n// Definitions\nimport {\n  IRule,\n  IRules,\n  ITransitionData,\n  ITransitionFilters,\n  ITransitionOnce,\n  ITransitionPage,\n  RuleName,\n} from '../defs';\n\n// Modules\nimport { Logger } from './Logger';\n\nexport class Store {\n  public logger: Logger = new Logger('@barba/core');\n  /**\n   * All registered transitions.\n   */\n  public all: ITransitionPage[] = [];\n  /**\n   * \"Page only\" registered transitions.\n   */\n  public page: ITransitionPage[] = [];\n  /**\n   * \"Once only\" registered transitions.\n   */\n  public once: ITransitionOnce[] = [];\n  /**\n   * Rules for transition resolution.\n   *\n   * Defaults:\n   *\n   * - namespace\n   * - custom\n   */\n  private _rules: IRule[] = [\n    {\n      name: 'namespace',\n      type: 'strings',\n    },\n    {\n      name: 'custom',\n      type: 'function',\n    },\n  ];\n\n  /**\n   * Init store.\n   */\n  constructor(transitions: ITransitionPage[] = []) {\n    /* istanbul ignore else */\n    if (transitions) {\n      // TODO: add check for valid transitions? criteria? (once || enter && leave)\n      this.all = this.all.concat(transitions);\n    }\n    this.update();\n  }\n\n  /**\n   * Add rule or transition.\n   */\n  public add(type: 'rule' | 'transition', data: any): void {\n    switch (type) {\n      case 'rule':\n        // TODO: check for valid rule\n        this._rules.splice(data.position || 0, 0, data.value);\n        break;\n      case 'transition':\n      default:\n        // TODO: check for valid transition\n        this.all.push(data);\n        break;\n    }\n\n    this.update();\n  }\n\n  /**\n   * Resolve transition.\n   */\n  public resolve(\n    data: ITransitionData,\n    filters: ITransitionFilters = {}\n  ): ITransitionOnce | ITransitionPage {\n    // Filter on \"once\"\n    let transitions = filters.once ? this.once : this.page;\n\n    // Filter on \"self\"\n    if (filters.self) {\n      transitions = transitions.filter(t => t.name && t.name === 'self');\n    } else {\n      transitions = transitions.filter(t => !t.name || t.name !== 'self');\n    }\n\n    // All matching transition infos\n    const matching = new Map();\n\n    // Active = first of valid transitions\n    // sorted by directions (from/to, from || to, …)\n    const active = transitions.find(t => {\n      let valid = true;\n      const match = {};\n\n      if (filters.self && t.name === 'self') {\n        matching.set(t, match);\n        return true;\n      }\n\n      // Check rules\n      this._rules.reverse().forEach(rule => {\n        if (valid) {\n          valid = this._check(t, rule, data, match);\n          // From/to check\n          if (t.from && t.to) {\n            valid =\n              this._check(t, rule, data, match, 'from') &&\n              this._check(t, rule, data, match, 'to');\n          }\n          if (t.from && !t.to) {\n            valid = this._check(t, rule, data, match, 'from');\n          }\n          if (!t.from && t.to) {\n            valid = this._check(t, rule, data, match, 'to');\n          }\n        }\n      });\n\n      matching.set(t, match);\n\n      return valid;\n    });\n\n    const activeMatch = matching.get(active);\n    const transitionType = [];\n    if (filters.once) {\n      transitionType.push('once');\n    } else {\n      transitionType.push('page');\n    }\n    if (filters.self) {\n      transitionType.push('self');\n    }\n\n    if (activeMatch) {\n      // Log resolved transition\n      const infos: any[] = [active];\n      // Log if matching criteria\n      Object.keys(activeMatch).length > 0 && infos.push(activeMatch);\n\n      this.logger.info(\n        `Transition found [${transitionType.join(',')}]`,\n        ...infos\n      );\n    } else {\n      this.logger.info(`No transition found [${transitionType.join(',')}]`);\n    }\n\n    return active;\n  }\n\n  /**\n   * ### Update store.\n   *\n   * - Reorder transition by priorities\n   * - Get wait indicator\n   * - Get once transitions\n   */\n  public update(): void {\n    // Reorder by priorities\n    this.all = this.all\n      .map(t => this._addPriority(t))\n      .sort((a, b) => a.priority - b.priority)\n      .reverse()\n      .map(t => {\n        delete t.priority;\n\n        return t;\n      });\n    this.page = this.all.filter(\n      t => t.leave !== undefined || t.enter !== undefined\n    ) as ITransitionPage[];\n    this.once = this.all.filter(t => t.once !== undefined) as ITransitionOnce[];\n  }\n\n  /**\n   * ### Check if transition apply.\n   *\n   * Based on rule, page data and optional direction:\n   *\n   * 1. transition has no rule \"property\":\n   *    - always returns true\n   * 2. transition has rule \"property\":\n   *     - \"strings\" should be present on both side (transition + page) and match\n   *     - \"function\" should return true\n   */\n  private _check(\n    transition: ITransitionPage,\n    rule: IRule,\n    data: ITransitionData,\n    match: any,\n    direction?: 'from' | 'to'\n  ): boolean {\n    let isValid = true;\n    let hasMatch = false;\n    const t = transition;\n    const { name, type } = rule;\n    const strRule = name as IRules['strings'];\n    const objRule = name as IRules['object'];\n    const fnName = name as IRules['function'];\n    const base = direction ? t[direction] : t; // = t || t.from || t.to\n    const page = direction === 'to' ? data.next : data.current; // = current || next\n    const exist = direction ? base && base[name] : base[name];\n\n    // If transition rule exists\n    if (exist) {\n      switch (type) {\n        case 'strings':\n        default: {\n          // Array support\n          const names: string[] = Array.isArray(base[strRule])\n            ? (base[strRule] as string[])\n            : [base[strRule] as string];\n\n          // For matching, prop should be present on both sides and match\n          if (page[strRule] && names.indexOf(page[strRule]) !== -1) {\n            hasMatch = true;\n          }\n          // If transition prop is different from current, not valid\n          if (names.indexOf(page[strRule]) === -1) {\n            isValid = false;\n          }\n          break;\n        }\n\n        case 'object': {\n          // Array support\n          const names: string[] = Array.isArray(base[objRule])\n            ? (base[objRule] as string[])\n            : [base[objRule] as string];\n\n          // For matching, prop should be present on both sides and match\n          if (page[objRule]) {\n            if (\n              page[objRule].name &&\n              names.indexOf(page[objRule].name) !== -1\n            ) {\n              hasMatch = true;\n            }\n            // If transition prop is different from current, not valid\n            if (names.indexOf(page[objRule].name) === -1) {\n              isValid = false;\n            }\n          } else {\n            isValid = false;\n          }\n          break;\n        }\n\n        case 'function':\n          if (base[fnName](data)) {\n            hasMatch = true;\n          } else {\n            isValid = false;\n          }\n          break;\n      }\n\n      if (hasMatch) {\n        if (direction) {\n          match[direction] = match[direction] || {};\n          match[direction][name] = t[direction][name];\n        } else {\n          match[name] = t[name];\n        }\n      }\n    }\n\n    return isValid;\n  }\n\n  /**\n   * ### Calculate transition priority.\n   *\n   * Based on:\n   *\n   * - rule \"position\" (index) give tens, hundreds, thousands, …\n   * - from/to properties give units (0, 1 or 2)\n   */\n  private _calculatePriority(\n    t: ITransitionPage,\n    ruleName: RuleName,\n    ruleIndex: number\n  ): number {\n    let priority = 0;\n\n    if (\n      t[ruleName] ||\n      (t.from && t.from[ruleName]) ||\n      (t.to && t.to[ruleName])\n    ) {\n      priority += Math.pow(10, ruleIndex);\n\n      if (t.from && t.from[ruleName]) {\n        priority += 1;\n      }\n      if (t.to && t.to[ruleName]) {\n        priority += 2;\n      }\n    }\n\n    return priority;\n  }\n\n  private _addPriority(t: ITransitionPage): ITransitionPage {\n    t.priority = 0;\n    let priority = 0;\n\n    this._rules.forEach((rule, i) => {\n      const { name } = rule;\n      const index = i + 1;\n\n      priority += this._calculatePriority(t, name, index);\n    });\n\n    t.priority = priority;\n\n    return t;\n  }\n}\n"
  },
  {
    "path": "packages/core/src/modules/Transitions.ts",
    "content": "/**\n * @barba/core/modules/transitions\n * <br><br>\n * ## Transitions manager.\n *\n * - Handle hooks and transition lifecycle\n *\n * @module core/modules/transitions\n * @preferred\n */\n\n/***/\n\n// Definitions\nimport {\n  HooksTransition,\n  HooksTransitionMap,\n  IResponse,\n  ITransitionData,\n  ITransitionFilters,\n  ITransitionOnce,\n  ITransitionPage,\n  Wrapper,\n} from '../defs';\n// Hooks\nimport { hooks } from '../hooks';\n// Utils\nimport { dom, helpers, runAsync } from '../utils';\n// Modules\nimport { BarbaError } from './Error';\nimport { Logger } from './Logger';\nimport { Store } from './Store';\n\nexport class Transitions {\n  public logger: Logger = new Logger('@barba/core');\n  public store: Store;\n  private _running: boolean = false;\n\n  constructor(transitions: ITransitionPage[] = []) {\n    this.store = new Store(transitions);\n  }\n\n  /**\n   * Get resolved transition\n   *\n   * - based on data\n   */\n  public get(\n    data: ITransitionData,\n    filters?: ITransitionFilters\n  ): ITransitionOnce | ITransitionPage {\n    return this.store.resolve(data, filters);\n  }\n\n  /**\n   * Animation running status.\n   */\n  get isRunning(): boolean {\n    return this._running;\n  }\n  set isRunning(status: boolean) {\n    this._running = status;\n  }\n\n  /**\n   * Check for registered once transition(s).\n   */\n  get hasOnce(): boolean {\n    return this.store.once.length > 0;\n  }\n\n  /**\n   * Check for registered self transition.\n   */\n  get hasSelf(): boolean {\n    return this.store.all.some(t => t.name === 'self');\n  }\n\n  /**\n   * ### Wait indicator.\n   *\n   * Tells Barba to get next page data<br>\n   * before starting the resolution<br>\n   * because some registered transitions need<br>\n   * next page data to be resolved (eg: `sync: true`, `to: { namespace }`, …)\n   */\n  get shouldWait(): boolean {\n    return this.store.all.some(t => (t.to && !t.to.route) || t.sync);\n  }\n\n  /**\n   * ### Do \"once\" transition.\n   *\n   * Hooks: see [[HooksOnce]].\n   */\n  public async doOnce({\n    data,\n    transition,\n  }: {\n    data: ITransitionData;\n    transition: ITransitionOnce;\n  }) {\n    const t = transition || {};\n    this._running = true;\n\n    try {\n      await this._doAsyncHook('beforeOnce', data, t);\n      await this.once(data, t);\n      await this._doAsyncHook('afterOnce', data, t);\n    } catch (error) {\n      this._running = false;\n\n      this.logger.debug('Transition error [before/after/once]');\n      this.logger.error(error);\n    }\n\n    this._running = false;\n  }\n\n  /**\n   * ### Do \"page\" transition.\n   *\n   * Hooks: see [[HooksPage]].\n   *\n   * `sync: false` (default) order:\n   *\n   * 1. before\n   * 2. beforeLeave\n   * 3. leave\n   * 4. afterLeave\n   * 5. beforeEnter\n   * 6. enter\n   * 7. afterEnter\n   * 8. after\n   *\n   * `sync: true` order:\n   *\n   * 1. before\n   * 2. beforeLeave\n   * 3. beforeEnter\n   * 4. leave & enter\n   * 5. afterLeave\n   * 6. afterEnter\n   * 7. after\n   */\n  public async doPage({\n    data,\n    transition,\n    page,\n    wrapper,\n  }: {\n    data: ITransitionData;\n    transition: ITransitionPage;\n    page: Promise<IResponse | void>;\n    wrapper: Wrapper;\n  }) {\n    const t = transition || {};\n    const sync = t.sync === true || false;\n\n    this._running = true;\n\n    try {\n      // Check sync mode, wait for next content\n      if (sync) {\n        await helpers.update(page, data);\n      }\n\n      await this._doAsyncHook('before', data, t);\n\n      if (sync) {\n        try {\n          await this.add(data, wrapper);\n          // Before actions\n          await this._doAsyncHook('beforeLeave', data, t);\n          await this._doAsyncHook('beforeEnter', data, t);\n\n          // Actions\n          await Promise.all([this.leave(data, t), this.enter(data, t)]);\n\n          // After actions\n          await this._doAsyncHook('afterLeave', data, t);\n          await this._doAsyncHook('afterEnter', data, t);\n        } catch (error) {\n          // this.logger.debug('Transition error [sync]');\n          // this.logger.error(error);\n          if (this._isTransitionError(error)) {\n            throw new BarbaError(\n              (error as Error),\n              'Transition error [sync]'\n            );\n          }\n        }\n      } else {\n        let leaveResult: any = false;\n\n        try {\n          // Leave\n          await this._doAsyncHook('beforeLeave', data, t);\n\n          leaveResult = await Promise.all([\n            this.leave(data, t),\n            helpers.update(page, data),\n          ]).then(values => values[0]);\n\n          await this._doAsyncHook('afterLeave', data, t);\n\n          // TODO: check here \"valid\" page result\n          // before going further\n        } catch (error) {\n          // this.logger.debug('Transition error [before/after/leave]');\n          // this.logger.error(error);\n          if (this._isTransitionError(error)) {\n            throw new BarbaError(\n              (error as Error),\n              'Transition error [before/after/leave]'\n            );\n          }\n        }\n\n        try {\n          // Enter\n          /* istanbul ignore else */\n          if (leaveResult !== false) {\n            await this.add(data, wrapper);\n\n            await this._doAsyncHook('beforeEnter', data, t);\n            await this.enter(data, t, leaveResult);\n            await this._doAsyncHook('afterEnter', data, t);\n          }\n        } catch (error) {\n          // this.logger.debug('Transition error [before/after/enter]');\n          // this.logger.error(error);\n          if (this._isTransitionError(error)) {\n            throw new BarbaError(\n              (error as Error),\n              'Transition error [before/after/enter]'\n            );\n          }\n        }\n      }\n\n      // Remove current container\n      await this.remove(data);\n\n      await this._doAsyncHook('after', data, t);\n    } catch (error: any) {\n      this._running = false;\n\n      // If \"custom/specific\" barba error.\n      /* istanbul ignore else */\n      if (error.name && error.name === 'BarbaError') {\n        this.logger.debug(error.label);\n        this.logger.error(error.error);\n\n        throw error;\n      }\n\n      this.logger.debug('Transition error [page]');\n      this.logger.error(error);\n\n      throw error;\n    }\n\n    this._running = false;\n  }\n\n  /**\n   * Once hook + async \"once\" transition.\n   */\n  public async once(data: ITransitionData, t: ITransitionOnce): Promise<void> {\n    await hooks.do('once', data, t);\n\n    return t.once ? runAsync(t.once, t)(data) : Promise.resolve();\n  }\n\n  /**\n   * Leave hook + async \"leave\" transition.\n   */\n  public async leave(data: ITransitionData, t: ITransitionPage): Promise<any> {\n    await hooks.do('leave', data, t);\n\n    return t.leave ? runAsync(t.leave, t)(data) : Promise.resolve();\n  }\n\n  /**\n   * Enter hook + async \"enter\" transition.\n   */\n  public async enter(\n    data: ITransitionData,\n    t: ITransitionPage,\n    leaveResult?: any\n  ): Promise<void> {\n    await hooks.do('enter', data, t);\n\n    return t.enter\n      ? runAsync(t.enter, t)(data, leaveResult)\n      : Promise.resolve();\n  }\n\n  /**\n   * Add next container.\n   */\n  public async add(data: ITransitionData, wrapper: Wrapper): Promise<void> {\n    dom.addContainer(data.next.container, wrapper);\n    hooks.do('nextAdded', data);\n  }\n\n  /**\n   * Remove current container.\n   */\n  public async remove(data: ITransitionData): Promise<void> {\n    dom.removeContainer(data.current.container);\n    hooks.do('currentRemoved', data);\n  }\n\n  private _isTransitionError(error: any) {\n    if (error.message) {\n      // Errors from request\n      return !/Timeout error|Fetch error/.test(error.message);\n    }\n\n    if (error.status) {\n      // Errors from request\n      return false;\n    }\n\n    return true;\n  }\n\n  /**\n   * Do hooks + async transition methods.\n   */\n  private async _doAsyncHook(\n    hook: HooksTransition,\n    data: ITransitionData,\n    t: HooksTransitionMap\n  ): Promise<void> {\n    await hooks.do(hook, data, t);\n\n    return t[hook] ? runAsync(t[hook], t)(data) : Promise.resolve();\n  }\n}\n"
  },
  {
    "path": "packages/core/src/modules/Views.ts",
    "content": "/**\n * @barba/core/modules/views\n * <br><br>\n * ## Views manager.\n *\n * @module core/modules/views\n * @preferred\n */\n\n/***/\n\n// Definitions\nimport { HooksView, IView, IViewData } from '../defs';\n// Hooks\nimport { hooks } from '../hooks';\n// Utils\nimport { runAsync } from '../utils';\n// Types\ntype Hook = (data: IViewData) => Promise<void>;\n\nexport class Views {\n  /**\n   * Available hook names for views.\n   */\n  public names: HooksView[] = [\n    'beforeLeave',\n    'afterLeave',\n    'beforeEnter',\n    'afterEnter',\n  ];\n  /**\n   * Registered views by namespace.\n   */\n  public byNamespace: Map<string, IView> = new Map();\n\n  /**\n   * Init views.\n   */\n  constructor(views: IView[]) {\n    if (views.length === 0) {\n      return;\n    }\n\n    // TODO: add check\n    // for valid views? criteria? (namespace property, string ?)\n    // or duplicate\n    views.forEach(view => {\n      this.byNamespace.set(view.namespace, view);\n    });\n\n    this.names.forEach(name => {\n      hooks[name](this._createHook(name));\n    });\n  }\n\n  /**\n   * Create the hook method.\n   *\n   * - get view based on namespace\n   * - execute callback with transition data\n   */\n  private _createHook(name: HooksView): Hook {\n    return data => {\n      const { namespace } = name.match(/enter/i) ? data.next : data.current;\n      const view = this.byNamespace.get(namespace);\n\n      // TODO: manage self…\n      // if (view && data.trigger !== 'self') {\n      if (view && view[name]) {\n        return runAsync(view[name], view)(data);\n      }\n\n      return Promise.resolve();\n    };\n  }\n}\n"
  },
  {
    "path": "packages/core/src/polyfills/index.ts",
    "content": "// Element.prototype.matches polyfill\n// https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#Polyfill\nif (!Element.prototype.matches) {\n  Element.prototype.matches =\n    (Element as any).prototype.msMatchesSelector ||\n    Element.prototype.webkitMatchesSelector;\n}\n\n// Element.prototype.closest polyfill\n// https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Polyfill\nif (!Element.prototype.closest) {\n  Element.prototype.closest = function closest(s: string) {\n    let el = this;\n\n    do {\n      if (el.matches(s)) {\n        return el;\n      }\n\n      el = (el.parentElement || el.parentNode) as Element;\n    } while (el !== null && el.nodeType === 1);\n\n    return null;\n  };\n}\n"
  },
  {
    "path": "packages/core/src/schemas/attribute.ts",
    "content": "/**\n * @barba/core/schemas\n * <br><br>\n * ## Schemas description.\n *\n * @module core/schemas\n * @preferred\n */\n\n/***/\n\n// Definitions\nimport { ISchemaAttribute } from '../defs';\n\n/**\n * See [[ISchemaAttribute]]\n */\nexport const schemaAttribute: ISchemaAttribute = {\n  container: 'container',\n  history: 'history',\n  namespace: 'namespace',\n  prefix: 'data-barba',\n  prevent: 'prevent',\n  wrapper: 'wrapper',\n};\n"
  },
  {
    "path": "packages/core/src/schemas/page.ts",
    "content": "/**\n * @module core/schemas\n */\n\n// Definitions\nimport { ISchemaPage } from '../defs';\n\n/**\n * See [[ISchemaPage]]\n */\nexport const schemaPage: ISchemaPage = {\n  container: null,\n  html: '',\n  namespace: '',\n  url: {\n    hash: '',\n    href: '',\n    path: '',\n    port: null,\n    query: {},\n  },\n};\n"
  },
  {
    "path": "packages/core/src/typings.ts",
    "content": "export * from './defs';\nexport { default } from './core';\n"
  },
  {
    "path": "packages/core/src/utils/dom.ts",
    "content": "/**\n * @barba/core/utils/dom\n * <br><br>\n * ## Dom utils\n *\n * - Access DOM contents\n * - DOM vs string conversions\n *\n * @module core/utils/dom\n * @preferred\n */\n\n/***/\n\nimport path from 'path';\n\n// Definitions\nimport { IDomSibling, ISchemaAttribute, Link, Scope, Wrapper } from '../defs';\n// Schemas\nimport { schemaAttribute } from '../schemas/attribute';\n\nexport class Dom {\n  private _attr: ISchemaAttribute = schemaAttribute;\n  private _parser: DOMParser;\n  private _sibling: IDomSibling = {\n    after: null,\n    before: null,\n    parent: null\n  };\n\n  /**\n   * Convert HTMLDocument to string.\n   */\n  public toString(el: HTMLElement): string {\n    return el.outerHTML;\n  }\n\n  /**\n   * Parse HTML string to HTMLDocument.\n   */\n  // see https://github.com/barbajs/barba/issues/362\n  // Seems that using DOMParser.parseFromString causes this issue.\n  public toDocument(htmlString: string): HTMLDocument {\n    /* istanbul ignore else */\n    if (!this._parser) {\n      this._parser = new DOMParser();\n    }\n    return this._parser.parseFromString(htmlString, 'text/html');\n  }\n\n  /**\n   * Parse HTML string to DIVElement.\n   *\n   * DOMParser.parseFromString fails with img[srcset] on iOS.\n   * see https://github.com/barbajs/barba/issues/362\n   */\n  public toElement(htmlString: string): HTMLDivElement {\n    const div = document.createElement('div');\n\n    div.innerHTML = htmlString;\n    return div;\n  }\n\n  /**\n   * Get HTML content.\n   */\n  public getHtml(doc: HTMLDocument = document): string {\n    return this.toString(doc.documentElement);\n  }\n\n  /**\n   * Get full document content.\n   */\n  // getDocument(el = document.documentElement) {\n  //   return this.toStr(el);\n  // },\n\n  /**\n   * Get `[data-barba=\"wrapper\"]`.\n   */\n  public getWrapper(scope: Scope = document): Wrapper {\n    return scope.querySelector(\n      `[${this._attr.prefix}=\"${this._attr.wrapper}\"]`\n    );\n  }\n\n  /**\n   * Get `[data-barba=\"container\"]`.\n   */\n  public getContainer(scope: Scope = document): HTMLElement | null {\n    return scope.querySelector(\n      `[${this._attr.prefix}=\"${this._attr.container}\"]`\n    );\n  }\n\n  /**\n   * Remove container and store next sibling (if applicable).\n   */\n  public removeContainer(container: HTMLElement) {\n    if (document.body.contains(container)) {\n      this._updateSibling(container);\n      container.parentNode.removeChild(container);\n    }\n  }\n\n  /**\n   * Add container near previous container\n   */\n  public addContainer(container: HTMLElement, wrapper: HTMLElement) {\n    const siblingBefore = this.getContainer() || this._sibling.before;\n\n    if (siblingBefore) {\n      this._insertAfter(container, siblingBefore);\n    } else if (this._sibling.after) {\n      this._sibling.after.parentNode.insertBefore(container, this._sibling.after);\n    } else if (this._sibling.parent) {\n      this._sibling.parent.appendChild(container);\n    } else {\n      wrapper.appendChild(container);\n    }\n  }\n\n  /**\n   * Get current dom sibling\n   */\n  public getSibling(): IDomSibling {\n    return this._sibling;\n  }\n\n  /**\n   * Get `[data-barba-namespace]`.\n   */\n  public getNamespace(scope: Scope = document): string | null {\n    const ns = scope.querySelector(\n      `[${this._attr.prefix}-${this._attr.namespace}]`\n    );\n\n    return ns\n      ? ns.getAttribute(`${this._attr.prefix}-${this._attr.namespace}`)\n      : null;\n  }\n\n  /**\n   * Get URL from `href` value.\n   */\n  public getHref(el: Link): string | null {\n    // HTML tagName is UPPERCASE, xhtml tagName keeps existing case.\n    if (el.tagName && el.tagName.toLowerCase() === 'a') {\n      // HTMLAnchorElement, full URL available\n      if (typeof el.href === 'string') {\n        return el.href;\n      }\n\n      // Probably a SVGAElement…\n      const href = el.getAttribute('href') || el.getAttribute('xlink:href');\n\n      /* istanbul ignore else */\n      if (href) {\n        // When link comes from SVG, `href` returns an object, not a string.\n        const attr: string =\n          ((href as unknown) as SVGAnimatedString).baseVal || href;\n\n        return this.resolveUrl(attr);\n      }\n    }\n    return null;\n  }\n\n  // Copyright 2014 Simon Lydell\n  // X11 (“MIT”) Licensed. (See LICENSE\n  // https://github.com/lydell/resolve-url/blob/master/resolve-url.js\n  /* istanbul ignore next */\n  public resolveUrl(...urls: string[]) {\n    const numUrls = urls.length;\n\n    if (numUrls === 0) {\n      throw new Error('resolveUrl requires at least one argument; got none.');\n    }\n\n    const base = document.createElement('base');\n    base.href = arguments[0];\n\n    if (numUrls === 1) {\n      return base.href;\n    }\n\n    const head = document.getElementsByTagName('head')[0];\n    head.insertBefore(base, head.firstChild);\n\n    const a = document.createElement('a');\n    let resolved;\n\n    for (let index = 1; index < numUrls; index++) {\n      a.href = arguments[index];\n      resolved = a.href;\n      base.href = resolved;\n    }\n\n    head.removeChild(base);\n\n    return resolved;\n  }\n\n  /**\n   * Insert node after another node.\n   */\n  private _insertAfter(newNode: Node, referenceNode: Node) {\n    referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);\n  }\n\n  /**\n   * Update current dom sibling regarding container\n   */\n  private _updateSibling(container: HTMLElement): IDomSibling {\n    this._sibling = {\n      after: container.nextElementSibling,\n      before: container.previousElementSibling,\n      parent: container.parentElement\n    };\n\n    return this._sibling;\n  }\n}\n\nconst dom = new Dom();\n\nexport { dom };\n"
  },
  {
    "path": "packages/core/src/utils/helpers.ts",
    "content": "/**\n * @barba/core/utils/helpers\n * <br><br>\n * ## Helpers\n *\n * - Update next page data\n *\n * @module core/utils/helpers\n * @preferred\n */\n\n/***/\n\n// Third-party\nimport { pathToRegexp as ptr } from 'path-to-regexp';\n// Definitions\nimport { IResponse, ITransitionData } from '../defs';\n// Utils\nimport { dom } from './dom';\nimport { history } from './history';\n\n/**\n * Update `data.next`, the title and the history\n */\nexport const update = async (\n  page: Promise<IResponse | void>,\n  data: ITransitionData\n): Promise<void> => {\n  // If not already updated\n  if (!data.next.html) {\n    const response = await page;\n    const { next } = data;\n\n    if (response) {\n      // see: https://github.com/barbajs/barba/issues/362\n      // const nextDocument = dom.toDocument(html);\n      const nextDocument = dom.toElement(response.html);\n\n      next.namespace = dom.getNamespace(nextDocument);\n      next.container = dom.getContainer(nextDocument);\n      // see https://github.com/barbajs/barba/issues/362\n      // next.html = dom.getHtml(nextDocument);\n      // next.html = nextDocument.innerHTML;\n      next.url = response.url;\n      next.html = response.html;\n\n      // Update history namespace (not available when initially set)\n      history.update({ ns: next.namespace });\n\n      // Update title.\n      const { title } = dom.toDocument(response.html);\n\n      document.title = title;\n    }\n  }\n};\n\n/**\n * Next tick\n */\nexport const nextTick = () =>\n  new Promise(resolve => {\n    window.requestAnimationFrame(resolve);\n    // DEV: same result?\n    // setTimeout(resolve, 0);\n  });\n\n/**\n * Turn a route string such as `/user/:name` into a regular expression.\n *\n * Used for:\n *\n * - routes to ignore\n * - route transition resolution\n *\n * @see https://www.npmjs.com/package/path-to-regexp\n */\nconst pathToRegexp = ptr;\n\nexport { pathToRegexp };\n"
  },
  {
    "path": "packages/core/src/utils/history.ts",
    "content": "import { HistoryAction, LinkEvent, Trigger } from '../defs';\n// Schemas\nimport { schemaAttribute } from '../schemas/attribute';\n\n/**\n * @barba/core/utils/history\n * <br><br>\n * ## History manager.\n *\n * - Keep track of the navigation history\n *\n * @module core/utils/history\n * @preferred\n */\n\n/**\n * State item.\n *\n * @property from\n * @property index\n */\ninterface IHistoryItem {\n  /** origin */\n  from: string;\n  /** index */\n  index: number;\n  /** states */\n  states: IStateItem[];\n}\n\n/***/\ninterface ICoords {\n  x: number;\n  y: number;\n}\n\n/**\n * History item.\n *\n * @property namespace\n * @property scroll\n * @property URL\n */\ninterface IStateItem {\n  /** data */\n  data: object;\n  /** namespace */\n  ns: string | undefined;\n  /** Scroll position */\n  scroll: ICoords;\n  /** URL */\n  url: string;\n}\n\nexport class History {\n  private _session: string;\n  private _states: IStateItem[] = [];\n  private _pointer = -1;\n\n  /**\n   * Init with first state.\n   */\n  public init(url: string, ns: string): void {\n    this._session = 'barba';\n\n    const state: IStateItem = {\n      data: {},\n      ns,\n      scroll: {\n        x: window.scrollX,\n        y: window.scrollY,\n      },\n      url,\n    };\n\n    this._pointer = 0;\n    this._states.push(state);\n\n    const item: IHistoryItem = {\n      from: this._session,\n      index: this._pointer,\n      states: [...this._states],\n    };\n\n    window.history && window.history.replaceState(item, '', url);\n  }\n\n  public change(\n    url: string,\n    trigger: Trigger,\n    e?: LinkEvent | PopStateEvent\n  ): Trigger {\n    if (e && (e as PopStateEvent).state) {\n      // If popstate, move to existing state\n      // and get back/forward direction.\n      const { state }: { state: IHistoryItem } = e as PopStateEvent;\n      const { index } = state;\n      const diff = this._pointer - index;\n\n      trigger = this._getDirection(diff);\n\n      // Work with previous states\n      this.replace(state.states);\n      this._pointer = index;\n    } else {\n      // Add new state\n      this.add(url, trigger);\n    }\n\n    return trigger;\n  }\n\n  /**\n   * Add a new state.\n   */\n  public add(url: string, trigger: Trigger, action?: HistoryAction, data?: object): void {\n    // If no state, it will be updated later.\n    const ns = 'tmp';\n    const method = action ?? this._getAction(trigger);\n    const state: IStateItem = {\n      data: data ?? {},\n      ns,\n      scroll: {\n        x: window.scrollX,\n        y: window.scrollY,\n      },\n      url,\n    };\n\n    switch (method) {\n      case 'push':\n        this._pointer = this.size;\n        this._states.push(state);\n        break;\n      case 'replace':\n        this.set(this._pointer, state);\n        break;\n      /* istanbul ignore next */\n      default:\n    }\n\n    const item: IHistoryItem = {\n      from: this._session,\n      index: this._pointer,\n      states: [...this._states],\n    };\n\n    switch (method) {\n      case 'push':\n        window.history && window.history.pushState(item, '', url);\n        break;\n      case 'replace':\n        window.history && window.history.replaceState(item, '', url);\n        break;\n      /* istanbul ignore next */\n      default:\n    }\n  }\n\n  /**\n   * Store custom user data per state.\n   */\n   public store(data: object, i?: number): void {\n     const index = i || this._pointer;\n     const state = this.get(index);\n\n     // merge data (allow data overwrite)\n     state.data = {\n       ...state.data,\n       ...data\n     };\n\n     // update states\n     this.set(index, state);\n\n     const item: IHistoryItem = {\n       from: this._session,\n       index: this._pointer,\n       states: [...this._states],\n     };\n\n     // update browser history\n     window.history.replaceState(item, '');\n   }\n\n  /**\n   * Update state.\n   */\n  public update(data: any, i?: number): void {\n    const index = i || this._pointer;\n    const existing = this.get(index);\n    const state: IStateItem = {\n      ...existing,\n      ...data,\n    };\n\n    this.set(index, state);\n  }\n\n  /**\n   * Remove last state.\n   */\n  public remove(i?: number): void {\n    if (i) {\n      this._states.splice(i, 1);\n    } else {\n      this._states.pop();\n    }\n\n    this._pointer--;\n  }\n\n  /**\n   * Delete all states.\n   */\n  public clear(): void {\n    this._states = [];\n    this._pointer = -1;\n  }\n\n  /**\n   * Replace all states.\n   */\n  public replace(newStates: IStateItem[]): void {\n    this._states = newStates;\n  }\n\n  /**\n   * Get state by index.\n   */\n  public get(index: number): IStateItem {\n    return this._states[index];\n  }\n\n  /**\n   * Set state by index.\n   */\n  public set(i: number, state: IStateItem) {\n    return (this._states[i] = state);\n  }\n\n  /**\n   * Get the current state.\n   */\n  get current(): IStateItem {\n    return this._states[this._pointer];\n  }\n\n  /**\n   * Get the previous state.\n   */\n  get previous(): IStateItem | null {\n    return this._pointer < 1 ? null : this._states[this._pointer - 1];\n  }\n\n  /**\n   * Get the state size.\n   */\n  get size(): number {\n    return this._states.length;\n  }\n\n  /**\n   * Get the history action: push vs replace\n   */\n  private _getAction(trigger: Trigger): HistoryAction {\n    let action: HistoryAction = 'push';\n\n    // Manage `data-barba-history` attribute\n    // to get the right action (push vs replace).\n    const el = trigger as HTMLAnchorElement;\n    const attr = `${schemaAttribute.prefix}-${schemaAttribute.history}`;\n\n    if (el.hasAttribute && el.hasAttribute(attr)) {\n      action = el.getAttribute(attr) as HistoryAction;\n    }\n\n    return action;\n  }\n\n  /**\n   * Get the direction of popstate change\n   */\n  private _getDirection(diff: number): Trigger {\n    // Check if \"session switch\"\n    if (Math.abs(diff) > 1) {\n      // Ex 6-0 > 0 -> forward, 0-6 < 0 -> back\n      return diff > 0 ? 'forward' : 'back';\n    } else {\n      if (diff === 0) {\n        return 'popstate';\n      } else {\n        // Ex 6-5 > 0 -> back, 5-6 < 0 -> forward\n        return diff > 0 ? 'back' : 'forward';\n      }\n    }\n  }\n}\n\nconst history = new History();\n\nexport { history };\n"
  },
  {
    "path": "packages/core/src/utils/index.ts",
    "content": "import * as helpers from './helpers';\nimport * as url from './url';\n\nexport * from './dom';\nexport * from './history';\nexport * from './request';\nexport * from './run-async';\nexport { helpers, url };\n"
  },
  {
    "path": "packages/core/src/utils/request.ts",
    "content": "/**\n * @barba/core/utils/request\n * <br><br>\n * ## Fetch pages for transitions.\n *\n * - Includes timeout\n * - Uses Fetch API\n * - Handles errors\n *\n * @module core/utils/request\n * @preferred\n */\n\n/***/\n\n// Definitions\nimport { Cache } from '@barba/core/src/modules/Cache';\nimport { Headers } from '@barba/core/src/modules/Headers';\nimport { IResponse, RequestError } from '../defs';\nimport { parse } from './url';\n\n/**\n * Init a page request.\n * Fetch the page and returns a promise with the text content.\n */\nfunction request(\n  url: string,\n  ttl: number = 2e3,\n  requestError: RequestError,\n  cache: Cache,\n  headers: Headers\n): Promise<IResponse> {\n  return new Promise((resolve, reject) => {\n    const xhr = new XMLHttpRequest();\n\n    xhr.onreadystatechange = () => {\n      if (xhr.readyState === XMLHttpRequest.DONE) {\n        if (xhr.status === 200) {\n          /* istanbul ignore next: bypass jest since xhr-mock doesn't support custom xhr.responseURL */\n          const responseURL = xhr.responseURL !== '' && xhr.responseURL !== url ? xhr.responseURL : url;\n\n          resolve({\n            html: xhr.responseText,\n            url: {\n              href: responseURL,\n              ...parse(responseURL)\n            },\n          });\n\n          cache.update(url, {\n            status: 'fulfilled',\n            target: responseURL\n          });\n        } else if (xhr.status) {\n          // HTTP code is not 200, reject with response.\n          const response = {\n            status: xhr.status,\n            statusText: xhr.statusText,\n          };\n\n          requestError(url, response);\n          reject(response);\n\n          cache.update(url, { status: 'rejected' });\n        }\n      }\n    };\n\n    xhr.ontimeout = () => {\n      const error = new Error(`Timeout error [${ttl}]`);\n      requestError(url, error);\n      reject(error);\n      cache.update(url, { status: 'rejected' });\n    };\n\n    xhr.onerror = () => {\n      const error = new Error(`Fetch error`);\n      requestError(url, error);\n      reject(error);\n      cache.update(url, { status: 'rejected' });\n    };\n\n    xhr.open('GET', url);\n    xhr.timeout = ttl;\n    xhr.setRequestHeader(\n      'Accept',\n      'text/html,application/xhtml+xml,application/xml'\n    );\n    xhr.setRequestHeader('x-barba', 'yes');\n\n    headers.all().forEach((value, key) => {\n      xhr.setRequestHeader(key, value);\n    });\n\n    xhr.send();\n  });\n}\n\nexport { request };\n"
  },
  {
    "path": "packages/core/src/utils/run-async.ts",
    "content": "import isPromise from 'is-promise';\n\n// https://github.com/SBoudrias/run-async\n/* istanbul ignore next */\nexport function runAsync(\n  func: (...args: any[]) => void | Promise<any>,\n  ctx: any = {}\n): (...args: any[]) => Promise<any> {\n  return (...args: any[]) => {\n    let async = false;\n\n    const promise = new Promise((resolve, reject) => {\n      // Add async to context\n      ctx.async = () => {\n        async = true;\n\n        return (err: any, value: any) => {\n          if (err) {\n            reject(err);\n          } else {\n            resolve(value);\n          }\n        };\n      };\n\n      const answer = func.apply(ctx, args as []);\n\n      if (!async) {\n        if (isPromise(answer)) {\n          (answer as Promise<any>).then(resolve, reject);\n        } else {\n          resolve(answer);\n        }\n      }\n    });\n\n    return promise;\n  };\n}\n"
  },
  {
    "path": "packages/core/src/utils/url.ts",
    "content": "/**\n * @barba/core/utils/url\n * <br><br>\n * ## URL utils.\n *\n * - Collect and structure informations from URLs\n *\n * @module core/utils/url\n */\n\n/***/\n\n// Definitions\nimport { IGenericObject, IUrlBase } from '../defs';\n\n/**\n * Get location href.\n */\nexport const getHref = () => window.location.href;\n\n/**\n * Get absolute href from URL.\n */\nexport const getAbsoluteHref = (url: string, base: string = document.baseURI): string => new URL(url, base).href;\n\n/**\n * Get location origin.\n */\nexport const getOrigin = () => window.location.origin;\n\n/**\n * Get port based on URL or location.\n */\nexport const getPort = (url: string = window.location.href) => parse(url).port;\n\n/**\n * Get path from URL.\n */\nexport const getPath = (url: string = window.location.href) => parse(url).path;\n\n/**\n * Get query object from URL.\n */\nexport const getQuery = (url: string, stringify: boolean = false): IGenericObject|string => {\n  return stringify ? JSON.stringify(parse(url).query) : parse(url).query;\n};\n\n/**\n * Get hash from URL.\n */\nexport const getHash = (url: string): string => parse(url).hash;\n\n/**\n * Parse URL for path, query and hash and more.\n */\nexport const parse = (url: string): IUrlBase => {\n  // Port\n  let port;\n  const matches = url.match(/:\\d+/);\n\n  if (matches === null) {\n    if (/^http/.test(url)) {\n      port = 80;\n    }\n\n    if (/^https/.test(url)) {\n      port = 443;\n    }\n  } else {\n    const portString = matches[0].substring(1);\n\n    port = parseInt(portString, 10);\n  }\n\n  // Path\n  let path = url.replace(getOrigin(), '');\n  let hash;\n  let query = {};\n\n  // Hash\n  const hashIndex = path.indexOf('#');\n\n  if (hashIndex >= 0) {\n    hash = path.slice(hashIndex + 1);\n    path = path.slice(0, hashIndex);\n  }\n\n  // Query\n  const queryIndex = path.indexOf('?');\n\n  if (queryIndex >= 0) {\n    query = parseQuery(path.slice(queryIndex + 1));\n    path = path.slice(0, queryIndex);\n  }\n\n  return {\n    hash,\n    path,\n    port,\n    query,\n  };\n};\n\n/**\n * Parse a query string to object.\n */\nexport const parseQuery = (str: string) =>\n  str.split('&').reduce((acc: IGenericObject, el: string) => {\n    const [key, value] = el.split('=');\n\n    acc[key] = value;\n\n    return acc;\n  }, {});\n\n/**\n * Clean URL, remove \"hash\" and/or \"trailing slash\".\n */\nexport const clean = (url: string = window.location.href) =>\n  url.replace(/(\\/#.*|\\/|#.*)$/, '');\n"
  },
  {
    "path": "packages/css/.npmignore",
    "content": "### Custom ###\n/__e2e__\n/__mocks__\n/__tests__\n/__web__\n/jest.config.js\n/mangle.json\n/*.md\n/.rts2*\n!/README.md\n!/CHANGELOG.md\n"
  },
  {
    "path": "packages/css/AUTHORS",
    "content": "Luigi De Rosa <lurukee@gmail.com> (https://luruke.com/)\nThierry Michel <thmichel@gmail.com> (https://www.epic.net/)\nXavier Foucrier <xavier.foucrier@gmail.com> (https://xavierfoucrier.dev/)\n"
  },
  {
    "path": "packages/css/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n## [2.1.16](https://github.com/barbajs/barba/compare/@barba/css@2.1.15...@barba/css@2.1.16) (2024-05-10)\n\n### Bug Fixes\n\n- **core:** :pencil2: fix typos in tests ([a748356](https://github.com/barbajs/barba/commit/a748356daf77117a120783eee4750c16e7603ad2))\n- **css:** :bug: fix broken transition with sync mode and popstate events ([ae6f5f7](https://github.com/barbajs/barba/commit/ae6f5f7359d5994efd5f1d3379fc27ac6992fbb4)), closes [#559](https://github.com/barbajs/barba/issues/559)\n\n## [2.1.15](https://github.com/barbajs/barba/compare/@barba/css@2.1.14...@barba/css@2.1.15) (2019-11-25)\n\n### Bug Fixes\n\n- **root:** :art: improve typings for TS ([48f0637](https://github.com/barbajs/barba/commit/48f0637))\n\n## [2.1.14](https://github.com/barbajs/barba/compare/@barba/css@2.1.13...@barba/css@2.1.14) (2019-11-25)\n\n**Note:** Version bump only for package @barba/css\n\n## [2.1.13](https://github.com/barbajs/barba/compare/@barba/css@2.1.12...@barba/css@2.1.13) (2019-11-06)\n\n### Bug Fixes\n\n- **core:** :ok_hand: resolve once transitions ([20cafe1](https://github.com/barbajs/barba/commit/20cafe1)), closes [#439](https://github.com/barbajs/barba/issues/439)\n\n## [2.1.12](https://github.com/barbajs/barba/compare/@barba/css@2.1.11...@barba/css@2.1.12) (2019-11-05)\n\n### Bug Fixes\n\n- **root:** :bug: fix context for views and add to transitions ([9054673](https://github.com/barbajs/barba/commit/9054673)), closes [#467](https://github.com/barbajs/barba/issues/467)\n\n## [2.1.11](https://github.com/barbajs/barba/compare/@barba/css@2.1.10...@barba/css@2.1.11) (2019-08-02)\n\n### Bug Fixes\n\n- **css:** :bug: do not trigger `enter` transition on first load ([f283cd2](https://github.com/barbajs/barba/commit/f283cd2)), closes [#393](https://github.com/barbajs/barba/issues/393)\n\n## [2.1.10](https://github.com/barbajs/barba/compare/@barba/css@2.1.9...@barba/css@2.1.10) (2019-07-16)\n\n### Bug Fixes\n\n- **root:** :mute: remove print version ([be5aa73](https://github.com/barbajs/barba/commit/be5aa73)), closes [#415](https://github.com/barbajs/barba/issues/415)\n\n## [2.1.9](https://github.com/barbajs/barba/compare/@barba/css@2.1.8...@barba/css@2.1.9) (2019-06-11)\n\n**Note:** Version bump only for package @barba/css\n\n## [2.1.8](https://github.com/barbajs/barba/compare/@barba/css@2.1.7...@barba/css@2.1.8) (2019-04-29)\n\n**Note:** Version bump only for package @barba/css\n\n## [2.1.7](https://github.com/barbajs/barba/compare/@barba/css@2.1.6...@barba/css@2.1.7) (2019-04-29)\n\n**Note:** Version bump only for package @barba/css\n\n## [2.1.6](https://github.com/barbajs/barba/compare/@barba/css@2.1.5...@barba/css@2.1.6) (2019-04-23)\n\n### Bug Fixes\n\n- **css:** :bug: remove current container after leave ([a06ec61](https://github.com/barbajs/barba/commit/a06ec61))\n\n## [2.1.5](https://github.com/barbajs/barba/compare/@barba/css@2.1.4...@barba/css@2.1.5) (2019-04-14)\n\n### Bug Fixes\n\n- **css:** :bug: trigger overriden global hooks ([5435702](https://github.com/barbajs/barba/commit/5435702))\n\n## [2.1.4](https://github.com/barbajs/barba/compare/@barba/css@2.1.3...@barba/css@2.1.4) (2019-04-14)\n\n### Bug Fixes\n\n- **css:** :recycle: rewrite CSS plugin ([12ce8ac](https://github.com/barbajs/barba/commit/12ce8ac))\n\n## [2.1.3](https://github.com/barbajs/barba/compare/@barba/css@2.1.2...@barba/css@2.1.3) (2019-04-13)\n\n### Bug Fixes\n\n- **css:** :loud_sound: print version ([3a222d3](https://github.com/barbajs/barba/commit/3a222d3))\n\n### Reverts\n\n- **root:** :bug: revert failed release ([2b8a1ef](https://github.com/barbajs/barba/commit/2b8a1ef))\n\n## [2.1.3](https://github.com/barbajs/barba/compare/@barba/css@2.1.2...@barba/css@2.1.3) (2019-04-13)\n\n### Bug Fixes\n\n- **css:** :loud_sound: print version ([3a222d3](https://github.com/barbajs/barba/commit/3a222d3))\n\n## [2.1.2](https://github.com/barbajs/barba/compare/@barba/css@2.1.1...@barba/css@2.1.2) (2019-04-13)\n\n### Bug Fixes\n\n- **core:** :mute: remove debug logs ([f4ce952](https://github.com/barbajs/barba/commit/f4ce952))\n\n## [2.1.1](https://github.com/barbajs/barba/compare/@barba/css@2.1.0...@barba/css@2.1.1) (2019-04-13)\n\n### Bug Fixes\n\n- **css:** :bug: fix transitions public hooks ([af5fa22](https://github.com/barbajs/barba/commit/af5fa22))\n\n# 2.1.0 (2019-03-17)\n\n### Bug Fixes\n\n- **css:** :bug: fix css with next tick ([63642bf](https://github.com/barbajs/barba/commit/63642bf))\n\n### Features\n\n- **css:** :recycle: add transitionend logic + big refactoring ([b775358](https://github.com/barbajs/barba/commit/b775358))\n- **css:** :tada: initial commit ([aed8206](https://github.com/barbajs/barba/commit/aed8206))\n"
  },
  {
    "path": "packages/css/LICENSE",
    "content": "MIT License\n\nCopyright (c) 2024 Luigi De Rosa, Thierry Michel, Xavier Foucrier\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 all\ncopies 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 THE\nSOFTWARE.\n"
  },
  {
    "path": "packages/css/README.md",
    "content": "# @barba/css\n\n[![NPM version](https://img.shields.io/npm/v/@barba/css?style=flat-square)](https://www.npmjs.com/package/@barba/css)\n[![Dependencies](https://img.shields.io/librariesio/release/npm/@barba/css?style=flat-square)](https://github.com/barbajs/barba/network/dependencies)\n\n> TBD ([GitHub repo](https://github.com/barbajs/barba.js))\n\n## Install\n\nUsing npm:\n\n```sh\nnpm install --save-dev @barba/css\n```\n\nor using yarn:\n\n```sh\nyarn add @barba/css --dev\n```\n"
  },
  {
    "path": "packages/css/__e2e__/default.spec.js",
    "content": "describe('Transition', () => {\n  it('works', () => {\n    cy.prepare('/index.html', 'home', 'home');\n    // Click link\n    cy.wait(1000); // eslint-disable-line cypress/no-unnecessary-waiting\n    cy.get('[data-test=link]').click();\n    cy.final('/page.html', 'page', 'page');\n    cy.get('@next')\n      .should('not.have.class', 'barba-enter')\n      .should('not.have.class', 'barba-enter-to')\n      .should('not.have.class', 'barba-enter-active');\n  });\n});\n"
  },
  {
    "path": "packages/css/__e2e__/named.spec.js",
    "content": "describe('Named transition', () => {\n  it('works', () => {\n    cy.prepare('/named.html', 'named', 'named');\n    // Click link\n    cy.wait(1000); // eslint-disable-line cypress/no-unnecessary-waiting\n    cy.get('[data-test=link]').click();\n    cy.final('/page.html', 'page', 'page');\n    cy.get('@next')\n      .should('not.have.class', 'named-enter')\n      .should('not.have.class', 'named-enter-to')\n      .should('not.have.class', 'named-enter-active');\n  });\n});\n"
  },
  {
    "path": "packages/css/__e2e__/once.spec.js",
    "content": "describe('Once transition', () => {\n  it('works', () => {\n    cy.prepare('/once.html', 'once', 'once');\n    // Click link\n    // cy.get('[data-test=link]').click();\n    // cy.final('/page.html', 'page', 'page');\n    cy.get('@current')\n      .should('not.have.class', 'named-enter')\n      .should('not.have.class', 'named-enter-to')\n      .should('not.have.class', 'named-enter-active');\n  });\n});\n"
  },
  {
    "path": "packages/css/__tests__/css.classes.test.ts",
    "content": "import css from '../src';\n\n// Dom\nconst container = document.createElement('div');\nconst step = 'test';\n\nit('add/remove class', () => {\n  css.add(container, step);\n\n  expect(container.classList.contains(`barba-${step}`)).toBeTruthy();\n\n  css.remove(container, step);\n\n  expect(container.classList.contains(`barba-${step}`)).toBeFalsy();\n});\n"
  },
  {
    "path": "packages/css/__tests__/css.hooks.test.ts",
    "content": "/* tslint:disable:no-string-literal */\nimport barba from '@barba/core/src';\n// Definitions\nimport { ISchemaPage, ITransitionData } from '@barba/core/src/defs';\nimport css from '../src';\n\n// Dom\nconst wrapper = document.createElement('div');\nconst current = document.createElement('div');\nconst next = document.createElement('div');\n\nwrapper.dataset.barba = 'wrapper';\ncurrent.dataset.barba = 'container';\n\ndocument.body.appendChild(wrapper);\ndocument.body.appendChild(current);\n\nconst t = {\n  enter: () => Promise.resolve(),\n  leave: () => Promise.resolve(),\n  once: () => Promise.resolve(),\n};\nconst data: ITransitionData = {\n  current: ({ container: current } as unknown) as ISchemaPage,\n  next: ({ container: next } as unknown) as ISchemaPage,\n  trigger: 'barba',\n};\n\nbarba.use(css);\nbarba.init();\n\ncss.start = jest.fn();\ncss.next = jest.fn();\ncss.end = jest.fn();\n\nit('do once hooks', async () => {\n  await barba.hooks.do('beforeOnce', data, t);\n  await barba.hooks.do('afterOnce', data, t);\n\n  expect(css.start).toHaveBeenCalledWith(next, 'once');\n  expect(css.end).toHaveBeenCalledWith(next, 'once');\n});\n\nit('do leave hooks', async () => {\n  await barba.hooks.do('beforeLeave', data, t);\n  await barba.hooks.do('afterLeave', data, t);\n\n  expect(css.start).toHaveBeenCalledWith(current, 'leave');\n  expect(css.end).toHaveBeenCalledWith(current, 'leave');\n});\n\nit('do enter hooks on first load', async () => {\n  // Remove from history to simulate first page load.\n  barba.history.remove();\n\n  await barba.hooks.do('beforeEnter', data, t);\n  await barba.hooks.do('afterEnter', data, t);\n\n  expect(css.start).toHaveBeenCalledWith(next, 'enter');\n  expect(css.end).toHaveBeenCalledWith(next, 'enter');\n});\n\nit('do enter hooks', async () => {\n  await barba.hooks.do('beforeEnter', data, t);\n  await barba.hooks.do('afterEnter', data, t);\n\n  expect(css.start).toHaveBeenCalledWith(next, 'enter');\n  expect(css.end).toHaveBeenCalledWith(next, 'enter');\n});\n\nit('override transitions', async () => {\n  await barba.transitions.once(data, t);\n  await barba.transitions.leave(data, t);\n  await barba.transitions.enter(data, t);\n\n  expect(css.next).toHaveBeenNthCalledWith(1, next, 'once');\n  expect(css.next).toHaveBeenNthCalledWith(2, current, 'leave');\n  expect(css.next).toHaveBeenNthCalledWith(3, next, 'enter');\n});\n"
  },
  {
    "path": "packages/css/__tests__/css.init.test.ts",
    "content": "/* tslint:disable:no-string-literal */\nimport barba from '@barba/core/src';\nimport { version } from '../package.json';\nimport css from '../src';\n\n// Dom\nconst wrapper = document.createElement('div');\nconst container = document.createElement('div');\n\nwrapper.dataset.barba = 'wrapper';\ncontainer.dataset.barba = 'container';\n\ndocument.body.appendChild(wrapper);\ndocument.body.appendChild(container);\n\nit('has defaults', () => {\n  expect(css.version).toBe(version);\n  expect(css.prefix).toBe('barba');\n  expect(css.callbacks).toEqual({});\n});\n\nit('registers hooks', () => {\n  barba.use(css);\n  barba.init();\n\n  expect(barba.hooks.registered.get('before').size).toBe(1);\n  expect(barba.hooks.registered.get('beforeOnce').size).toBe(2);\n  expect(barba.hooks.registered.get('afterOnce').size).toBe(1);\n  expect(barba.hooks.registered.get('beforeLeave').size).toBe(1);\n  expect(barba.hooks.registered.get('afterLeave').size).toBe(1);\n  expect(barba.hooks.registered.get('beforeEnter').size).toBe(1);\n  expect(barba.hooks.registered.get('afterEnter').size).toBe(1);\n});\n\nit('overrides transitions', () => {\n  expect(barba.transitions['once']).toBe(css['_once']);\n  expect(barba.transitions['leave']).toBe(css['_leave']);\n  expect(barba.transitions['enter']).toBe(css['_enter']);\n});\n"
  },
  {
    "path": "packages/css/__tests__/css.prefix.test.ts",
    "content": "/* tslint:disable:no-empty */\nimport barba from '@barba/core/src';\nimport css from '../src';\nimport { Css } from '../src/css';\n\n// Dom\nconst wrapper = document.createElement('div');\nconst container = document.createElement('div');\n\nwrapper.dataset.barba = 'wrapper';\ncontainer.dataset.barba = 'container';\n\ndocument.body.appendChild(wrapper);\ndocument.body.appendChild(container);\n\n// Transitions\nconst name = 'my-name';\nconst unnamed = {\n  once() {},\n  leave() {},\n  enter() {},\n};\nconst named = {\n  ...unnamed,\n  name,\n};\nconst data = {\n  current: { container },\n  next: { container },\n};\n\nbarba.use(css);\nbarba.init({\n  transitions: [named, unnamed],\n});\n\nit('prefixes with transition name', async () => {\n  await barba.hooks.do('before', data, named);\n  expect(css.prefix).toBe(name);\n  css.prefix = null;\n  await barba.hooks.do('beforeOnce', data, named);\n  expect(css.prefix).toBe(name);\n});\n\nit('prefixes with default', async () => {\n  await barba.hooks.do('before', data, unnamed);\n  expect(css.prefix).toBe('barba');\n  css.prefix = null;\n  await barba.hooks.do('beforeOnce', data, unnamed);\n  expect(css.prefix).toBe('barba');\n});\n\n// DEV\n// it('adds and removes default CSS classes', async () => {\n//   barba.hooks.do('beforeOnce', {}, unnamed);\n//   await checkHooks();\n// });\n\n// it('adds and removes named CSS classes', async () => {\n//   barba.hooks.do('beforeOnce', {}, named);\n//   await checkHooks(name);\n// });\n"
  },
  {
    "path": "packages/css/__tests__/css.states.test.ts",
    "content": "/* tslint:disable:no-string-literal */\nimport barba from '@barba/core/src';\nimport css from '../src';\n\n// Dom\nconst container = document.createElement('div');\nconst kind = 'test';\n\ncss.install(barba);\ncss.add = jest.fn();\ncss.remove = jest.fn();\n\ncontainer.addEventListener = jest.fn();\ncontainer.removeEventListener = jest.fn();\n\nit('do start', async () => {\n  await css.start(container, kind);\n\n  expect(css.add).toHaveBeenNthCalledWith(1, container, kind);\n  expect(css.add).toHaveBeenNthCalledWith(2, container, `${kind}-active`);\n});\n\nit('do next', async () => {\n  css['_checkTransition'] = jest.fn().mockReturnValue(true);\n  css.next(container, kind);\n\n  expect.assertions(4);\n  expect(css.callbacks[kind]).toBeDefined();\n  expect(container.addEventListener).toHaveBeenCalledTimes(1);\n\n  await barba.helpers.nextTick();\n\n  expect(css.remove).toHaveBeenNthCalledWith(1, container, kind);\n  expect(css.add).toHaveBeenCalledTimes(1);\n  // DEV not working?!??\n  // expect(css.add).toHaveBeenNthCalledWith(2, container, `${kind}-to`);\n});\n\nit('do end', async () => {\n  await css.end(container, kind);\n\n  expect(css.remove).toHaveBeenNthCalledWith(1, container, `${kind}-to`);\n  expect(css.remove).toHaveBeenNthCalledWith(2, container, `${kind}-active`);\n  expect(container.removeEventListener).toHaveBeenCalledTimes(1);\n});\n\nit('do next with no CSS transition', async () => {\n  css['_checkTransition'] = jest.fn().mockReturnValue(false);\n  await css.next(container, kind);\n\n  expect(css.remove).toHaveBeenNthCalledWith(1, container, kind);\n  expect(css.add).toHaveBeenNthCalledWith(1, container, `${kind}-to`);\n  expect(container.removeEventListener).toHaveBeenCalledTimes(0);\n});\n"
  },
  {
    "path": "packages/css/__web__/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n    <title>home</title>\n    <link rel=\"stylesheet\" href=\"styles/default.css\" />\n  </head>\n  <body>\n    <div data-barba=\"wrapper\" data-test-wrapper=\"current\">\n      <div\n        data-barba=\"container\"\n        data-barba-namespace=\"home\"\n        data-test-container=\"current\"\n      >\n        <h1 data-test=\"title\">home</h1>\n        <a data-test=\"link\" href=\"page.html\">Go to page</a>\n      </div>\n    </div>\n    <script src=\"../../core/dist/barba.umd.js\"></script>\n    <script src=\"../dist/barba-css.umd.js\"></script>\n    <script src=\"scripts/default.js\" type=\"module\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "packages/css/__web__/named.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n    <title>named</title>\n    <link rel=\"stylesheet\" href=\"styles/named.css\" />\n  </head>\n  <body>\n    <div data-barba=\"wrapper\" data-test-wrapper=\"current\">\n      <div\n        data-barba=\"container\"\n        data-barba-namespace=\"named\"\n        data-test-container=\"current\"\n      >\n        <h1 data-test=\"title\">named</h1>\n        <a data-test=\"link\" href=\"page.html\">Go to page</a>\n      </div>\n    </div>\n    <script src=\"../../core/dist/barba.umd.js\"></script>\n    <script src=\"../dist/barba-css.umd.js\"></script>\n    <script src=\"scripts/named.js\" type=\"module\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "packages/css/__web__/once.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n  <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n  <title>once</title>\n  <link rel=\"stylesheet\" href=\"styles/once.css\" />\n</head>\n\n<body>\n  <div data-barba=\"wrapper\" data-test-wrapper=\"current\">\n    <div data-barba=\"container\" data-barba-namespace=\"once\" data-test-container=\"current\">\n      <h1 data-test=\"title\">once</h1>\n      <a data-test=\"link\" href=\"page.html\">Go to page</a>\n    </div>\n  </div>\n  <script src=\"../../core/dist/barba.umd.js\"></script>\n  <script src=\"../dist/barba-css.umd.js\"></script>\n  <script src=\"scripts/default.js\" type=\"module\"></script>\n</body>\n\n</html>\n"
  },
  {
    "path": "packages/css/__web__/page.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n    <title>page</title>\n  </head>\n  <body>\n    <div data-barba=\"wrapper\" data-test-wrapper=\"next\">\n      <div\n        data-barba=\"container\"\n        data-barba-namespace=\"page\"\n        data-test-container=\"next\"\n      >\n        <h1 data-test=\"title\">page</h1>\n        <a data-test=\"link\" href=\"index.html\">Go to home</a>\n      </div>\n    </div>\n  </body>\n</html>\n"
  },
  {
    "path": "packages/css/__web__/scripts/default.js",
    "content": "console.info('🚀 Barba e2e');\n\nconst { barba, barbaCss: css } = window;\n\nbarba.use(css);\nbarba.init({ debug: true });\n"
  },
  {
    "path": "packages/css/__web__/scripts/named.js",
    "content": "console.info('🚀 Barba e2e');\n\nconst { barba, barbaCss: css } = window;\n\nbarba.use(css);\nbarba.init({\n  transitions: [{ name: 'named' }],\n});\n"
  },
  {
    "path": "packages/css/__web__/styles/default.css",
    "content": "[data-barba='container'] {\n  opacity: 1;\n}\n\n.barba-enter-active,\n.barba-leave-active {\n  transition: opacity 2s;\n}\n\n.barba-leave,\n.barba-enter-to {\n  opacity: 1;\n}\n\n.barba-enter,\n.barba-leave-to {\n  opacity: 0;\n}\n"
  },
  {
    "path": "packages/css/__web__/styles/named.css",
    "content": "[data-barba='container'] {\n  opacity: 1;\n}\n\n.named-enter-active,\n.named-leave-active {\n  transition: opacity 2s;\n}\n\n.named-leave,\n.named-enter-to {\n  opacity: 1;\n}\n\n.named-enter,\n.named-leave-to {\n  opacity: 0;\n}\n"
  },
  {
    "path": "packages/css/__web__/styles/once.css",
    "content": "[data-barba='container'] {\n  opacity: 1;\n}\n\n.barba-once {\n  opacity: 0;\n}\n\n.barba-once-active {\n  transition: opacity 5s;\n}\n\n.barba-once-to {\n  opacity: 1;\n}\n"
  },
  {
    "path": "packages/css/jest.config.js",
    "content": "const jestBase = require('../../jest.config.js');\n\nmodule.exports = {\n  ...jestBase,\n};\n"
  },
  {
    "path": "packages/css/package.json",
    "content": "{\n  \"name\": \"@barba/css\",\n  \"version\": \"2.1.16\",\n  \"description\": \"Style helper that manage you CSS classes during transitions\",\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"main\": \"dist/barba-css.js\",\n  \"umd:main\": \"dist/barba-css.umd.js\",\n  \"browser\": \"dist/barba-css.umd.js\",\n  \"unpkg\": \"dist/barba-css.umd.js\",\n  \"module\": \"dist/barba-css.mjs\",\n  \"source\": \"src/index.ts\",\n  \"types\": \"dist/css/src/typings\",\n  \"mangle\": {\n    \"regex\": \"^_\"\n  },\n  \"files\": [\n    \"dist\"\n  ],\n  \"keywords\": [\n    \"page\",\n    \"transition\",\n    \"animation\",\n    \"css\",\n    \"router\",\n    \"prefetch\"\n  ],\n  \"homepage\": \"https://github.com/barbajs/barba#readme\",\n  \"bugs\": {\n    \"url\": \"https://github.com/barbajs/barba/issues\"\n  },\n  \"license\": \"MIT\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+ssh://git@github.com/barbajs/barba.git\"\n  },\n  \"scripts\": {\n    \"build\": \"microbundle --name barbaCss\",\n    \"build:watch\": \"microbundle watch --name barbaCss\",\n    \"clear\": \"rimraf dist\",\n    \"lint\": \"tslint src/**\",\n    \"precommit\": \"lint-staged\",\n    \"size\": \"echo '💄 css' && gzip-size ./dist/barba-css.umd.js\",\n    \"tag:latest\": \"npm dist-tag add @barba/css@$npm_package_version latest\",\n    \"tag:next\": \"npm dist-tag add @barba/css@$npm_package_version next\"\n  },\n  \"gitHead\": \"33c213bc36a0996f6333185dfc695fcd0d37c9d9\"\n}\n"
  },
  {
    "path": "packages/css/src/css.ts",
    "content": "/**\n * @barba/css\n * <br><br>\n * ## Barba CSS.\n *\n * - Add CSS classes\n * - Manage CSS transitions\n *\n * @module css\n * @preferred\n */\n\n/***/\n\n// Definitions\nimport {\n  IBarbaPlugin,\n  ITransitionData,\n  ITransitionPage,\n} from '@barba/core/src/defs';\n\nimport { Core } from '@barba/core/src/core';\nimport { Logger } from '@barba/core/src/modules/Logger';\n\nimport { ICssCallbacks } from './defs';\n\nimport { version } from '../package.json';\n\nexport class Css implements IBarbaPlugin<{}> {\n  public name = '@barba/css';\n  public version = version;\n  public barba: Core;\n  public logger: Logger;\n\n  public prefix: string = 'barba';\n  public callbacks: ICssCallbacks = {};\n  public cb: any;\n\n  // Check if transition property applied\n  private _hasTransition: boolean = false;\n\n  /**\n   * Plugin installation.\n   */\n  public install(barba: Core) {\n    this.logger = new barba.Logger(this.name);\n    this.logger.info(this.version);\n    this.barba = barba;\n    this._once = this._once.bind(this);\n    this._leave = this._leave.bind(this);\n    this._enter = this._enter.bind(this);\n  }\n\n  /**\n   * Plugin installation.\n   */\n  public init() {\n    // Register hooks to get prefix\n    this.barba.hooks.before(this._getPrefix, this);\n    this.barba.hooks.beforeOnce(this._getPrefix, this);\n\n    // Register hook for CSS classes\n    this.barba.hooks.beforeOnce(this._beforeOnce, this);\n    this.barba.hooks.afterOnce(this._afterOnce, this);\n    this.barba.hooks.beforeLeave(this._beforeLeave, this);\n    this.barba.hooks.afterLeave(this._afterLeave, this);\n    this.barba.hooks.beforeEnter(this._beforeEnter, this);\n    this.barba.hooks.afterEnter(this._afterEnter, this);\n\n    // Override main transitions\n    this.barba.transitions.once = this._once;\n    this.barba.transitions.leave = this._leave;\n    this.barba.transitions.enter = this._enter;\n\n    // Add empty default transition (force prepend)\n    /* istanbul ignore next */\n    this.barba.transitions.store.all.unshift({\n      name: 'barba',\n      once() {}, // tslint:disable-line:no-empty\n      leave() {}, // tslint:disable-line:no-empty\n      enter() {}, // tslint:disable-line:no-empty\n    });\n    this.barba.transitions.store.update();\n  }\n\n  /**\n   * Initial state.\n   */\n  public async start(container: HTMLElement, kind: string): Promise<void> {\n    // Set initial CSS values\n    this.add(container, kind); // CSS: add kind\n    await this.barba.helpers.nextTick();\n    // Apply CSS transition\n    this.add(container, `${kind}-active`); // CSS: add kind-active\n    await this.barba.helpers.nextTick();\n  }\n\n  /**\n   * Next frame state.\n   */\n  public async next(container: HTMLElement, kind: string): Promise<any> {\n    this._hasTransition = this._checkTransition(container);\n\n    if (this._hasTransition) {\n      // We need to listen the end of the animation\n      return new Promise(async resolve => {\n        this.cb = resolve;\n        this.callbacks[kind] = resolve;\n\n        container.addEventListener('transitionend', resolve, false);\n        this.remove(container, kind); // CSS: remove kind\n        await this.barba.helpers.nextTick();\n        this.add(container, `${kind}-to`); // CSS: add kind-to\n        await this.barba.helpers.nextTick();\n      });\n    } else {\n      this.remove(container, kind); // CSS: remove kind\n      await this.barba.helpers.nextTick();\n      this.add(container, `${kind}-to`); // CSS: add kind-to\n      await this.barba.helpers.nextTick();\n    }\n  }\n\n  /**\n   * Final state.\n   */\n  public async end(container: HTMLElement, kind: string): Promise<void> {\n    this.remove(container, `${kind}-to`); // CSS: remove kind-to\n    this.remove(container, `${kind}-active`); // CSS: remove kind-active\n    container.removeEventListener('transitionend', this.callbacks[kind]);\n    this._hasTransition = false;\n  }\n\n  /**\n   * Add CSS classes.\n   */\n  public add(el: HTMLElement, step: string): void {\n    el.classList.add(`${this.prefix}-${step}`);\n  }\n\n  /**\n   * Remove CSS classes.\n   */\n  public remove(el: HTMLElement, step: string): void {\n    el.classList.remove(`${this.prefix}-${step}`);\n  }\n\n  /**\n   * Get CSS prefix from transition `name` property.\n   */\n  private _getPrefix(data: ITransitionData, t: ITransitionPage): void {\n    this.prefix = t.name || 'barba';\n  }\n\n  /**\n   * Check if CSS transition is applied\n   */\n  private _checkTransition(container: HTMLElement) {\n    // DEV: check for CSS animation property?\n    return getComputedStyle(container).transitionDuration !== '0s';\n  }\n\n  /**\n   * `beforeOnce` hook.\n   */\n  private _beforeOnce(data: ITransitionData): Promise<void> {\n    return this.start(data.next.container, 'once');\n  }\n\n  /**\n   * `once` hook.\n   */\n  private async _once(\n    data: ITransitionData,\n    t: ITransitionPage\n  ): Promise<any> {\n    await this.barba.hooks.do('once', data, t);\n\n    return this.next(data.next.container, 'once');\n  }\n\n  /**\n   * `afterOnce` hook.\n   */\n  private _afterOnce(data: ITransitionData): Promise<void> {\n    return this.end(data.next.container, 'once');\n  }\n\n  /**\n   * `beforeLeave` hook.\n   */\n  private _beforeLeave(data: ITransitionData): Promise<void> {\n    return this.start(data.current.container, 'leave');\n  }\n\n  /**\n   * `leave` hook.\n   */\n  private async _leave(\n    data: ITransitionData,\n    t: ITransitionPage\n  ): Promise<void> {\n    await this.barba.hooks.do('leave', data, t);\n\n    return this.next(data.current.container, 'leave');\n  }\n\n  /**\n   * `afterLeave` hook.\n   */\n  private _afterLeave(data: ITransitionData): Promise<void> {\n    this.end(data.current.container, 'leave');\n    // For CSS transitions, we need to remove current container\n    // directly after the leave transition\n    this.barba.transitions.remove(data);\n\n    return Promise.resolve();\n  }\n\n  /**\n   * `beforeEnter` hook.\n   */\n  private _beforeEnter(data: ITransitionData): Promise<void> {\n    return this.start(data.next.container, 'enter');\n  }\n\n  /**\n   * `enter` hook.\n   */\n  private async _enter(\n    data: ITransitionData,\n    t: ITransitionPage\n  ): Promise<void> {\n    await this.barba.hooks.do('enter', data, t);\n\n    return this.next(data.next.container, 'enter');\n  }\n\n  /**\n   * `afterEnter` hook.\n   */\n  private _afterEnter(data: ITransitionData): Promise<void> {\n    return this.end(data.next.container, 'enter');\n  }\n}\n\nconst css = new Css();\n\nexport default css;\n"
  },
  {
    "path": "packages/css/src/defs/index.ts",
    "content": "/**\n * @module typings/css\n */\n\ntype CssKinds = 'once' | 'leave' | 'enter';\nexport interface ICssCallbacks {\n  [key: string]: EventListenerOrEventListenerObject;\n}\n"
  },
  {
    "path": "packages/css/src/index.ts",
    "content": "import * as t from './typings';\nexport { default } from './css';\n"
  },
  {
    "path": "packages/css/src/typings.ts",
    "content": "export * from './defs';\nexport { default } from './css';\n"
  },
  {
    "path": "packages/prefetch/.npmignore",
    "content": "### Custom ###\n/__e2e__\n/__mocks__\n/__tests__\n/__web__\n/jest.config.js\n/mangle.json\n/*.md\n/.rts2*\n!/README.md\n!/CHANGELOG.md\n"
  },
  {
    "path": "packages/prefetch/AUTHORS",
    "content": "Luigi De Rosa <lurukee@gmail.com> (https://luruke.com/)\nThierry Michel <thmichel@gmail.com> (https://www.epic.net/)\nXavier Foucrier <xavier.foucrier@gmail.com> (https://xavierfoucrier.dev/)\n"
  },
  {
    "path": "packages/prefetch/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n# [2.2.0](https://github.com/barbajs/barba/compare/@barba/prefetch@2.1.10...@barba/prefetch@2.2.0) (2024-05-10)\n\n### Bug Fixes\n\n- **prefetch:** :bug: fix missing request headers argument ([56aae92](https://github.com/barbajs/barba/commit/56aae920b1b5d08c221ff136d905aee03bf0b249))\n- **prefetch:** :bug: prevent prefetch plugin to cache relative URLs ([4f7ba02](https://github.com/barbajs/barba/commit/4f7ba028be7024dde39be96c1888e561265d9187))\n\n### Features\n\n- **prefetch:** :sparkles: add `limit` option to `IPrefetchOptions` interface ([28460cb](https://github.com/barbajs/barba/commit/28460cb37a028d480e7949a810eae85c37a3da7d))\n- **prefetch:** :sparkles: limit links to prefetch ([1288029](https://github.com/barbajs/barba/commit/1288029116089d88d7041c82673f36d226640c33))\n\n## [2.1.10](https://github.com/barbajs/barba/compare/@barba/prefetch@2.1.9...@barba/prefetch@2.1.10) (2019-11-25)\n\n### Bug Fixes\n\n- **root:** :art: improve typings for TS ([48f0637](https://github.com/barbajs/barba/commit/48f0637))\n\n## [2.1.9](https://github.com/barbajs/barba/compare/@barba/prefetch@2.1.8...@barba/prefetch@2.1.9) (2019-11-25)\n\n**Note:** Version bump only for package @barba/prefetch\n\n## [2.1.8](https://github.com/barbajs/barba/compare/@barba/prefetch@2.1.7...@barba/prefetch@2.1.8) (2019-11-05)\n\n**Note:** Version bump only for package @barba/prefetch\n\n## [2.1.7](https://github.com/barbajs/barba/compare/@barba/prefetch@2.1.6...@barba/prefetch@2.1.7) (2019-10-22)\n\n### Bug Fixes\n\n- **core:** :ambulance: fix URL with query/hash ([f5e639c](https://github.com/barbajs/barba/commit/f5e639c)), closes [#445](https://github.com/barbajs/barba/issues/445)\n\n## [2.1.6](https://github.com/barbajs/barba/compare/@barba/prefetch@2.1.5...@barba/prefetch@2.1.6) (2019-07-16)\n\n### Bug Fixes\n\n- **root:** :mute: remove print version ([be5aa73](https://github.com/barbajs/barba/commit/be5aa73)), closes [#415](https://github.com/barbajs/barba/issues/415)\n\n## [2.1.5](https://github.com/barbajs/barba/compare/@barba/prefetch@2.1.4...@barba/prefetch@2.1.5) (2019-06-26)\n\n### Bug Fixes\n\n- **core:** :ok_hand: improve support of SVG links ([19e7e5d](https://github.com/barbajs/barba/commit/19e7e5d))\n\n## [2.1.4](https://github.com/barbajs/barba/compare/@barba/prefetch@2.1.3...@barba/prefetch@2.1.4) (2019-06-11)\n\n**Note:** Version bump only for package @barba/prefetch\n\n## [2.1.3](https://github.com/barbajs/barba/compare/@barba/prefetch@2.1.2...@barba/prefetch@2.1.3) (2019-04-29)\n\n**Note:** Version bump only for package @barba/prefetch\n\n## [2.1.2](https://github.com/barbajs/barba/compare/@barba/prefetch@2.1.1...@barba/prefetch@2.1.2) (2019-04-13)\n\n### Bug Fixes\n\n- **prefetch:** :loud_sound: print version ([a5beae3](https://github.com/barbajs/barba/commit/a5beae3))\n\n### Reverts\n\n- **root:** :bug: revert failed release ([2b8a1ef](https://github.com/barbajs/barba/commit/2b8a1ef))\n\n## [2.1.2](https://github.com/barbajs/barba/compare/@barba/prefetch@2.1.1...@barba/prefetch@2.1.2) (2019-04-13)\n\n### Bug Fixes\n\n- **prefetch:** :loud_sound: print version ([a5beae3](https://github.com/barbajs/barba/commit/a5beae3))\n\n## [2.1.1](https://github.com/barbajs/barba/compare/@barba/prefetch@2.1.0...@barba/prefetch@2.1.1) (2019-04-13)\n\n### Bug Fixes\n\n- **core:** :bug: fix sameUrl + anchors ([039f5d9](https://github.com/barbajs/barba/commit/039f5d9)), closes [#359](https://github.com/barbajs/barba/issues/359)\n- **core:** :bug: fix timeout error ([70b7805](https://github.com/barbajs/barba/commit/70b7805)), closes [#373](https://github.com/barbajs/barba/issues/373)\n- **prefetch:** :bug: fix wrong/missing context + catch error ([7220126](https://github.com/barbajs/barba/commit/7220126))\n\n# 2.1.0 (2019-03-17)\n\n### Bug Fixes\n\n- **prefetch:** :bug: fix check error ([f12a441](https://github.com/barbajs/barba/commit/f12a441))\n\n### Features\n\n- **prefetch:** :sparkles: add prefetch + refactor e2e scripts ([c90b85b](https://github.com/barbajs/barba/commit/c90b85b))\n- **root:** :sparkles: add logger + fixes ([6db3875](https://github.com/barbajs/barba/commit/6db3875))\n"
  },
  {
    "path": "packages/prefetch/LICENSE",
    "content": "MIT License\n\nCopyright (c) 2024 Luigi De Rosa, Thierry Michel, Xavier Foucrier\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 all\ncopies 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 THE\nSOFTWARE.\n"
  },
  {
    "path": "packages/prefetch/README.md",
    "content": "# @barba/prefetch\n\n[![NPM version](https://img.shields.io/npm/v/@barba/prefetch?style=flat-square)](https://www.npmjs.com/package/@barba/prefetch)\n[![Dependencies](https://img.shields.io/librariesio/release/npm/@barba/prefetch?style=flat-square)](https://github.com/barbajs/barba/network/dependencies)\n\n> TBD ([GitHub repo](https://github.com/barbajs/barba.js))\n\n## Install\n\nUsing npm:\n\n```sh\nnpm install --save-dev @barba/prefetch\n```\n\nor using yarn:\n\n```sh\nyarn add @barba/prefetch --dev\n```\n"
  },
  {
    "path": "packages/prefetch/__e2e__/prefetch.spec.js",
    "content": "describe('page', () => {\n  it('Page is visible', () => {\n    cy.visit('/');\n    expect(true).to.equal(true);\n  });\n});\n"
  },
  {
    "path": "packages/prefetch/__tests__/prefetch.init.test.ts",
    "content": "/* tslint:disable:no-empty */\nimport barba from '@barba/core/src';\nimport { version } from '../package.json';\nimport prefetch from '../src';\n\nconst wrapper = document.createElement('div');\nconst container = document.createElement('div');\n\nwrapper.dataset.barba = 'wrapper';\ncontainer.dataset.barba = 'container';\n\ndocument.body.appendChild(wrapper);\ndocument.body.appendChild(container);\n\n// https://stackoverflow.com/questions/40743131/how-to-prevent-property-does-not-exist-on-type-global-with-jsdom-and-t\n(global as any).IntersectionObserver = class {\n  public observe() {}\n  public unobserve() {}\n};\n(global as any).window.requestIdleCallback = jest.fn();\n\nit('has defaults', () => {\n  expect(prefetch.name).toBe('@barba/prefetch');\n  expect(prefetch.version).toBe(version);\n});\n\nit('init with defaults', () => {\n  prefetch.observe = jest.fn();\n  barba.use(prefetch);\n  barba.init();\n\n  expect(prefetch.root).toBe(document.body);\n  expect(prefetch.timeout).toBe(2e3);\n  expect(prefetch.limit).toBe(0);\n  expect(prefetch.observe).toHaveBeenCalled();\n});\n\nit('init with options', () => {\n  prefetch.observe = jest.fn();\n  barba.destroy();\n  barba.use(prefetch, {\n    limit: 0,\n    root: wrapper,\n    timeout: 0,\n  });\n  barba.init();\n\n  expect(prefetch.root).toBe(wrapper);\n  expect(prefetch.timeout).toBe(0);\n  expect(prefetch.limit).toBe(0);\n});\n\nit('registers hooks', () => {\n  expect(barba.hooks.registered.has('after')).toBeTruthy();\n});\n\nit('warns with cache/prefetch disabled', () => {\n  global.console.warn = jest.fn();\n  barba.use(prefetch);\n  barba.init({\n    cacheIgnore: false,\n    debug: true,\n    prefetchIgnore: true,\n  });\n\n  expect(global.console.warn).toHaveBeenCalledWith(\n    '[@barba/prefetch] ',\n    'barba.prefetchIgnore is enabled'\n  );\n\n  barba.init({\n    cacheIgnore: true,\n    debug: true,\n    prefetchIgnore: false,\n  });\n\n  expect(global.console.warn).toHaveBeenCalledWith(\n    '[@barba/prefetch] ',\n    'barba.cacheIgnore is enabled'\n  );\n});\n"
  },
  {
    "path": "packages/prefetch/__web__/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <title>Test</title>\n  </head>\n  <body>\n    <h1>Hello prefetch</h1>\n  </body>\n</html>\n"
  },
  {
    "path": "packages/prefetch/jest.config.js",
    "content": "const jestBase = require('../../jest.config.js');\n\nmodule.exports = {\n  ...jestBase,\n};\n"
  },
  {
    "path": "packages/prefetch/package.json",
    "content": "{\n  \"name\": \"@barba/prefetch\",\n  \"version\": \"2.2.0\",\n  \"description\": \"Automatically fetch and cache your pages based on the viewport\",\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"main\": \"dist/barba-prefetch.js\",\n  \"umd:main\": \"dist/barba-prefetch.umd.js\",\n  \"browser\": \"dist/barba-prefetch.umd.js\",\n  \"unpkg\": \"dist/barba-prefetch.umd.js\",\n  \"module\": \"dist/barba-prefetch.mjs\",\n  \"source\": \"src/index.ts\",\n  \"types\": \"dist/prefetch/src/typings\",\n  \"mangle\": {\n    \"regex\": \"^_\"\n  },\n  \"files\": [\n    \"dist\"\n  ],\n  \"keywords\": [\n    \"page\",\n    \"transition\",\n    \"animation\",\n    \"css\",\n    \"router\",\n    \"prefetch\"\n  ],\n  \"homepage\": \"https://github.com/barbajs/barba#readme\",\n  \"bugs\": {\n    \"url\": \"https://github.com/barbajs/barba/issues\"\n  },\n  \"license\": \"MIT\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+ssh://git@github.com/barbajs/barba.git\"\n  },\n  \"scripts\": {\n    \"build\": \"microbundle --name barbaPrefetch\",\n    \"build:watch\": \"microbundle watch --name barbaPrefetch\",\n    \"clear\": \"rimraf dist\",\n    \"lint\": \"tslint src/**\",\n    \"precommit\": \"lint-staged\",\n    \"report\": \"source-map-explorer --html ./dist/barba-prefetch.umd.js > report.html\",\n    \"size\": \"echo '🚀 prefetch' && gzip-size ./dist/barba-prefetch.umd.js\",\n    \"tag:latest\": \"npm dist-tag add @barba/prefetch@$npm_package_version latest\",\n    \"tag:next\": \"npm dist-tag add @barba/prefetch@$npm_package_version next\"\n  },\n  \"gitHead\": \"33c213bc36a0996f6333185dfc695fcd0d37c9d9\"\n}\n"
  },
  {
    "path": "packages/prefetch/src/defs/index.ts",
    "content": "/**\n * @module typings/prefetch\n */\n\nexport interface IPrefetchOptions {\n  root?: HTMLElement | HTMLDocument;\n  timeout?: number;\n  limit?: number;\n}\n"
  },
  {
    "path": "packages/prefetch/src/index.ts",
    "content": "import * as t from './typings';\nexport { default } from './prefetch';\n"
  },
  {
    "path": "packages/prefetch/src/polyfills/index.ts",
    "content": "// Browser support + polyfills\n// if (window.NodeList && !NodeList.prototype.forEach) {\n//   NodeList.prototype.forEach = Array.prototype.forEach;\n// }\n\nexport * from './requestIdleCallback';\n"
  },
  {
    "path": "packages/prefetch/src/polyfills/requestIdleCallback.ts",
    "content": "/**\n * @module prefetch/polyfills\n */\n/**\n * Copyright 2018 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// [source](https://github.com/GoogleChromeLabs/quicklink/blob/master/src/request-idle-callback.mjs)\n// RIC and shim for browsers setTimeout() without it\nexport const requestIdleCallback =\n  // @ts-ignore\n  window.requestIdleCallback ||\n  function ric(cb: any) {\n    const start = Date.now();\n\n    return setTimeout(() => {\n      cb({\n        didTimeout: false,\n        timeRemaining: function timeRemaining() {\n          return Math.max(0, 50 - (Date.now() - start));\n        },\n      });\n    }, 1);\n  };\n"
  },
  {
    "path": "packages/prefetch/src/prefetch.ts",
    "content": "/**\n * @barba/prefetch\n * <br><br>\n * ## Barba prefetch.\n *\n * @module prefetch\n * @preferred\n */\n\nimport { IPrefetchOptions } from './defs';\n\n/***/\n\n// Definitions\nimport { Core } from '@barba/core/src/core';\nimport { IBarbaPlugin, Link } from '@barba/core/src/defs';\nimport { Logger } from '@barba/core/src/modules/Logger';\n\nimport { version } from '../package.json';\nimport { requestIdleCallback } from './polyfills';\n\nclass Prefetch implements IBarbaPlugin<IPrefetchOptions> {\n  public name = '@barba/prefetch';\n  public version = version;\n  public barba: Core;\n  public logger: Logger;\n\n  public observer: IntersectionObserver;\n  public root: HTMLElement | HTMLDocument;\n  public timeout: number;\n  public limit: number;\n  public toPrefetch: Set<string> = new Set();\n\n  /**\n   * Plugin installation.\n   */\n  public install(\n    barba: Core,\n    { root = document.body, timeout = 2e3, limit = 0 }: IPrefetchOptions = {}\n  ) {\n    this.logger = new barba.Logger(this.name);\n    this.logger.info(this.version);\n    this.barba = barba;\n    this.root = root;\n    this.timeout = timeout;\n    this.limit = limit;\n  }\n\n  /**\n   * Plugin initialisation.\n   */\n  public init() {\n    if (this.barba.prefetchIgnore) {\n      this.logger.warn('barba.prefetchIgnore is enabled');\n\n      return;\n    }\n    if (this.barba.cacheIgnore) {\n      this.logger.warn('barba.cacheIgnore is enabled');\n\n      return;\n    }\n\n    /**\n     * Init intersection observer\n     * when intersecting, it will check if URL should be prefetched\n     * then unobserve the element\n     * and, if no cache data, fetch the page\n     */\n    /* istanbul ignore next */\n    this.observer = new IntersectionObserver(entries => {\n      entries.forEach(entry => {\n        if (!entry.isIntersecting) {\n          return;\n        }\n\n        const link = entry.target as Link;\n        const href = this.barba.url.getAbsoluteHref(this.barba.dom.getHref(link));\n\n        if (!this.toPrefetch.has(href)) {\n          return;\n        }\n\n        this.observer.unobserve(link);\n\n        // Prefetch and cache\n        if (!this.barba.cache.has(href)) {\n          this.barba.cache.set(\n            href,\n            this.barba\n              .request(\n                href,\n                this.barba.timeout,\n                this.barba['onRequestError'].bind(this.barba, 'barba'), // tslint:disable-line:no-string-literal\n                this.barba.cache,\n                this.barba.headers\n              )\n              .catch(error => {\n                this.logger.error(error);\n              }),\n            'prefetch',\n            'pending'\n          );\n        } else {\n          this.barba.cache.update(href, { action: 'prefetch' });\n        }\n      });\n    });\n    this.observe();\n\n    // Register hooks\n    this.barba.hooks.after(this.observe, this);\n  }\n\n  /* istanbul ignore next */\n  public observe(): void {\n    const timeout = this.timeout;\n\n    requestIdleCallback(\n      () => {\n        let links = Array.from(this.root.querySelectorAll('a'));\n\n        if (this.limit > 0) {\n          links = links.slice(0, this.limit);\n        }\n\n        // If not, find all links and use IntersectionObserver.\n        links.forEach(el => {\n          const link = (el as unknown) as Link;\n          const href = this.barba.dom.getHref(link);\n\n          if (\n            !this.barba.cache.has(href) &&\n            !this.barba.prevent.checkHref(href) &&\n            !this.barba.prevent.checkLink(link, {} as Event, href)\n          ) {\n            this.observer.observe(el);\n            this.toPrefetch.add(href);\n          }\n        });\n      },\n      { timeout }\n    );\n  }\n}\n\nconst prefetch = new Prefetch();\n\nexport default prefetch;\n"
  },
  {
    "path": "packages/prefetch/src/typings.ts",
    "content": "export * from './defs';\nexport { default } from './prefetch';\n"
  },
  {
    "path": "packages/router/.npmignore",
    "content": "### Custom ###\n/__e2e__\n/__mocks__\n/__tests__\n/__web__\n/jest.config.js\n/mangle.json\n/*.md\n/.rts2*\n!/README.md\n!/CHANGELOG.md\n"
  },
  {
    "path": "packages/router/AUTHORS",
    "content": "Luigi De Rosa <lurukee@gmail.com> (https://luruke.com/)\nThierry Michel <thmichel@gmail.com> (https://www.epic.net/)\nXavier Foucrier <xavier.foucrier@gmail.com> (https://xavierfoucrier.dev/)\n"
  },
  {
    "path": "packages/router/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n## [2.1.11](https://github.com/barbajs/barba/compare/@barba/router@2.1.10...@barba/router@2.1.11) (2024-05-10)\n\n**Note:** Version bump only for package @barba/router\n\n## [2.1.10](https://github.com/barbajs/barba/compare/@barba/router@2.1.9...@barba/router@2.1.10) (2019-12-12)\n\n**Note:** Version bump only for package @barba/router\n\n## [2.1.9](https://github.com/barbajs/barba/compare/@barba/router@2.1.8...@barba/router@2.1.9) (2019-11-25)\n\n### Bug Fixes\n\n- **root:** :art: improve typings for TS ([48f0637](https://github.com/barbajs/barba/commit/48f0637))\n\n## [2.1.8](https://github.com/barbajs/barba/compare/@barba/router@2.1.7...@barba/router@2.1.8) (2019-11-25)\n\n**Note:** Version bump only for package @barba/router\n\n## [2.1.7](https://github.com/barbajs/barba/compare/@barba/router@2.1.6...@barba/router@2.1.7) (2019-11-05)\n\n**Note:** Version bump only for package @barba/router\n\n## [2.1.6](https://github.com/barbajs/barba/compare/@barba/router@2.1.5...@barba/router@2.1.6) (2019-10-22)\n\n**Note:** Version bump only for package @barba/router\n\n## [2.1.5](https://github.com/barbajs/barba/compare/@barba/router@2.1.4...@barba/router@2.1.5) (2019-07-16)\n\n### Bug Fixes\n\n- **root:** :mute: remove print version ([be5aa73](https://github.com/barbajs/barba/commit/be5aa73)), closes [#415](https://github.com/barbajs/barba/issues/415)\n\n## [2.1.4](https://github.com/barbajs/barba/compare/@barba/router@2.1.3...@barba/router@2.1.4) (2019-06-11)\n\n**Note:** Version bump only for package @barba/router\n\n## [2.1.3](https://github.com/barbajs/barba/compare/@barba/router@2.1.2...@barba/router@2.1.3) (2019-04-29)\n\n**Note:** Version bump only for package @barba/router\n\n## [2.1.2](https://github.com/barbajs/barba/compare/@barba/router@2.1.1...@barba/router@2.1.2) (2019-04-13)\n\n### Bug Fixes\n\n- **router:** :loud_sound: print version ([70e9857](https://github.com/barbajs/barba/commit/70e9857))\n\n### Reverts\n\n- **root:** :bug: revert failed release ([2b8a1ef](https://github.com/barbajs/barba/commit/2b8a1ef))\n\n## [2.1.2](https://github.com/barbajs/barba/compare/@barba/router@2.1.1...@barba/router@2.1.2) (2019-04-13)\n\n### Bug Fixes\n\n- **router:** :loud_sound: print version ([70e9857](https://github.com/barbajs/barba/commit/70e9857))\n\n## [2.1.1](https://github.com/barbajs/barba/compare/@barba/router@2.1.0...@barba/router@2.1.1) (2019-04-13)\n\n### Bug Fixes\n\n- **core:** :bug: fix sameUrl + anchors ([039f5d9](https://github.com/barbajs/barba/commit/039f5d9)), closes [#359](https://github.com/barbajs/barba/issues/359)\n\n# 2.1.0 (2019-03-17)\n\n### Bug Fixes\n\n- **root:** :bug: force publish ([ddb8798](https://github.com/barbajs/barba/commit/ddb8798))\n\n### Features\n\n- **core:** :sparkles: add prevent custom + update README ([2fb4ec6](https://github.com/barbajs/barba/commit/2fb4ec6))\n- **router:** :sparkles: add multiple properties to `route` ([4e92c83](https://github.com/barbajs/barba/commit/4e92c83))\n"
  },
  {
    "path": "packages/router/LICENSE",
    "content": "MIT License\n\nCopyright (c) 2024 Luigi De Rosa, Thierry Michel, Xavier Foucrier\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 all\ncopies 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 THE\nSOFTWARE.\n"
  },
  {
    "path": "packages/router/README.md",
    "content": "# @barba/router\n\n[![NPM version](https://img.shields.io/npm/v/@barba/router?style=flat-square)](https://www.npmjs.com/package/@barba/router)\n[![Dependencies](https://img.shields.io/librariesio/release/npm/@barba/router?style=flat-square)](https://github.com/barbajs/barba/network/dependencies)\n\n> TBD ([GitHub repo](https://github.com/barbajs/barba.js))\n\n## Install\n\nUsing npm:\n\n```sh\nnpm install --save-dev @barba/router\n```\n\nor using yarn:\n\n```sh\nyarn add @barba/router --dev\n```\n"
  },
  {
    "path": "packages/router/__e2e__/default.spec.js",
    "content": "/* eslint-disable cypress/no-unnecessary-waiting */\nconst logs = [\n  'leave-from',\n  'enter-from',\n  'leave-default',\n  'enter-default',\n  'leave-to',\n  'enter-to',\n];\n\ndescribe('Route transition', () => {\n  it('works', () => {\n    cy.prepare('/index.html', 'home', 'home');\n    cy.get('[data-test=\"logs-list\"]').as('logs'); // Alias to @hooks\n    cy.wait(1000); // Wait for once complete\n\n    // Click link\n    cy.get('[data-test=link]').click();\n    // Check route \"from\"\n    logs.forEach((name, i) => {\n      if (i < 2) {\n        cy.get('@logs')\n          .find(`:nth-child(${i + 1})`)\n          .should('contain', name);\n      }\n    });\n\n    // Go to default\n    cy.get('[data-test=link2]').click();\n    // Check no route\n    logs.forEach((name, i) => {\n      if (i < 4) {\n        cy.get('@logs')\n          .find(`:nth-child(${i + 1})`)\n          .should('contain', name);\n      }\n    });\n\n    // Back to home\n    cy.get('[data-test=link]').click();\n    // Check route \"to\"\n    logs.forEach((name, i) => {\n      cy.get('@logs')\n        .find(`:nth-child(${i + 1})`)\n        .should('contain', name);\n    });\n\n    // Go to page again, for final check\n    cy.get('[data-test=link]').click();\n    cy.final('/page.html', 'page', 'page');\n  });\n});\n"
  },
  {
    "path": "packages/router/__tests__/router.test.ts",
    "content": "import barba from '@barba/core/src';\n// Definitions\nimport { ITransitionData } from '@barba/core/src/defs';\nimport { version } from '../package.json';\nimport router from '../src';\n\nconst wrapper = document.createElement('div');\nconst container = document.createElement('div');\n\nwrapper.dataset.barba = 'wrapper';\ncontainer.dataset.barba = 'container';\n\ndocument.body.appendChild(wrapper);\ndocument.body.appendChild(container);\n\nconst routes = [\n  {\n    name: 'home',\n    path: '(/|/index.html)',\n  },\n  {\n    name: 'foo',\n    path: '/foo/:bar',\n  },\n];\n\nit('has defaults', () => {\n  expect(router.name).toBe('@barba/router');\n  expect(router.version).toBe(version);\n  expect(router.routeNames).toHaveLength(0);\n  router.install(barba);\n  expect(router.routeNames).toHaveLength(0);\n});\n\nit('has routes', () => {\n  router.install(barba, {\n    routes,\n  });\n\n  expect([...router.routeNames]).toEqual(['home', 'foo']);\n  expect(router.routesByName.foo).toEqual({\n    keys: [\n      {\n        modifier: '',\n        name: 'bar',\n        pattern: '[^\\\\/#\\\\?]+?',\n        prefix: '/',\n        suffix: '',\n      },\n    ],\n    path: '/foo/:bar',\n    regex: /^\\/foo(?:\\/([^\\/#\\?]+?))[\\/#\\?]?$/i,\n  });\n});\n\nit('add rule', () => {\n  barba.init();\n  barba.transitions.store.add = jest.fn();\n\n  router.init();\n\n  expect(barba.transitions.store.add).toHaveBeenCalledTimes(1);\n});\n\nit('has duplicate routes', () => {\n  console.warn = jest.fn();\n\n  router.install(barba, {\n    routes,\n  });\n\n  expect(console.warn).toHaveBeenCalledTimes(2);\n});\n\nit('resolves url', () => {\n  const result = router.resolveUrl('http://localhost/foo/something');\n\n  expect(result.name).toBe('foo');\n  expect(result.params.bar).toBe('something');\n});\n\nit('resolves unknown url', () => {\n  const result = router.resolveUrl('http://localhost/bar/something');\n\n  expect(result).toBeNull();\n});\n\nit('resolves data urls (home)', () => {\n  const data = {\n    current: { url: { href: 'http://localhost/' } },\n    next: { url: { href: 'http://localhost/' } },\n  } as ITransitionData;\n\n  router.resolveRoutes(data);\n\n  expect(data.current.route.name).toBe('home');\n  expect(data.next.route.name).toBe('home');\n});\n\nit('resolves data urls (foo)', () => {\n  const data = {\n    current: { url: { href: 'http://localhost/foo/current' } },\n    next: { url: { href: 'http://localhost/foo/next' } },\n  } as ITransitionData;\n\n  router.resolveRoutes(data);\n\n  expect(data.current.route.name).toBe('foo');\n  expect(data.next.route.name).toBe('foo');\n});\n\nit('resolves unknown data urls', () => {\n  const data = {\n    current: { url: {} },\n    next: { url: {} },\n  } as ITransitionData;\n\n  router.resolveRoutes(data);\n\n  expect(data.current.route).toBeUndefined();\n  expect(data.next.route).toBeUndefined();\n});\n"
  },
  {
    "path": "packages/router/__web__/default.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n  <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n  <title>default</title>\n</head>\n\n<body>\n  <div data-barba=\"wrapper\" data-test-wrapper=\"next\">\n    <div data-barba=\"container\" data-barba-namespace=\"default\" data-test-container=\"next\">\n      <h1 data-test=\"title\">default</h1>\n      <a data-test=\"link\" href=\"index.html\">Go to home</a>\n    </div>\n  </div>\n</body>\n\n</html>\n"
  },
  {
    "path": "packages/router/__web__/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n  <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n  <title>home</title>\n</head>\n\n<body>\n  <div data-barba=\"wrapper\" data-test-wrapper=\"current\">\n    <ol data-test=\"logs-list\"></ol>\n    <div data-barba=\"container\" data-barba-namespace=\"home\" data-test-container=\"current\">\n      <h1 data-test=\"title\">home</h1>\n      <a data-test=\"link\" href=\"page.html\">Go to page</a>\n      <a data-test=\"link2\" href=\"default.html\">Go to default</a>\n    </div>\n  </div>\n  <script src=\"../../core/dist/barba.umd.js\"></script>\n  <script src=\"../dist/barba-router.umd.js\"></script>\n  <script src=\"scripts/default.js\" type=\"module\"></script>\n</body>\n\n</html>\n"
  },
  {
    "path": "packages/router/__web__/page.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n  <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n  <title>page</title>\n</head>\n\n<body>\n  <div data-barba=\"wrapper\" data-test-wrapper=\"next\">\n    <div data-barba=\"container\" data-barba-namespace=\"page\" data-test-container=\"next\">\n      <h1 data-test=\"title\">page</h1>\n      <a data-test=\"link\" href=\"index.html\">Go to home</a>\n      <a data-test=\"link2\" href=\"default.html\">Go to default</a>\n    </div>\n  </div>\n</body>\n\n</html>\n"
  },
  {
    "path": "packages/router/__web__/scripts/default.js",
    "content": "console.info('🚀 Barba e2e');\n\nconst { barba, barbaRouter: router } = window;\n\nconst list = document.querySelector('[data-test=\"logs-list\"]');\nconst routes = [\n  {\n    name: 'home',\n    path: '(/packages/router/__web__/|/packages/router/__web__/index.html)',\n  },\n  { name: 'page', path: '/packages/router/__web__/page.html' },\n];\n\n/**\n * Append list item\n *\n * @param {*} str List item content\n * @param {string} prefix Prefix for global\n * @returns {void}\n */\nfunction append(str, prefix = '') {\n  const item = document.createElement('li');\n\n  item.textContent = prefix + str;\n  list.appendChild(item);\n}\n\nbarba.use(router, {\n  routes,\n});\n\nbarba.init({\n  debug: true,\n  transitions: [\n    {\n      name: 'default',\n      leave: data => {\n        console.info('leave-default', data);\n        append('leave-default');\n\n        return Promise.resolve();\n      },\n      enter: data => {\n        console.info('enter-default', data);\n        append('enter-default');\n\n        return Promise.resolve();\n      },\n    },\n    {\n      name: 'from',\n      from: { route: 'home' },\n      leave: data => {\n        console.info('leave-from', data);\n        append('leave-from');\n\n        return Promise.resolve();\n      },\n      enter: data => {\n        console.info('enter-from', data);\n        append('enter-from');\n\n        return Promise.resolve();\n      },\n    },\n    {\n      name: 'to',\n      to: { route: 'home' },\n      leave: data => {\n        console.info('leave-to', data);\n        append('leave-to');\n\n        return Promise.resolve();\n      },\n      enter: data => {\n        console.info('enter-to', data);\n        append('enter-to');\n\n        return Promise.resolve();\n      },\n    },\n  ],\n});\n"
  },
  {
    "path": "packages/router/jest.config.js",
    "content": "const jestBase = require('../../jest.config.js');\n\nmodule.exports = {\n  ...jestBase,\n};\n"
  },
  {
    "path": "packages/router/package.json",
    "content": "{\n  \"name\": \"@barba/router\",\n  \"version\": \"2.1.11\",\n  \"description\": \"Use custom routes for your page transitions\",\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"main\": \"dist/barba-router.js\",\n  \"umd:main\": \"dist/barba-router.umd.js\",\n  \"browser\": \"dist/barba-router.umd.js\",\n  \"unpkg\": \"dist/barba-router.umd.js\",\n  \"module\": \"dist/barba-router.mjs\",\n  \"source\": \"src/index.ts\",\n  \"types\": \"dist/router/src/typings\",\n  \"mangle\": {\n    \"regex\": \"^_\"\n  },\n  \"files\": [\n    \"dist\"\n  ],\n  \"keywords\": [\n    \"page\",\n    \"transition\",\n    \"animation\",\n    \"css\",\n    \"router\",\n    \"prefetch\"\n  ],\n  \"homepage\": \"https://github.com/barbajs/barba#readme\",\n  \"bugs\": {\n    \"url\": \"https://github.com/barbajs/barba/issues\"\n  },\n  \"license\": \"MIT\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+ssh://git@github.com/barbajs/barba.git\"\n  },\n  \"scripts\": {\n    \"build\": \"microbundle --name barbaRouter --external none\",\n    \"build:watch\": \"microbundle watch --name barbaRouter --external none\",\n    \"clear\": \"rimraf dist\",\n    \"lint\": \"tslint src/**\",\n    \"precommit\": \"lint-staged\",\n    \"size\": \"echo '🚦 router' && gzip-size ./dist/barba-router.umd.js\",\n    \"tag:latest\": \"npm dist-tag add @barba/router@$npm_package_version latest\",\n    \"tag:next\": \"npm dist-tag add @barba/router@$npm_package_version next\"\n  },\n  \"gitHead\": \"33c213bc36a0996f6333185dfc695fcd0d37c9d9\"\n}\n"
  },
  {
    "path": "packages/router/src/defs/index.ts",
    "content": "/**\n * @module typings/router\n */\n\nexport interface IRoute {\n  name: string;\n  path: string;\n}\nexport interface IRouteParsed {\n  path: string;\n  regex: RegExp;\n  keys: any[];\n}\nexport interface IRouteResolved {\n  name: string;\n  params: any;\n}\nexport interface IRouteByName {\n  [key: string]: IRouteParsed;\n}\nexport interface IRouterOptions {\n  routes?: IRoute[];\n}\n"
  },
  {
    "path": "packages/router/src/index.ts",
    "content": "import * as t from './typings';\nexport { default } from './router';\n"
  },
  {
    "path": "packages/router/src/router.ts",
    "content": "/**\n * @barba/router\n * <br><br>\n * ## Barba Router.\n *\n * - Add `route` to Barba transitions resolution\n *\n * @module router\n * @preferred\n */\n\n/***/\n\n// Definitions\nimport { IBarbaPlugin, ITransitionData } from '@barba/core/src/defs';\n\n// Barba/core\nimport { Core } from '@barba/core/src/core';\nimport { Logger } from '@barba/core/src/modules/Logger';\n// Local\nimport { version } from '../package.json';\nimport { IRouteByName, IRouteResolved, IRouterOptions } from './defs';\n\nclass Router implements IBarbaPlugin<IRouterOptions> {\n  public name = '@barba/router';\n  public version = version;\n  public barba: Core;\n  public logger: Logger;\n\n  public routeNames: string[] = [];\n  public routesByName: IRouteByName = {};\n\n  /**\n   * Plugin installation.\n   */\n  public install(barba: Core, { routes = [] }: IRouterOptions = {}) {\n    this.logger = new barba.Logger(this.name);\n    this.logger.info(this.version);\n    this.barba = barba;\n\n    routes.forEach(route => {\n      const { name, path } = route;\n      const keys: any[] = [];\n      const regex = this.barba.helpers.pathToRegexp(path, keys);\n\n      if (this.routeNames.indexOf(name) > -1) {\n        console.warn(`[@barba/router] Duplicated route name (${name})`);\n      } else {\n        this.routeNames.push(name);\n        this.routesByName[name] = {\n          keys,\n          path,\n          regex,\n        };\n      }\n    });\n\n    // Add property to \"pageSchema\" (current, next)\n    barba.schemaPage.route = undefined;\n  }\n\n  /**\n   * Plugin initialisation.\n   */\n  public init() {\n    // Wait for store initialization then add new rule for routes\n    this.barba.transitions.store.add('rule', {\n      position: 1,\n      value: {\n        name: 'route',\n        type: 'object',\n      },\n    });\n    // Register hooks\n    this.barba.hooks.page(this.resolveRoutes, this);\n    this.barba.hooks.reset(this.resolveRoutes, this);\n  }\n\n  /**\n   * Resolve URL to route name.\n   */\n  public resolveUrl(url: string): IRouteResolved | null {\n    const { path } = this.barba.url.parse(url);\n    const output: IRouteResolved = {\n      name: '',\n      params: {},\n    };\n\n    /* tslint:disable:no-shadowed-variable */\n    for (let i = 0, l = this.routeNames.length; i < l; i++) {\n      const name = this.routeNames[i];\n      const { regex, keys } = this.routesByName[name];\n      const res = regex.exec(path);\n\n      if (res !== null) {\n        output.name = name;\n\n        keys.forEach((key, i) => {\n          output.params[key.name] = res[i + 1];\n        });\n\n        return output;\n      }\n    }\n\n    return null;\n  }\n\n  /**\n   * Hooks: do, reset.\n   *\n   * - Update `current` and `next` data\n   */\n  public resolveRoutes(data: ITransitionData): void {\n    const { current, next } = data;\n\n    current.route = current.url.href\n      ? this.resolveUrl(current.url.href)\n      : undefined;\n    next.route = next.url.href ? this.resolveUrl(next.url.href) : undefined;\n  }\n}\n\nconst router = new Router();\n\nexport default router;\n"
  },
  {
    "path": "packages/router/src/typings.ts",
    "content": "export * from './defs';\nexport { default } from './router';\n"
  },
  {
    "path": "prettier.config.js",
    "content": "module.exports = {\n  printWidth: 80,\n  tabWidth: 2,\n  useTabs: false,\n  semi: true,\n  singleQuote: true,\n  trailingComma: 'es5',\n  bracketSpacing: true,\n  arrowParens: 'avoid',\n  overrides: [\n    {\n      files: '*.md',\n      options: {\n        parser: 'markdown',\n      },\n    },\n  ],\n};\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"resolveJsonModule\": true,\n    \"strict\": true,\n    \"strictNullChecks\": false,\n    \"useUnknownInCatchVariables\": false,\n    \"esModuleInterop\": true,\n    \"target\": \"es5\",\n    \"plugins\": [\n      {\n        \"name\": \"typescript-tslint-plugin\",\n        \"alwaysShowRuleFailuresAsWarnings\": false,\n        \"ignoreDefinitionFiles\": true,\n        \"configFile\": \"./tslint.json\",\n        \"suppressWhileTypeErrorsPresent\": false,\n        \"mockTypeScriptVersion\": false\n      }\n    ]\n  },\n  \"exclude\": [\n    \"node_modules\",\n    \"**/__*__/**/*\",\n    \"**/polyfills/index.d.ts\",\n    \"./cypress.config.ts\"\n  ]\n}\n"
  },
  {
    "path": "tslint.json",
    "content": "{\n  \"defaultSeverity\": \"error\",\n  \"extends\": [\"tslint:recommended\"],\n  \"jsRules\": {},\n  \"rules\": {\n    \"arrow-parens\": [true, \"ban-single-arg-parens\"],\n    \"max-line-length\": [true, 120],\n    \"no-console\": [false],\n    \"no-unused-expression\": [true, \"allow-fast-null-checks\"],\n    \"quotemark\": [true, \"single\"],\n    \"variable-name\": [\n      true,\n      \"ban-keywords\",\n      \"check-format\",\n      \"allow-leading-underscore\"\n    ],\n\n    \"trailing-comma\": [false]\n  },\n  \"rulesDirectory\": []\n}\n"
  },
  {
    "path": "typedoc.json",
    "content": "{\n  \"extends\": \"./tsconfig\",\n  \"compilerOptions\": {\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"node\",\n    \"skipLibCheck\": true\n  },\n  \"typedocOptions\": {\n    \"exclude\": \"**/index.ts\",\n    \"excludeExternals\": true,\n    \"ignoreCompilerErrors\": true,\n    \"name\": \"barba.js\",\n    \"readme\": \"README.md\",\n    \"out\": \"documentation/api\",\n    \"theme\": \"documentation/theme\"\n  }\n}\n"
  }
]