-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path.eslintcache
1 lines (1 loc) · 496 KB
/
.eslintcache
1
[{"/home/aureen/the_odin_project/room_homepage/src/firebase/firebase.js":"1","/home/aureen/the_odin_project/room_homepage/src/utils/utils.js":"2","/home/aureen/the_odin_project/room_homepage/src/hooks/useSignIn.js":"3","/home/aureen/the_odin_project/room_homepage/src/hooks/useStorage.js":"4","/home/aureen/the_odin_project/room_homepage/src/hooks/useSignUp.js":"5","/home/aureen/the_odin_project/room_homepage/src/hooks/useUserSettings.js":"6","/home/aureen/the_odin_project/room_homepage/src/hooks/useShop.js":"7","/home/aureen/the_odin_project/room_homepage/src/hooks/useOrder.js":"8","/home/aureen/the_odin_project/room_homepage/src/hooks/useCart.js":"9","/home/aureen/the_odin_project/room_homepage/src/hooks/useDesign.js":"10","/home/aureen/the_odin_project/room_homepage/src/hooks/useAddress.js":"11","/home/aureen/the_odin_project/room_homepage/src/hooks/usePayment.js":"12","/home/aureen/the_odin_project/room_homepage/src/hooks/useUser.js":"13","/home/aureen/the_odin_project/room_homepage/src/hooks/useCarousel.js":"14","/home/aureen/the_odin_project/room_homepage/src/hooks/useWindowSize.js":"15","/home/aureen/the_odin_project/room_homepage/src/index.jsx":"16","/home/aureen/the_odin_project/room_homepage/src/App.jsx":"17","/home/aureen/the_odin_project/room_homepage/src/contexts/AuthContext.jsx":"18","/home/aureen/the_odin_project/room_homepage/src/contexts/FavoriteContext.jsx":"19","/home/aureen/the_odin_project/room_homepage/src/routes/general/About.jsx":"20","/home/aureen/the_odin_project/room_homepage/src/routes/general/Home.jsx":"21","/home/aureen/the_odin_project/room_homepage/src/routes/general/Contact.jsx":"22","/home/aureen/the_odin_project/room_homepage/src/routes/shop/Shop.jsx":"23","/home/aureen/the_odin_project/room_homepage/src/routes/account/Account.jsx":"24","/home/aureen/the_odin_project/room_homepage/src/routes/shop/checkout/Cart.jsx":"25","/home/aureen/the_odin_project/room_homepage/src/routes/account/Favorite.jsx":"26","/home/aureen/the_odin_project/room_homepage/src/routes/account/Entry.jsx":"27","/home/aureen/the_odin_project/room_homepage/src/routes/general/HandleShop.jsx":"28","/home/aureen/the_odin_project/room_homepage/src/components/Nav.jsx":"29","/home/aureen/the_odin_project/room_homepage/src/components/Carousel.jsx":"30","/home/aureen/the_odin_project/room_homepage/src/routes/types/PublicRoute.jsx":"31","/home/aureen/the_odin_project/room_homepage/src/routes/types/PrivateRoute.jsx":"32","/home/aureen/the_odin_project/room_homepage/src/routes/shop/orders/Tracking.jsx":"33","/home/aureen/the_odin_project/room_homepage/src/routes/shop/display/Category.jsx":"34","/home/aureen/the_odin_project/room_homepage/src/routes/shop/display/Main.jsx":"35","/home/aureen/the_odin_project/room_homepage/src/routes/shop/display/ItemDetails.jsx":"36","/home/aureen/the_odin_project/room_homepage/src/routes/shop/display/Design.jsx":"37","/home/aureen/the_odin_project/room_homepage/src/routes/shop/display/NewIn.jsx":"38","/home/aureen/the_odin_project/room_homepage/src/routes/shop/checkout/Payment.jsx":"39","/home/aureen/the_odin_project/room_homepage/src/routes/shop/checkout/Personal.jsx":"40","/home/aureen/the_odin_project/room_homepage/src/routes/shop/checkout/Confirmation.jsx":"41","/home/aureen/the_odin_project/room_homepage/src/routes/account/settings/Orders.jsx":"42","/home/aureen/the_odin_project/room_homepage/src/components/account/AccountNav.jsx":"43","/home/aureen/the_odin_project/room_homepage/src/routes/account/settings/Addresses.jsx":"44","/home/aureen/the_odin_project/room_homepage/src/routes/account/settings/Payment.jsx":"45","/home/aureen/the_odin_project/room_homepage/src/routes/account/settings/Settings.jsx":"46","/home/aureen/the_odin_project/room_homepage/src/components/shop/nav/ShopNav.jsx":"47","/home/aureen/the_odin_project/room_homepage/src/components/shop/nav/Nav.jsx":"48","/home/aureen/the_odin_project/room_homepage/src/components/shop/nav/Footer.jsx":"49","/home/aureen/the_odin_project/room_homepage/src/components/account/SignIn.jsx":"50","/home/aureen/the_odin_project/room_homepage/src/components/account/SignUp.jsx":"51","/home/aureen/the_odin_project/room_homepage/src/components/shop/display/ShopItemPreview.jsx":"52","/home/aureen/the_odin_project/room_homepage/src/components/shop_handling/AddShopItem.jsx":"53","/home/aureen/the_odin_project/room_homepage/src/components/account/Order.jsx":"54","/home/aureen/the_odin_project/room_homepage/src/components/shop/display/Filters.jsx":"55","/home/aureen/the_odin_project/room_homepage/src/components/shop/display/SideFilters.jsx":"56","/home/aureen/the_odin_project/room_homepage/src/components/shop/display/Sort.jsx":"57","/home/aureen/the_odin_project/room_homepage/src/components/FullCarousel.jsx":"58","/home/aureen/the_odin_project/room_homepage/src/components/shop/display/Designs.jsx":"59","/home/aureen/the_odin_project/room_homepage/src/components/shop/display/Recommendations.jsx":"60","/home/aureen/the_odin_project/room_homepage/src/components/shop/display/ImagesPreview.jsx":"61","/home/aureen/the_odin_project/room_homepage/src/components/shop/cart/CartPreview.jsx":"62","/home/aureen/the_odin_project/room_homepage/src/components/shop/checkout/Order.jsx":"63","/home/aureen/the_odin_project/room_homepage/src/components/account/AccessSettings.jsx":"64","/home/aureen/the_odin_project/room_homepage/src/components/shop/nav/SideNav.jsx":"65","/home/aureen/the_odin_project/room_homepage/src/components/shop/display/ImageMagnifier.jsx":"66","/home/aureen/the_odin_project/room_homepage/src/components/shop/cart/CartItem.jsx":"67","/home/aureen/the_odin_project/room/src/index.jsx":"68","/home/aureen/the_odin_project/room/src/App.jsx":"69","/home/aureen/the_odin_project/room/src/contexts/AuthContext.jsx":"70","/home/aureen/the_odin_project/room/src/contexts/FavoriteContext.jsx":"71","/home/aureen/the_odin_project/room/src/routes/general/About.jsx":"72","/home/aureen/the_odin_project/room/src/routes/general/Contact.jsx":"73","/home/aureen/the_odin_project/room/src/routes/general/Home.jsx":"74","/home/aureen/the_odin_project/room/src/routes/shop/Shop.jsx":"75","/home/aureen/the_odin_project/room/src/routes/account/Account.jsx":"76","/home/aureen/the_odin_project/room/src/firebase/firebase.js":"77","/home/aureen/the_odin_project/room/src/hooks/useWindowSize.js":"78","/home/aureen/the_odin_project/room/src/routes/account/Favorite.jsx":"79","/home/aureen/the_odin_project/room/src/routes/account/Entry.jsx":"80","/home/aureen/the_odin_project/room/src/routes/general/HandleShop.jsx":"81","/home/aureen/the_odin_project/room/src/components/Nav.jsx":"82","/home/aureen/the_odin_project/room/src/components/Carousel.jsx":"83","/home/aureen/the_odin_project/room/src/routes/types/PublicRoute.jsx":"84","/home/aureen/the_odin_project/room/src/routes/types/PrivateRoute.jsx":"85","/home/aureen/the_odin_project/room/src/routes/shop/orders/Tracking.jsx":"86","/home/aureen/the_odin_project/room/src/routes/shop/display/Category.jsx":"87","/home/aureen/the_odin_project/room/src/routes/shop/display/ItemDetails.jsx":"88","/home/aureen/the_odin_project/room/src/routes/shop/display/Main.jsx":"89","/home/aureen/the_odin_project/room/src/routes/shop/display/NewIn.jsx":"90","/home/aureen/the_odin_project/room/src/routes/shop/display/Design.jsx":"91","/home/aureen/the_odin_project/room/src/routes/shop/checkout/Cart.jsx":"92","/home/aureen/the_odin_project/room/src/routes/shop/checkout/Payment.jsx":"93","/home/aureen/the_odin_project/room/src/routes/shop/checkout/Personal.jsx":"94","/home/aureen/the_odin_project/room/src/routes/shop/checkout/Confirmation.jsx":"95","/home/aureen/the_odin_project/room/src/components/account/AccountNav.jsx":"96","/home/aureen/the_odin_project/room/src/routes/account/settings/Orders.jsx":"97","/home/aureen/the_odin_project/room/src/routes/account/settings/Addresses.jsx":"98","/home/aureen/the_odin_project/room/src/routes/account/settings/Payment.jsx":"99","/home/aureen/the_odin_project/room/src/routes/account/settings/Settings.jsx":"100","/home/aureen/the_odin_project/room/src/components/shop/nav/Nav.jsx":"101","/home/aureen/the_odin_project/room/src/components/shop/nav/ShopNav.jsx":"102","/home/aureen/the_odin_project/room/src/components/shop/nav/Footer.jsx":"103","/home/aureen/the_odin_project/room/src/hooks/useShop.js":"104","/home/aureen/the_odin_project/room/src/hooks/useOrder.js":"105","/home/aureen/the_odin_project/room/src/hooks/useUser.js":"106","/home/aureen/the_odin_project/room/src/hooks/useUserSettings.js":"107","/home/aureen/the_odin_project/room/src/hooks/usePayment.js":"108","/home/aureen/the_odin_project/room/src/hooks/useCart.js":"109","/home/aureen/the_odin_project/room/src/hooks/useAddress.js":"110","/home/aureen/the_odin_project/room/src/utils/utils.js":"111","/home/aureen/the_odin_project/room/src/hooks/useSignIn.js":"112","/home/aureen/the_odin_project/room/src/hooks/useDesign.js":"113","/home/aureen/the_odin_project/room/src/components/account/SignIn.jsx":"114","/home/aureen/the_odin_project/room/src/components/account/SignUp.jsx":"115","/home/aureen/the_odin_project/room/src/components/shop/display/ShopItemPreview.jsx":"116","/home/aureen/the_odin_project/room/src/components/shop_handling/AddShopItem.jsx":"117","/home/aureen/the_odin_project/room/src/components/account/Order.jsx":"118","/home/aureen/the_odin_project/room/src/components/shop/display/SideFilters.jsx":"119","/home/aureen/the_odin_project/room/src/components/shop/display/Filters.jsx":"120","/home/aureen/the_odin_project/room/src/components/shop/display/Sort.jsx":"121","/home/aureen/the_odin_project/room/src/components/shop/display/Designs.jsx":"122","/home/aureen/the_odin_project/room/src/components/shop/cart/CartPreview.jsx":"123","/home/aureen/the_odin_project/room/src/components/account/AccessSettings.jsx":"124","/home/aureen/the_odin_project/room/src/components/shop/nav/SideNav.jsx":"125","/home/aureen/the_odin_project/room/src/components/shop/cart/CartItem.jsx":"126","/home/aureen/the_odin_project/room/src/components/FullCarousel.jsx":"127","/home/aureen/the_odin_project/room/src/components/shop/display/ImagesPreview.jsx":"128","/home/aureen/the_odin_project/room/src/components/shop/display/Recommendations.jsx":"129","/home/aureen/the_odin_project/room/src/components/shop/checkout/Order.jsx":"130","/home/aureen/the_odin_project/room/src/hooks/useSignUp.js":"131","/home/aureen/the_odin_project/room/src/hooks/useStorage.js":"132","/home/aureen/the_odin_project/room/src/hooks/useCarousel.js":"133","/home/aureen/the_odin_project/room/src/components/shop/display/ImageMagnifier.jsx":"134"},{"size":641,"mtime":1612805752693,"results":"135","hashOfConfig":"136"},{"size":444,"mtime":1611937493436,"results":"137","hashOfConfig":"136"},{"size":2345,"mtime":1612805998865,"results":"138","hashOfConfig":"136"},{"size":367,"mtime":1612806047965,"results":"139","hashOfConfig":"136"},{"size":1892,"mtime":1612807550657,"results":"140","hashOfConfig":"136"},{"size":3727,"mtime":1612806076765,"results":"141","hashOfConfig":"136"},{"size":3439,"mtime":1612805962973,"results":"142","hashOfConfig":"136"},{"size":1348,"mtime":1612805935421,"results":"143","hashOfConfig":"136"},{"size":2747,"mtime":1612805892853,"results":"144","hashOfConfig":"136"},{"size":574,"mtime":1612805922069,"results":"145","hashOfConfig":"136"},{"size":5121,"mtime":1612807530845,"results":"146","hashOfConfig":"136"},{"size":3330,"mtime":1612805948101,"results":"147","hashOfConfig":"136"},{"size":1061,"mtime":1612806061149,"results":"148","hashOfConfig":"136"},{"size":2950,"mtime":1612805879685,"results":"149","hashOfConfig":"136"},{"size":532,"mtime":1612806089225,"results":"150","hashOfConfig":"136"},{"size":197,"mtime":1612807827357,"results":"151","hashOfConfig":"136"},{"size":1099,"mtime":1616608652312,"results":"152","hashOfConfig":"136"},{"size":1690,"mtime":1612807507029,"results":"153","hashOfConfig":"136"},{"size":2289,"mtime":1612807487657,"results":"154","hashOfConfig":"136"},{"size":3096,"mtime":1616782340245,"results":"155","hashOfConfig":"136"},{"size":4060,"mtime":1616786210329,"results":"156","hashOfConfig":"136"},{"size":6822,"mtime":1616782361725,"results":"157","hashOfConfig":"136"},{"size":2929,"mtime":1616786121493,"results":"158","hashOfConfig":"136"},{"size":2594,"mtime":1616782071609,"results":"159","hashOfConfig":"136"},{"size":10638,"mtime":1616782468437,"results":"160","hashOfConfig":"136"},{"size":3136,"mtime":1616782328101,"results":"161","hashOfConfig":"136"},{"size":2310,"mtime":1616782309005,"results":"162","hashOfConfig":"136"},{"size":211,"mtime":1612806271133,"results":"163","hashOfConfig":"136"},{"size":3665,"mtime":1616781884457,"results":"164","hashOfConfig":"136"},{"size":5902,"mtime":1616781853641,"results":"165","hashOfConfig":"136"},{"size":555,"mtime":1612806571849,"results":"166","hashOfConfig":"136"},{"size":571,"mtime":1612806565457,"results":"167","hashOfConfig":"136"},{"size":3633,"mtime":1616786090625,"results":"168","hashOfConfig":"136"},{"size":5988,"mtime":1616783113249,"results":"169","hashOfConfig":"136"},{"size":3597,"mtime":1616786047969,"results":"170","hashOfConfig":"136"},{"size":19185,"mtime":1616786032177,"results":"171","hashOfConfig":"136"},{"size":4324,"mtime":1616786472549,"results":"172","hashOfConfig":"136"},{"size":5687,"mtime":1616786065793,"results":"173","hashOfConfig":"136"},{"size":11746,"mtime":1616786221937,"results":"174","hashOfConfig":"136"},{"size":11946,"mtime":1616783049269,"results":"175","hashOfConfig":"136"},{"size":4375,"mtime":1616782574989,"results":"176","hashOfConfig":"136"},{"size":981,"mtime":1616782030605,"results":"177","hashOfConfig":"136"},{"size":2266,"mtime":1616780626085,"results":"178","hashOfConfig":"136"},{"size":15456,"mtime":1616782020477,"results":"179","hashOfConfig":"136"},{"size":11518,"mtime":1616782045389,"results":"180","hashOfConfig":"136"},{"size":8189,"mtime":1616782058529,"results":"181","hashOfConfig":"136"},{"size":4698,"mtime":1616781802289,"results":"182","hashOfConfig":"136"},{"size":4930,"mtime":1616786603809,"results":"183","hashOfConfig":"136"},{"size":2972,"mtime":1616781774581,"results":"184","hashOfConfig":"136"},{"size":4401,"mtime":1616780658670,"results":"185","hashOfConfig":"136"},{"size":5002,"mtime":1616780674334,"results":"186","hashOfConfig":"136"},{"size":3444,"mtime":1616781685949,"results":"187","hashOfConfig":"136"},{"size":35378,"mtime":1616781839413,"results":"188","hashOfConfig":"136"},{"size":4677,"mtime":1616780638448,"results":"189","hashOfConfig":"136"},{"size":16997,"mtime":1616781084466,"results":"190","hashOfConfig":"136"},{"size":14961,"mtime":1616781699713,"results":"191","hashOfConfig":"136"},{"size":1215,"mtime":1616781721577,"results":"192","hashOfConfig":"136"},{"size":5488,"mtime":1616781865757,"results":"193","hashOfConfig":"136"},{"size":4832,"mtime":1616780963318,"results":"194","hashOfConfig":"136"},{"size":4811,"mtime":1616781671773,"results":"195","hashOfConfig":"136"},{"size":4491,"mtime":1616781227978,"results":"196","hashOfConfig":"136"},{"size":3158,"mtime":1616780748723,"results":"197","hashOfConfig":"136"},{"size":3855,"mtime":1616780773139,"results":"198","hashOfConfig":"136"},{"size":3308,"mtime":1616780608921,"results":"199","hashOfConfig":"136"},{"size":9014,"mtime":1616781814953,"results":"200","hashOfConfig":"136"},{"size":1778,"mtime":1616781107230,"results":"201","hashOfConfig":"136"},{"size":4048,"mtime":1616780572763,"results":"202","hashOfConfig":"136"},{"size":197,"mtime":1617184853370,"results":"203","hashOfConfig":"204"},{"size":1099,"mtime":1617184853318,"results":"205","hashOfConfig":"204"},{"size":1690,"mtime":1617184853370,"results":"206","hashOfConfig":"204"},{"size":2289,"mtime":1617184853370,"results":"207","hashOfConfig":"204"},{"size":3096,"mtime":1617184853370,"results":"208","hashOfConfig":"204"},{"size":7216,"mtime":1617184301758,"results":"209","hashOfConfig":"204"},{"size":4060,"mtime":1617184853370,"results":"210","hashOfConfig":"204"},{"size":2929,"mtime":1617184853370,"results":"211","hashOfConfig":"204"},{"size":2594,"mtime":1617184853370,"results":"212","hashOfConfig":"204"},{"size":641,"mtime":1617184853370,"results":"213","hashOfConfig":"204"},{"size":532,"mtime":1617184853370,"results":"214","hashOfConfig":"204"},{"size":3136,"mtime":1617184853370,"results":"215","hashOfConfig":"204"},{"size":2310,"mtime":1617184853370,"results":"216","hashOfConfig":"204"},{"size":211,"mtime":1617184853370,"results":"217","hashOfConfig":"204"},{"size":3665,"mtime":1617184853366,"results":"218","hashOfConfig":"204"},{"size":5902,"mtime":1617184853366,"results":"219","hashOfConfig":"204"},{"size":555,"mtime":1617184853370,"results":"220","hashOfConfig":"204"},{"size":571,"mtime":1617184853370,"results":"221","hashOfConfig":"204"},{"size":3633,"mtime":1617184853370,"results":"222","hashOfConfig":"204"},{"size":5988,"mtime":1617184853370,"results":"223","hashOfConfig":"204"},{"size":19185,"mtime":1617184853370,"results":"224","hashOfConfig":"204"},{"size":3597,"mtime":1617184853370,"results":"225","hashOfConfig":"204"},{"size":5687,"mtime":1617184853370,"results":"226","hashOfConfig":"204"},{"size":4324,"mtime":1617184853370,"results":"227","hashOfConfig":"204"},{"size":10638,"mtime":1617184853370,"results":"228","hashOfConfig":"204"},{"size":11746,"mtime":1617184853370,"results":"229","hashOfConfig":"204"},{"size":11946,"mtime":1617184853370,"results":"230","hashOfConfig":"204"},{"size":4375,"mtime":1617184853370,"results":"231","hashOfConfig":"204"},{"size":2266,"mtime":1617184853366,"results":"232","hashOfConfig":"204"},{"size":981,"mtime":1617184853370,"results":"233","hashOfConfig":"204"},{"size":15456,"mtime":1617184853370,"results":"234","hashOfConfig":"204"},{"size":11518,"mtime":1617184853370,"results":"235","hashOfConfig":"204"},{"size":8189,"mtime":1617184853370,"results":"236","hashOfConfig":"204"},{"size":4930,"mtime":1617184853366,"results":"237","hashOfConfig":"204"},{"size":4698,"mtime":1617184853366,"results":"238","hashOfConfig":"204"},{"size":2972,"mtime":1617184853366,"results":"239","hashOfConfig":"204"},{"size":3439,"mtime":1617184853370,"results":"240","hashOfConfig":"204"},{"size":1348,"mtime":1617184853370,"results":"241","hashOfConfig":"204"},{"size":1061,"mtime":1617184853370,"results":"242","hashOfConfig":"204"},{"size":3727,"mtime":1617184853370,"results":"243","hashOfConfig":"204"},{"size":3330,"mtime":1617184853370,"results":"244","hashOfConfig":"204"},{"size":2747,"mtime":1617184853370,"results":"245","hashOfConfig":"204"},{"size":5121,"mtime":1617184853370,"results":"246","hashOfConfig":"204"},{"size":444,"mtime":1617184853370,"results":"247","hashOfConfig":"204"},{"size":2345,"mtime":1617184853370,"results":"248","hashOfConfig":"204"},{"size":574,"mtime":1617184853370,"results":"249","hashOfConfig":"204"},{"size":4401,"mtime":1617184853366,"results":"250","hashOfConfig":"204"},{"size":5002,"mtime":1617184853366,"results":"251","hashOfConfig":"204"},{"size":3444,"mtime":1617184853366,"results":"252","hashOfConfig":"204"},{"size":35378,"mtime":1617184853370,"results":"253","hashOfConfig":"204"},{"size":4677,"mtime":1617184853366,"results":"254","hashOfConfig":"204"},{"size":14961,"mtime":1617184853366,"results":"255","hashOfConfig":"204"},{"size":16997,"mtime":1617184853366,"results":"256","hashOfConfig":"204"},{"size":1215,"mtime":1617184853366,"results":"257","hashOfConfig":"204"},{"size":4832,"mtime":1616780963318,"results":"258","hashOfConfig":"204"},{"size":3158,"mtime":1617184853366,"results":"259","hashOfConfig":"204"},{"size":3308,"mtime":1617184853366,"results":"260","hashOfConfig":"204"},{"size":9014,"mtime":1617184853370,"results":"261","hashOfConfig":"204"},{"size":4048,"mtime":1617184853366,"results":"262","hashOfConfig":"204"},{"size":5528,"mtime":1617180451994,"results":"263","hashOfConfig":"204"},{"size":4491,"mtime":1616781227978,"results":"264","hashOfConfig":"204"},{"size":4811,"mtime":1617184853366,"results":"265","hashOfConfig":"204"},{"size":3855,"mtime":1617184853366,"results":"266","hashOfConfig":"204"},{"size":1892,"mtime":1617184853370,"results":"267","hashOfConfig":"204"},{"size":367,"mtime":1617184853370,"results":"268","hashOfConfig":"204"},{"size":3174,"mtime":1617184694666,"results":"269","hashOfConfig":"204"},{"size":1778,"mtime":1617184853366,"results":"270","hashOfConfig":"204"},{"filePath":"271","messages":"272","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"273"},"9sjnut",{"filePath":"274","messages":"275","errorCount":6,"warningCount":0,"fixableErrorCount":4,"fixableWarningCount":0,"source":"276","usedDeprecatedRules":"273"},{"filePath":"277","messages":"278","errorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"279","usedDeprecatedRules":"273"},{"filePath":"280","messages":"281","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"273"},{"filePath":"282","messages":"283","errorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"284","usedDeprecatedRules":"273"},{"filePath":"285","messages":"286","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"273"},{"filePath":"287","messages":"288","errorCount":2,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"289","usedDeprecatedRules":"273"},{"filePath":"290","messages":"291","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"273"},{"filePath":"292","messages":"293","errorCount":2,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"294","usedDeprecatedRules":"273"},{"filePath":"295","messages":"296","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"273"},{"filePath":"297","messages":"298","errorCount":19,"warningCount":0,"fixableErrorCount":1,"fixableWarningCount":0,"source":"299","usedDeprecatedRules":"273"},{"filePath":"300","messages":"301","errorCount":9,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"302","usedDeprecatedRules":"273"},{"filePath":"303","messages":"304","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"273"},{"filePath":"305","messages":"306","errorCount":4,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"307","usedDeprecatedRules":"273"},{"filePath":"308","messages":"309","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"273"},{"filePath":"310","messages":"311","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"273"},{"filePath":"312","messages":"313","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"314","messages":"315","errorCount":1,"warningCount":0,"fixableErrorCount":1,"fixableWarningCount":0,"source":"316","usedDeprecatedRules":"273"},{"filePath":"317","messages":"318","errorCount":4,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"319","usedDeprecatedRules":"273"},{"filePath":"320","messages":"321","errorCount":1,"warningCount":0,"fixableErrorCount":1,"fixableWarningCount":0,"source":null},{"filePath":"322","messages":"323","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"324","messages":"325","errorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"326","messages":"327","errorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"328","messages":"329","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"330","messages":"331","errorCount":7,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"332","messages":"333","errorCount":3,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"334","messages":"335","errorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"336","messages":"337","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"273"},{"filePath":"338","messages":"339","errorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"340","messages":"341","errorCount":4,"warningCount":0,"fixableErrorCount":1,"fixableWarningCount":0,"source":null},{"filePath":"342","messages":"343","errorCount":3,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"344","usedDeprecatedRules":"273"},{"filePath":"345","messages":"346","errorCount":3,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"347","usedDeprecatedRules":"273"},{"filePath":"348","messages":"349","errorCount":2,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"350","messages":"351","errorCount":3,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"352","messages":"353","errorCount":4,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"354","messages":"355","errorCount":17,"warningCount":0,"fixableErrorCount":10,"fixableWarningCount":0,"source":null},{"filePath":"356","messages":"357","errorCount":4,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"358","messages":"359","errorCount":3,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"360","messages":"361","errorCount":11,"warningCount":0,"fixableErrorCount":8,"fixableWarningCount":0,"source":null},{"filePath":"362","messages":"363","errorCount":4,"warningCount":0,"fixableErrorCount":2,"fixableWarningCount":0,"source":null},{"filePath":"364","messages":"365","errorCount":10,"warningCount":0,"fixableErrorCount":8,"fixableWarningCount":0,"source":null},{"filePath":"366","messages":"367","errorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"368","messages":"369","errorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"370","messages":"371","errorCount":7,"warningCount":0,"fixableErrorCount":3,"fixableWarningCount":0,"source":null},{"filePath":"372","messages":"373","errorCount":12,"warningCount":0,"fixableErrorCount":6,"fixableWarningCount":0,"source":null},{"filePath":"374","messages":"375","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"376","messages":"377","errorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"378","messages":"379","errorCount":4,"warningCount":0,"fixableErrorCount":1,"fixableWarningCount":0,"source":null},{"filePath":"380","messages":"381","errorCount":2,"warningCount":0,"fixableErrorCount":1,"fixableWarningCount":0,"source":null},{"filePath":"382","messages":"383","errorCount":3,"warningCount":0,"fixableErrorCount":3,"fixableWarningCount":0,"source":null},{"filePath":"384","messages":"385","errorCount":5,"warningCount":0,"fixableErrorCount":1,"fixableWarningCount":0,"source":null},{"filePath":"386","messages":"387","errorCount":5,"warningCount":0,"fixableErrorCount":3,"fixableWarningCount":0,"source":null},{"filePath":"388","messages":"389","errorCount":74,"warningCount":0,"fixableErrorCount":32,"fixableWarningCount":0,"source":null},{"filePath":"390","messages":"391","errorCount":6,"warningCount":0,"fixableErrorCount":6,"fixableWarningCount":0,"source":null},{"filePath":"392","messages":"393","errorCount":48,"warningCount":0,"fixableErrorCount":36,"fixableWarningCount":0,"source":null},{"filePath":"394","messages":"395","errorCount":52,"warningCount":0,"fixableErrorCount":39,"fixableWarningCount":0,"source":null},{"filePath":"396","messages":"397","errorCount":1,"warningCount":0,"fixableErrorCount":1,"fixableWarningCount":0,"source":null},{"filePath":"398","messages":"399","errorCount":5,"warningCount":0,"fixableErrorCount":3,"fixableWarningCount":0,"source":null},{"filePath":"400","messages":"401","errorCount":7,"warningCount":0,"fixableErrorCount":3,"fixableWarningCount":0,"source":null},{"filePath":"402","messages":"403","errorCount":5,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"404","messages":"405","errorCount":3,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"406","messages":"407","errorCount":8,"warningCount":0,"fixableErrorCount":8,"fixableWarningCount":0,"source":null},{"filePath":"408","messages":"409","errorCount":11,"warningCount":0,"fixableErrorCount":10,"fixableWarningCount":0,"source":null},{"filePath":"410","messages":"411","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"412","messages":"413","errorCount":6,"warningCount":0,"fixableErrorCount":3,"fixableWarningCount":0,"source":null},{"filePath":"414","messages":"415","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"416","messages":"417","errorCount":11,"warningCount":0,"fixableErrorCount":9,"fixableWarningCount":0,"source":null},{"filePath":"418","messages":"419","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"420"},"1a1jx3r",{"filePath":"421","messages":"422","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"420"},{"filePath":"423","messages":"424","errorCount":1,"warningCount":0,"fixableErrorCount":1,"fixableWarningCount":0,"source":"316","usedDeprecatedRules":"420"},{"filePath":"425","messages":"426","errorCount":4,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"319","usedDeprecatedRules":"420"},{"filePath":"427","messages":"428","errorCount":1,"warningCount":0,"fixableErrorCount":1,"fixableWarningCount":0,"source":"429","usedDeprecatedRules":"420"},{"filePath":"430","messages":"431","errorCount":2,"warningCount":0,"fixableErrorCount":1,"fixableWarningCount":0,"source":"432","usedDeprecatedRules":"420"},{"filePath":"433","messages":"434","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"420"},{"filePath":"435","messages":"436","errorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"437","usedDeprecatedRules":"420"},{"filePath":"438","messages":"439","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"420"},{"filePath":"440","messages":"441","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"420"},{"filePath":"442","messages":"443","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"420"},{"filePath":"444","messages":"445","errorCount":3,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"446","usedDeprecatedRules":"420"},{"filePath":"447","messages":"448","errorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"449","usedDeprecatedRules":"420"},{"filePath":"450","messages":"451","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"420"},{"filePath":"452","messages":"453","errorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"454","usedDeprecatedRules":"420"},{"filePath":"455","messages":"456","errorCount":4,"warningCount":0,"fixableErrorCount":1,"fixableWarningCount":0,"source":"457","usedDeprecatedRules":"420"},{"filePath":"458","messages":"459","errorCount":3,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"344","usedDeprecatedRules":"420"},{"filePath":"460","messages":"461","errorCount":3,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"347","usedDeprecatedRules":"420"},{"filePath":"462","messages":"463","errorCount":2,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"464","usedDeprecatedRules":"420"},{"filePath":"465","messages":"466","errorCount":3,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"467","usedDeprecatedRules":"420"},{"filePath":"468","messages":"469","errorCount":17,"warningCount":0,"fixableErrorCount":10,"fixableWarningCount":0,"source":"470","usedDeprecatedRules":"420"},{"filePath":"471","messages":"472","errorCount":4,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"473","usedDeprecatedRules":"420"},{"filePath":"474","messages":"475","errorCount":3,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"476","usedDeprecatedRules":"420"},{"filePath":"477","messages":"478","errorCount":4,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"479","usedDeprecatedRules":"420"},{"filePath":"480","messages":"481","errorCount":7,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"482","usedDeprecatedRules":"420"},{"filePath":"483","messages":"484","errorCount":11,"warningCount":0,"fixableErrorCount":8,"fixableWarningCount":0,"source":"485","usedDeprecatedRules":"420"},{"filePath":"486","messages":"487","errorCount":4,"warningCount":0,"fixableErrorCount":2,"fixableWarningCount":0,"source":"488","usedDeprecatedRules":"420"},{"filePath":"489","messages":"490","errorCount":10,"warningCount":0,"fixableErrorCount":8,"fixableWarningCount":0,"source":"491","usedDeprecatedRules":"420"},{"filePath":"492","messages":"493","errorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"494","usedDeprecatedRules":"420"},{"filePath":"495","messages":"496","errorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"497","usedDeprecatedRules":"420"},{"filePath":"498","messages":"499","errorCount":7,"warningCount":0,"fixableErrorCount":3,"fixableWarningCount":0,"source":"500","usedDeprecatedRules":"420"},{"filePath":"501","messages":"502","errorCount":12,"warningCount":0,"fixableErrorCount":6,"fixableWarningCount":0,"source":"503","usedDeprecatedRules":"420"},{"filePath":"504","messages":"505","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"420"},{"filePath":"506","messages":"507","errorCount":4,"warningCount":0,"fixableErrorCount":1,"fixableWarningCount":0,"source":"508","usedDeprecatedRules":"420"},{"filePath":"509","messages":"510","errorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"511","usedDeprecatedRules":"420"},{"filePath":"512","messages":"513","errorCount":2,"warningCount":0,"fixableErrorCount":1,"fixableWarningCount":0,"source":"514","usedDeprecatedRules":"420"},{"filePath":"515","messages":"516","errorCount":2,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"289","usedDeprecatedRules":"420"},{"filePath":"517","messages":"518","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"420"},{"filePath":"519","messages":"520","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"420"},{"filePath":"521","messages":"522","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"420"},{"filePath":"523","messages":"524","errorCount":9,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"302","usedDeprecatedRules":"420"},{"filePath":"525","messages":"526","errorCount":2,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"294","usedDeprecatedRules":"420"},{"filePath":"527","messages":"528","errorCount":19,"warningCount":0,"fixableErrorCount":1,"fixableWarningCount":0,"source":"299","usedDeprecatedRules":"420"},{"filePath":"529","messages":"530","errorCount":6,"warningCount":0,"fixableErrorCount":4,"fixableWarningCount":0,"source":"276","usedDeprecatedRules":"420"},{"filePath":"531","messages":"532","errorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"279","usedDeprecatedRules":"420"},{"filePath":"533","messages":"534","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"420"},{"filePath":"535","messages":"536","errorCount":3,"warningCount":0,"fixableErrorCount":3,"fixableWarningCount":0,"source":"537","usedDeprecatedRules":"420"},{"filePath":"538","messages":"539","errorCount":5,"warningCount":0,"fixableErrorCount":1,"fixableWarningCount":0,"source":"540","usedDeprecatedRules":"420"},{"filePath":"541","messages":"542","errorCount":5,"warningCount":0,"fixableErrorCount":3,"fixableWarningCount":0,"source":"543","usedDeprecatedRules":"420"},{"filePath":"544","messages":"545","errorCount":74,"warningCount":0,"fixableErrorCount":32,"fixableWarningCount":0,"source":"546","usedDeprecatedRules":"420"},{"filePath":"547","messages":"548","errorCount":6,"warningCount":0,"fixableErrorCount":6,"fixableWarningCount":0,"source":"549","usedDeprecatedRules":"420"},{"filePath":"550","messages":"551","errorCount":52,"warningCount":0,"fixableErrorCount":39,"fixableWarningCount":0,"source":"552","usedDeprecatedRules":"420"},{"filePath":"553","messages":"554","errorCount":48,"warningCount":0,"fixableErrorCount":36,"fixableWarningCount":0,"source":"555","usedDeprecatedRules":"420"},{"filePath":"556","messages":"557","errorCount":1,"warningCount":0,"fixableErrorCount":1,"fixableWarningCount":0,"source":"558","usedDeprecatedRules":"420"},{"filePath":"559","messages":"560","errorCount":7,"warningCount":0,"fixableErrorCount":3,"fixableWarningCount":0,"source":null},{"filePath":"561","messages":"562","errorCount":8,"warningCount":0,"fixableErrorCount":8,"fixableWarningCount":0,"source":"563","usedDeprecatedRules":"420"},{"filePath":"564","messages":"565","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"420"},{"filePath":"566","messages":"567","errorCount":6,"warningCount":0,"fixableErrorCount":3,"fixableWarningCount":0,"source":"568","usedDeprecatedRules":"420"},{"filePath":"569","messages":"570","errorCount":11,"warningCount":0,"fixableErrorCount":9,"fixableWarningCount":0,"source":"571","usedDeprecatedRules":"420"},{"filePath":"572","messages":"573","errorCount":5,"warningCount":0,"fixableErrorCount":3,"fixableWarningCount":0,"source":"574","usedDeprecatedRules":"420"},{"filePath":"575","messages":"576","errorCount":3,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"577","messages":"578","errorCount":5,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"579","usedDeprecatedRules":"420"},{"filePath":"580","messages":"581","errorCount":11,"warningCount":0,"fixableErrorCount":10,"fixableWarningCount":0,"source":"582","usedDeprecatedRules":"420"},{"filePath":"583","messages":"584","errorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"284","usedDeprecatedRules":"420"},{"filePath":"585","messages":"586","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"420"},{"filePath":"587","messages":"588","errorCount":4,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"589","usedDeprecatedRules":"420"},{"filePath":"590","messages":"591","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"/home/aureen/the_odin_project/room_homepage/src/firebase/firebase.js",[],["592","593","594","595","596"],"/home/aureen/the_odin_project/room_homepage/src/utils/utils.js",["597","598","599","600","601","602"],"export const formatNavLink = (link) => {\n return (\n link\n // Replace '_' with spaces\n .replace(/_/gi, ' ')\n // Uppercase the first letter of each words except \"of\"\n .replace(/\\b(\\w+?)\\b/gi, (match, content) => {\n return capitalize(content);\n })\n );\n};\n\nconst capitalize = (word) => {\n if (!['of', 'and'].includes(word)) {\n return word[0].toUpperCase() + word.slice(1);\n } else {\n return word\n }\n};\n","/home/aureen/the_odin_project/room_homepage/src/hooks/useSignIn.js",["603"],"import { useState } from \"react\";\nimport { useHistory } from \"react-router-dom\";\nimport { useAuth } from \"../contexts/AuthContext\";\n\nfunction useSignIn() {\n const [email, setEmail] = useState(\"\");\n const [emailError, setEmailError] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [passwordError, setPasswordError] = useState(\"\");\n const [loading, setLoading] = useState(false);\n const { signIn, resetPassword } = useAuth();\n const history = useHistory();\n\n const clearErrors = () => {\n setEmailError(\"\");\n setPasswordError(\"\");\n };\n\n async function handleSignIn(isPaying) {\n clearErrors();\n\n if (!password && !email) {\n setPasswordError(\"This field is required\");\n setEmailError(\"This field is required\");\n return;\n }\n if (!password) {\n setPasswordError(\"This field is required\");\n return;\n }\n if (!email) {\n setEmailError(\"This field is required\");\n return;\n }\n\n setLoading(true);\n try {\n await signIn(email, password);\n isPaying ? history.push(\"/shop/cart\") : history.push(\"/shop\");\n setLoading(false);\n } catch (err) {\n switch (err.code) {\n case \"auth/invalid-email\":\n case \"auth/user-not-found\":\n case \"auth/wrong-password\":\n setEmailError(\"Login or password is invalid\");\n setPasswordError(\"Login or password is invalid\");\n setLoading(false);\n break;\n default:\n setPasswordError(\"Sorry, the sign in failed.\");\n setLoading(false);\n }\n }\n }\n\n const handleForgotPassword = async () => {\n clearErrors();\n if (!email) {\n setEmailError(\"This field is required\");\n return;\n }\n\n setLoading(true);\n\n try {\n await resetPassword(email);\n setLoading(false);\n } catch (err) {\n switch (err.code) {\n case \"auth/invalid-email\":\n case \"auth/user-not-found\":\n setEmailError(\"Email does not exist\");\n break;\n default:\n setEmailError(\"Sorry, we were unable to reset your password.\");\n }\n }\n };\n\n return {\n email,\n setEmail,\n password,\n setPassword,\n emailError,\n setEmailError,\n passwordError,\n setPasswordError,\n loading,\n setLoading,\n handleSignIn,\n handleForgotPassword,\n };\n}\n\nexport default useSignIn;\n","/home/aureen/the_odin_project/room_homepage/src/hooks/useStorage.js",[],"/home/aureen/the_odin_project/room_homepage/src/hooks/useSignUp.js",["604"],"import { useState, useEffect } from \"react\";\nimport { useAuth } from \"../contexts/AuthContext\";\nimport useUser from \"./useUser\";\n\nfunction useSignUp() {\n const [email, setEmail] = useState(\"\");\n const [firstName, setFirstName] = useState(\"\");\n const [lastName, setLastName] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [terms, setTerms] = useState(false);\n const [emailError, setEmailError] = useState(\"\");\n const [passwordError, setPasswordError] = useState(\"\");\n const [isFormCompleted, setIsFormCompleted] = useState(true);\n const [loading, setLoading] = useState(false);\n\n const { currentUser, signUp, signUpFromAnonymous } = useAuth();\n const { createUser } = useUser();\n\n useEffect(() => {\n email && firstName && lastName && password && terms\n ? setIsFormCompleted(false)\n : setIsFormCompleted(true);\n }, [email, firstName, lastName, password, terms]);\n\n async function handleSignUp() {\n setLoading(true);\n setEmailError(\"\");\n setPasswordError(\"\");\n\n try {\n const user =\n currentUser && currentUser.isAnonymous\n ? await signUpFromAnonymous(email, password)\n : await signUp(email, password);\n await createUser(user.user.uid, firstName, lastName, email);\n setLoading(false);\n } catch (err) {\n switch (err.code) {\n case \"auth/email-already-in-use\":\n case \"auth/invalid-email\":\n setEmailError(err.message);\n break;\n case \"auth/weak-password\":\n setPasswordError(err.message);\n break;\n default:\n }\n setLoading(false);\n }\n }\n\n return {\n email,\n setEmail,\n firstName,\n setFirstName,\n lastName,\n setLastName,\n password,\n setPassword,\n terms,\n setTerms,\n emailError,\n passwordError,\n isFormCompleted,\n loading,\n handleSignUp,\n };\n}\n\nexport default useSignUp;\n","/home/aureen/the_odin_project/room_homepage/src/hooks/useUserSettings.js",[],"/home/aureen/the_odin_project/room_homepage/src/hooks/useShop.js",["605","606"],"import { firestore } from \"../firebase/firebase\";\n\nfunction useShop() {\n // Create a document where we'll store an item.\n // Returns the id we will attribute to the item.\n const createItem = async () => {\n return firestore.collection(\"products\").add({});\n };\n\n // Puts the item data in the document.\n const addItem = async (\n id,\n name,\n price,\n type,\n dimensions,\n images,\n description,\n colors,\n additional,\n options,\n categories,\n queries\n ) => {\n await firestore.collection(\"products\").doc(id).set({\n id,\n name,\n price,\n type,\n dimensions,\n images,\n description,\n colors,\n additional,\n options,\n categories,\n queries,\n new: false,\n date: new Date(),\n });\n return id;\n };\n\n // Returns an object representing all the shopping categories.\n const getShopCategories = async () => {\n const categories = await firestore\n .collection(\"navigation\")\n .doc(\"categories\")\n .get();\n return categories.data();\n };\n\n // Returns all the products we are selling.\n const getShopItems = async () => {\n const itemsList = [];\n const items = await firestore.collection(\"products\").get();\n items.docs.map((doc) => itemsList.push(doc.data()));\n return itemsList;\n };\n\n // Returns only the products from a certain category\n const getCategoryItems = async (category) => {\n const itemsList = [];\n const items = await firestore\n .collection(\"products\")\n .where(\"categories\", \"array-contains\", category)\n .get();\n items.docs.map((doc) => itemsList.push(doc.data()));\n return itemsList;\n };\n\n const getNewItems = async () => {\n const itemsList = [];\n const items = await firestore\n .collection(\"products\")\n .where(\"new\", \"==\", true)\n .get();\n items.docs.map((doc) => itemsList.push(doc.data()));\n return itemsList;\n };\n\n // Gets an item's data\n const getItem = async (id) => {\n const doc = await firestore.collection(\"products\").doc(id).get();\n return doc.data();\n };\n\n // Gets similar items to recommend them to the user\n const getRecommendations = async (id) => {\n const item = await getItem(id);\n const recommendations = [];\n\n const sameCollection = await firestore\n .collection(\"products\")\n .where(\"name\", \"==\", item.name)\n .where(\"id\", \"!=\", item.id)\n .limit(12)\n .get();\n\n const sameCategory = await firestore\n .collection(\"products\")\n .where(\n \"categories\",\n \"array-contains\",\n item.categories[item.categories.length - 1]\n )\n .where(\"id\", \"!=\", item.id)\n .limit(12)\n .get();\n\n sameCollection.docs.forEach((item) => recommendations.push(item.data()));\n // Filter to avoid having the same item twice.\n sameCategory.docs.forEach(\n (item) =>\n recommendations.filter(\n (recommendation) => recommendation.id === item.id\n ).length === 0 && recommendations.push(item.data())\n );\n return recommendations;\n };\n\n // Search for an item\n const searchItem = (query) => {\n return firestore\n .collection(\"products\")\n .where(\"queries.search\", \"array-contains\", query)\n .get();\n };\n\n return {\n createItem,\n addItem,\n getShopCategories,\n getShopItems,\n getCategoryItems,\n getNewItems,\n getItem,\n getRecommendations,\n searchItem,\n };\n}\n\nexport default useShop;\n","/home/aureen/the_odin_project/room_homepage/src/hooks/useOrder.js",[],"/home/aureen/the_odin_project/room_homepage/src/hooks/useCart.js",["607","608"],"import { firestore } from \"../firebase/firebase\";\n\nfunction useCart() {\n // Add an item to the user's cart\n // In the cart, each product chosen has their own id.\n const addToCart = async (\n userId,\n productId,\n name,\n image,\n color,\n options,\n quantity,\n type,\n price\n ) => {\n // If the same item is already in the cart, we simply increase the quantity.\n const sameItem = await firestore\n .collection(\"carts\")\n .doc(userId)\n .collection(\"items\")\n .where(\"productId\", \"==\", productId)\n .where(\"color\", \"==\", color)\n .where(\"options\", \"==\", options)\n .get();\n\n if (sameItem.docs.length > 0) {\n const currentQuantity = sameItem.docs[0].data().quantity;\n sameItem.docs[0].ref.update({ quantity: +currentQuantity + +quantity });\n return;\n }\n\n // If the item is not already in the cart, we create a document for it.\n const docRef = await firestore\n .collection(\"carts\")\n .doc(userId)\n .collection(\"items\")\n .doc();\n\n const { id } = docRef;\n\n return firestore\n .collection(\"carts\")\n .doc(userId)\n .collection(\"items\")\n .doc(id)\n .set({\n id,\n productId,\n name,\n image,\n color,\n options,\n quantity,\n type,\n price,\n });\n };\n\n const deleteFromCart = (userId, id) => {\n return firestore\n .collection(\"carts\")\n .doc(userId)\n .collection(\"items\")\n .doc(id)\n .delete();\n };\n\n const updateCartQuantity = (userId, id, quantity) => {\n return firestore\n .collection(\"carts\")\n .doc(userId)\n .collection(\"items\")\n .doc(id)\n .update({ quantity });\n };\n\n // To delete the cart (=subcollection), we have to retrieve all the documents within the collection and delete them.\n const deleteCart = async (userId) => {\n const itemsId = [];\n const docs = await firestore\n .collection(\"carts\")\n .doc(userId)\n .collection(\"items\")\n .get();\n docs.forEach((doc) => itemsId.push(doc.id));\n for (const id of itemsId) {\n deleteFromCart(userId, id);\n }\n };\n\n // Get an user's cart.\n const getCart = async (userId) => {\n const cart = [];\n const items = await firestore\n .collection(\"carts\")\n .doc(userId)\n .collection(\"items\")\n .get();\n items.forEach((item) => cart.push(item.data()));\n return cart;\n };\n\n const cartListener = (userId, callback) => {\n return firestore\n .collection(\"carts\")\n .doc(userId)\n .collection(\"items\")\n .onSnapshot(callback);\n };\n\n return {\n addToCart,\n deleteFromCart,\n updateCartQuantity,\n deleteCart,\n getCart,\n cartListener,\n };\n}\n\nexport default useCart;\n","/home/aureen/the_odin_project/room_homepage/src/hooks/useDesign.js",[],"/home/aureen/the_odin_project/room_homepage/src/hooks/useAddress.js",["609","610","611","612","613","614","615","616","617","618","619","620","621","622","623","624","625","626","627"],"import { useState } from \"react\";\nimport { firestore } from \"../firebase/firebase\";\n\nfunction useAddress() {\n // Add address\n const [firstName, setFirstName] = useState(\"\");\n const [lastName, setLastName] = useState(\"\");\n const [address, setAddress] = useState(\"\");\n const [city, setCity] = useState(\"\");\n const [zipCode, setZipCode] = useState(\"\");\n const [country, setCountry] = useState(\"\");\n const [email, setEmail] = useState(\"\");\n const [phone, setPhone] = useState(\"\");\n const [message, setMessage] = useState(\"\");\n\n // Edit address\n const [isEditing, setIsEditing] = useState(false);\n const [firstNameEdit, setFirstNameEdit] = useState(\"\");\n const [lastNameEdit, setLastNameEdit] = useState(\"\");\n const [addressEdit, setAddressEdit] = useState(\"\");\n const [cityEdit, setCityEdit] = useState(\"\");\n const [zipCodeEdit, setZipCodeEdit] = useState(\"\");\n const [countryEdit, setCountryEdit] = useState(\"\");\n const [emailEdit, setEmailEdit] = useState(\"\");\n const [phoneEdit, setPhoneEdit] = useState(\"\");\n const [messageEdit, setMessageEdit] = useState(\"\");\n\n // Add an address to the user's address book\n const addAddress = async (\n userId,\n firstName,\n lastName,\n address,\n zipCode,\n city,\n country,\n phone,\n email\n ) => {\n const docRef = await firestore\n .collection(\"users\")\n .doc(userId)\n .collection(\"addresses\")\n .doc();\n const { id } = docRef;\n return firestore\n .collection(\"users\")\n .doc(userId)\n .collection(\"addresses\")\n .doc(id)\n .set({\n id,\n firstName,\n lastName,\n address,\n zipCode,\n city,\n country,\n phone,\n email,\n });\n };\n\n const handleAddAddress = async (userId) => {\n setMessage(\"\");\n try {\n await addAddress(\n userId,\n firstName,\n lastName,\n address,\n zipCode,\n city,\n country,\n phone,\n email\n );\n setFirstName(\"\");\n setLastName(\"\");\n setAddress(\"\");\n setZipCode(\"\");\n setCity(\"\");\n setCountry(\"\");\n setPhone(\"\");\n setEmail(\"\");\n setMessage(\"Your address was successfully saved.\");\n } catch (e) {\n setMessage(\"Sorry, we could not add your address.\");\n }\n };\n\n // Automatically enters the previous data in the fields.\n const handleStartEditing = (address) => {\n setIsEditing(true);\n setFirstNameEdit(address.firstName);\n setLastNameEdit(address.lastName);\n setAddressEdit(address.address);\n setCityEdit(address.city);\n setZipCodeEdit(address.zipCode);\n setCountryEdit(address.country);\n setEmailEdit(address.email);\n setPhoneEdit(address.phone);\n };\n\n const editAddress = (\n userId,\n id,\n firstName,\n lastName,\n address,\n zipCode,\n city,\n country,\n phone,\n email\n ) => {\n return firestore\n .collection(\"users\")\n .doc(userId)\n .collection(\"addresses\")\n .doc(id)\n .update({\n firstName,\n lastName,\n address,\n zipCode,\n city,\n country,\n phone,\n email,\n });\n };\n\n const handleEditAddress = async (userId, addressId) => {\n setMessageEdit(\"\");\n try {\n await editAddress(\n userId,\n addressId,\n firstNameEdit,\n lastNameEdit,\n addressEdit,\n zipCodeEdit,\n cityEdit,\n countryEdit,\n phoneEdit,\n emailEdit\n );\n setIsEditing(false);\n } catch (e) {\n setMessageEdit(\"Sorry, we could not update your address.\");\n }\n };\n\n\n // Remove an address from the user's address book\n const deleteAddress = (userId, id) => {\n return firestore\n .collection(\"users\")\n .doc(userId)\n .collection(\"addresses\")\n .doc(id)\n .delete();\n };\n\n // Get the user's addresses\n const getAddresses = async (userId) => {\n const addressBook = [];\n const addresses = await firestore\n .collection(\"users\")\n .doc(userId)\n .collection(\"addresses\")\n .get();\n addresses.forEach((address) => addressBook.push(address.data()));\n return addressBook;\n };\n\n const addressListener = (userId, callback) => {\n return firestore\n .collection(\"users\")\n .doc(userId)\n .collection(\"addresses\")\n .onSnapshot(callback);\n };\n\n return {\n handleAddAddress,\n handleStartEditing,\n handleEditAddress,\n deleteAddress,\n getAddresses,\n addressListener,\n\n firstName,\n setFirstName,\n lastName,\n setLastName,\n address,\n setAddress,\n city,\n setCity,\n zipCode,\n setZipCode,\n country,\n setCountry,\n email,\n setEmail,\n phone,\n setPhone,\n message,\n setMessage,\n isEditing,\n setIsEditing,\n firstNameEdit,\n setFirstNameEdit,\n lastNameEdit,\n setLastNameEdit,\n addressEdit,\n setAddressEdit,\n cityEdit,\n setCityEdit,\n zipCodeEdit,\n setZipCodeEdit,\n countryEdit,\n setCountryEdit,\n emailEdit,\n setEmailEdit,\n phoneEdit,\n setPhoneEdit,\n messageEdit,\n setMessageEdit,\n };\n}\n\nexport default useAddress;\n","/home/aureen/the_odin_project/room_homepage/src/hooks/usePayment.js",["628","629","630","631","632","633","634","635","636"],"import { useState } from \"react\";\nimport { firestore } from \"../firebase/firebase\";\n\nfunction usePayment() {\n // Add card\n const [name, setName] = useState(\"\");\n const [number, setNumber] = useState(\"\");\n const [date, setDate] = useState(\"\");\n const [cvc, setCvc] = useState(\"\");\n const [message, setMessage] = useState(\"\");\n\n // Edit card\n const [nameEdit, setNameEdit] = useState(\"\");\n const [numberEdit, setNumberEdit] = useState(\"\");\n const [dateEdit, setDateEdit] = useState(\"\");\n const [cvcEdit, setCvcEdit] = useState(\"\");\n const [messageEdit, setMessageEdit] = useState(\"\");\n const [isEditing, setIsEditing] = useState(false);\n\n // Add a card to the user's cards list\n const addCard = async (userId, name, number, date, cvc) => {\n const docRef = await firestore\n .collection(\"users\")\n .doc(userId)\n .collection(\"cards\")\n .doc();\n const { id } = docRef;\n return firestore\n .collection(\"users\")\n .doc(userId)\n .collection(\"cards\")\n .doc(id)\n .set({\n id,\n name,\n number,\n date,\n cvc,\n });\n };\n\n const handleAddCard = async (userId) => {\n setMessage(\"\");\n try {\n await addCard(userId, name, number, date, cvc);\n setName(\"\");\n setNumber(\"\");\n setDate(\"\");\n setCvc(\"\");\n setMessage(\"Your card was successfully saved.\");\n } catch (e) {\n setMessage(\"Sorry, we could not add your card.\");\n }\n };\n\n // Remove a card from the user's cards list\n const deleteCard = (userId, id) => {\n return firestore\n .collection(\"users\")\n .doc(userId)\n .collection(\"cards\")\n .doc(id)\n .delete();\n };\n\n // Get the user's cards\n const getCards = async (userId) => {\n const cardsList = [];\n const cards = await firestore\n .collection(\"users\")\n .doc(userId)\n .collection(\"cards\")\n .get();\n cards.forEach((card) => cardsList.push(card.data()));\n return cardsList;\n };\n\n const handleStartEditing = (card) => {\n setIsEditing(true);\n setNameEdit(card.name);\n setNumberEdit(card.number);\n setDateEdit(card.date);\n setCvcEdit(card.cvc);\n };\n\n const handleEditCard = async (userId, cardId) => {\n setMessageEdit(\"\");\n try {\n await editCard(userId, cardId, nameEdit, numberEdit, dateEdit, cvcEdit);\n setIsEditing(false);\n } catch (e) {\n setMessageEdit(\"Sorry, we could not update your card.\");\n }\n };\n\n const editCard = (userId, id, name, number, date, cvc) => {\n return firestore\n .collection(\"users\")\n .doc(userId)\n .collection(\"cards\")\n .doc(id)\n .update({\n name,\n number,\n date,\n cvc,\n });\n };\n\n const cardListener = (userId, callback) => {\n return firestore\n .collection(\"users\")\n .doc(userId)\n .collection(\"cards\")\n .onSnapshot(callback);\n };\n\n return {\n handleAddCard,\n handleStartEditing,\n handleEditCard,\n deleteCard,\n getCards,\n cardListener,\n name,\n setName,\n number,\n setNumber,\n date,\n setDate,\n cvc,\n setCvc,\n message,\n nameEdit,\n setNameEdit,\n numberEdit,\n setNumberEdit,\n dateEdit,\n setDateEdit,\n cvcEdit,\n setCvcEdit,\n messageEdit,\n isEditing,\n setIsEditing,\n addCard,\n };\n}\n\nexport default usePayment;\n","/home/aureen/the_odin_project/room_homepage/src/hooks/useUser.js",[],"/home/aureen/the_odin_project/room_homepage/src/hooks/useCarousel.js",["637","638","639","640"],"import { useState, useEffect } from \"react\";\n\nfunction useCarousel(slides, number) {\n const [currentSlide, setCurrentSlide] = useState(0);\n const [slidesNumber, setSlidesNumber] = useState(number);\n const [slidesGroups, setSlidesGroups] = useState([]);\n const [transition, setTransition] = useState(0);\n const [transitionDuration, setTransitionDuration] = useState(0.3);\n const [isNext, setIsNext] = useState(false); // Indicates the carousel direction (previous/next)\n\n const previous = () => {\n setIsNext(false);\n setTransition((prev) => prev + 100 / slidesGroups.length);\n setCurrentSlide((prev) => {\n return prev === 0 ? slidesGroups.length - 1 : prev - 1;\n });\n };\n\n const next = () => {\n setIsNext(true);\n setTransition((prev) => prev - 100 / slidesGroups.length);\n setCurrentSlide((prev) => {\n return prev === slidesGroups.length - 1 ? 0 : prev + 1;\n });\n };\n\n /* At the end of each transition:\n - The transition duration is set to 0. It allows us to silently reset transform: translateX to 0.\n - The slides order is changed so that there is always a \"previous slide\" and a \"next slide\" to go to without jumping too far.\n - Thanks to useEffect, the transition duration is put back to 0.3s to have a smooth animation.\n */\n const handleTransitionEnd = () => {\n setTransitionDuration(0);\n setTransition(-100 / slidesGroups.length);\n\n if (isNext) {\n setSlidesGroups((prev) => {\n const slides = [...prev];\n slides.pop();\n const prevSlide = slides.shift();\n slides.push(prevSlide);\n slides.push(slides[0]);\n return slides;\n });\n } else {\n setSlidesGroups((prev) => {\n const slides = [...prev];\n slides.shift();\n const lastSlide = slides.pop();\n slides.unshift(lastSlide);\n slides.unshift(slides[slides.length - 1]);\n return slides;\n });\n }\n };\n\n // Organize slides.\n // 1 \"slide\" = 1 group of slidesNumber mini preview pictures.\n useEffect(() => {\n const slidesGroups = [];\n slides.forEach((slide, index) => {\n index % slidesNumber === 0\n ? slidesGroups.push([slide])\n : slidesGroups[slidesGroups.length - 1].push(slide);\n });\n\n // If there aren't enough preview images to fill the last slide, empty space is added to compensate.\n while (slidesGroups[slidesGroups.length - 1].length < slidesNumber) {\n slidesGroups[slidesGroups.length - 1].push(null);\n }\n setSlidesGroups([slidesGroups[slidesGroups.length - 1], ...slidesGroups]);\n setTransition(-100 / (slidesGroups.length + 1));\n }, []);\n\n useEffect(() => {\n if (transitionDuration === 0) {\n setTransitionDuration(0.3);\n }\n }, [transitionDuration]);\n\n return {\n currentSlide,\n slidesNumber,\n slidesGroups,\n setSlidesNumber,\n transition,\n transitionDuration,\n previous,\n next,\n handleTransitionEnd,\n };\n}\n\nexport default useCarousel;\n","/home/aureen/the_odin_project/room_homepage/src/hooks/useWindowSize.js",[],"/home/aureen/the_odin_project/room_homepage/src/index.jsx",[],"/home/aureen/the_odin_project/room_homepage/src/App.jsx",[],"/home/aureen/the_odin_project/room_homepage/src/contexts/AuthContext.jsx",["641"],"import React, { useContext, useState, useEffect } from \"react\";\nimport PropTypes from \"prop-types\";\nimport firebase from \"firebase\";\nimport { auth } from \"../firebase/firebase\";\n\nconst AuthContext = React.createContext();\n\nexport function useAuth() {\n return useContext(AuthContext);\n}\n\nexport function AuthProvider({ children }) {\n const [currentUser, setCurrentUser] = useState();\n const [loading, setLoading] = useState(true);\n\n const signInAnonymously = () => {\n return auth.signInAnonymously();\n };\n\n const signUpFromAnonymous = async (email, password) => {\n const credential = await firebase.auth.EmailAuthProvider.credential(\n email,\n password\n );\n return auth.currentUser.linkWithCredential(credential);\n };\n\n const signUp = (email, password) => {\n return auth.createUserWithEmailAndPassword(email, password);\n };\n\n const signIn = (email, password) => {\n return auth.signInWithEmailAndPassword(email, password);\n };\n\n const signOut = () => {\n return auth.signOut();\n };\n\n const resetPassword = (email) => {\n return auth.sendPasswordResetEmail(email);\n };\n\n useEffect(() => {\n const unsubscribe = auth.onAuthStateChanged((user) => {\n setCurrentUser(user);\n setLoading(false);\n });\n return unsubscribe;\n }, []);\n\n const value = {\n signUp,\n signIn,\n signOut,\n signInAnonymously,\n signUpFromAnonymous,\n currentUser,\n resetPassword,\n };\n\n return (\n <AuthContext.Provider value={value}>\n {!loading && children}\n </AuthContext.Provider>\n );\n}\n\nAuthProvider.propTypes = {\n children: PropTypes.oneOfType([\n PropTypes.arrayOf(PropTypes.node),\n PropTypes.node,\n ]).isRequired,\n};","/home/aureen/the_odin_project/room_homepage/src/contexts/FavoriteContext.jsx",["642","643","644","645"],"import React, { useContext, useState, useEffect } from \"react\";\nimport firebase from \"firebase\";\nimport PropTypes from \"prop-types\";\nimport { firestore } from \"../firebase/firebase\";\nimport { useAuth } from \"./AuthContext\";\n\nconst FavoriteContext = React.createContext();\n\nexport function useFavorite() {\n return useContext(FavoriteContext);\n}\n\nexport function FavoriteProvider({ children }) {\n const { currentUser } = useAuth();\n const [favorites, setFavorites] = useState([]);\n\n // Get a user's saved items\n const getFavorites = async (userId) => {\n const items = await firestore.collection(\"favorites\").doc(userId).get();\n return items.data();\n };\n\n // Add favorite\n const addFavorite = (userId, id) => {\n return firestore\n .collection(\"favorites\")\n .doc(userId)\n .set(\n {\n [id]: true,\n },\n { merge: true }\n );\n };\n\n // Delete favorite\n const deleteFavoriteList = (userId) => {\n return firestore.collection(\"favorites\").doc(userId).delete();\n };\n\n const deleteFavorite = async (userId, id) => {\n await firestore\n .collection(\"favorites\")\n .doc(userId)\n .update({\n [id]: firebase.firestore.FieldValue.delete(),\n });\n\n const favorites = await getFavorites(userId);\n if (Object.keys(favorites).length === 0) {\n deleteFavoriteList(userId);\n }\n };\n\n useEffect(() => {\n if (!currentUser) return;\n const unsubscribe = firestore\n .collection(\"favorites\")\n .doc(currentUser.uid)\n .onSnapshot(async () => {\n const favoritesArray = [];\n const favorites = await getFavorites(currentUser.uid);\n if (!favorites) return;\n for (const favorite of Object.keys(favorites)) {\n favoritesArray.push(favorite);\n }\n setFavorites(favoritesArray);\n });\n return unsubscribe;\n }, [currentUser]);\n\n useEffect(() => {\n if (!currentUser) setFavorites([]);\n }, [currentUser]);\n\n const value = {\n addFavorite,\n deleteFavorite,\n favorites,\n };\n\n return (\n <FavoriteContext.Provider value={value}>\n {children}\n </FavoriteContext.Provider>\n );\n}\n\nFavoriteProvider.propTypes = {\n children: PropTypes.oneOfType([\n PropTypes.arrayOf(PropTypes.node),\n PropTypes.node,\n ]).isRequired,\n};\n","/home/aureen/the_odin_project/room_homepage/src/routes/general/About.jsx",["646"],"/home/aureen/the_odin_project/room_homepage/src/routes/general/Home.jsx",[],"/home/aureen/the_odin_project/room_homepage/src/routes/general/Contact.jsx",["647"],"/home/aureen/the_odin_project/room_homepage/src/routes/shop/Shop.jsx",["648"],"/home/aureen/the_odin_project/room_homepage/src/routes/account/Account.jsx",[],"/home/aureen/the_odin_project/room_homepage/src/routes/shop/checkout/Cart.jsx",["649","650","651","652","653","654","655"],"/home/aureen/the_odin_project/room_homepage/src/routes/account/Favorite.jsx",["656","657","658"],"/home/aureen/the_odin_project/room_homepage/src/routes/account/Entry.jsx",["659"],"/home/aureen/the_odin_project/room_homepage/src/routes/general/HandleShop.jsx",[],"/home/aureen/the_odin_project/room_homepage/src/components/Nav.jsx",["660"],"/home/aureen/the_odin_project/room_homepage/src/components/Carousel.jsx",["661","662","663","664"],"/home/aureen/the_odin_project/room_homepage/src/routes/types/PublicRoute.jsx",["665","666","667"],"import React from \"react\";\nimport { Route, Redirect } from \"react-router-dom\";\nimport { useAuth } from \"../../contexts/AuthContext\";\n\n// User can only access this route if they are logged out.\nfunction PublicRoute({ component: Component, ...rest }) {\n const { currentUser } = useAuth();\n\n return (\n <Route\n {...rest}\n render={(props) => {\n return currentUser && !currentUser.isAnonymous ? (\n <Redirect to=\"/\" />\n ) : (\n <Component {...props} />\n );\n }}\n />\n );\n}\n\nexport default PublicRoute;\n","/home/aureen/the_odin_project/room_homepage/src/routes/types/PrivateRoute.jsx",["668","669","670"],"import React from \"react\";\nimport { Route, Redirect } from \"react-router-dom\";\nimport { useAuth } from \"../../contexts/AuthContext\";\n\n// User can only access those routes if they are logged in.\nfunction PrivateRoute({ component: Component, ...rest }) {\n const { currentUser } = useAuth();\n\n return (\n <Route\n {...rest}\n render={(props) => {\n return currentUser && !currentUser.isAnonymous ? (\n <Component {...props} />\n ) : (\n <Redirect to=\"/account/entry\" />\n );\n }}\n />\n );\n}\n\nexport default PrivateRoute;\n","/home/aureen/the_odin_project/room_homepage/src/routes/shop/orders/Tracking.jsx",["671","672"],"/home/aureen/the_odin_project/room_homepage/src/routes/shop/display/Category.jsx",["673","674","675"],"/home/aureen/the_odin_project/room_homepage/src/routes/shop/display/Main.jsx",["676","677","678","679"],"/home/aureen/the_odin_project/room_homepage/src/routes/shop/display/ItemDetails.jsx",["680","681","682","683","684","685","686","687","688","689","690","691","692","693","694","695","696"],"/home/aureen/the_odin_project/room_homepage/src/routes/shop/display/Design.jsx",["697","698","699","700"],"/home/aureen/the_odin_project/room_homepage/src/routes/shop/display/NewIn.jsx",["701","702","703"],"/home/aureen/the_odin_project/room_homepage/src/routes/shop/checkout/Payment.jsx",["704","705","706","707","708","709","710","711","712","713","714"],"/home/aureen/the_odin_project/room_homepage/src/routes/shop/checkout/Personal.jsx",["715","716","717","718"],"/home/aureen/the_odin_project/room_homepage/src/routes/shop/checkout/Confirmation.jsx",["719","720","721","722","723","724","725","726","727","728"],"/home/aureen/the_odin_project/room_homepage/src/routes/account/settings/Orders.jsx",["729"],"/home/aureen/the_odin_project/room_homepage/src/components/account/AccountNav.jsx",["730"],"/home/aureen/the_odin_project/room_homepage/src/routes/account/settings/Addresses.jsx",["731","732","733","734","735","736","737"],"/home/aureen/the_odin_project/room_homepage/src/routes/account/settings/Payment.jsx",["738","739","740","741","742","743","744","745","746","747","748","749"],"/home/aureen/the_odin_project/room_homepage/src/routes/account/settings/Settings.jsx",[],"/home/aureen/the_odin_project/room_homepage/src/components/shop/nav/ShopNav.jsx",["750"],"/home/aureen/the_odin_project/room_homepage/src/components/shop/nav/Nav.jsx",["751","752","753","754"],"/home/aureen/the_odin_project/room_homepage/src/components/shop/nav/Footer.jsx",["755","756"],"/home/aureen/the_odin_project/room_homepage/src/components/account/SignIn.jsx",["757","758","759"],"/home/aureen/the_odin_project/room_homepage/src/components/account/SignUp.jsx",["760","761","762","763","764"],"/home/aureen/the_odin_project/room_homepage/src/components/shop/display/ShopItemPreview.jsx",["765","766","767","768","769"],"/home/aureen/the_odin_project/room_homepage/src/components/shop_handling/AddShopItem.jsx",["770","771","772","773","774","775","776","777","778","779","780","781","782","783","784","785","786","787","788","789","790","791","792","793","794","795","796","797","798","799","800","801","802","803","804","805","806","807","808","809","810","811","812","813","814","815","816","817","818","819","820","821","822","823","824","825","826","827","828","829","830","831","832","833","834","835","836","837","838","839","840","841","842","843"],"/home/aureen/the_odin_project/room_homepage/src/components/account/Order.jsx",["844","845","846","847","848","849"],"/home/aureen/the_odin_project/room_homepage/src/components/shop/display/Filters.jsx",["850","851","852","853","854","855","856","857","858","859","860","861","862","863","864","865","866","867","868","869","870","871","872","873","874","875","876","877","878","879","880","881","882","883","884","885","886","887","888","889","890","891","892","893","894","895","896","897"],"/home/aureen/the_odin_project/room_homepage/src/components/shop/display/SideFilters.jsx",["898","899","900","901","902","903","904","905","906","907","908","909","910","911","912","913","914","915","916","917","918","919","920","921","922","923","924","925","926","927","928","929","930","931","932","933","934","935","936","937","938","939","940","941","942","943","944","945","946","947","948","949"],"/home/aureen/the_odin_project/room_homepage/src/components/shop/display/Sort.jsx",["950"],"/home/aureen/the_odin_project/room_homepage/src/components/FullCarousel.jsx",["951","952","953","954","955"],"/home/aureen/the_odin_project/room_homepage/src/components/shop/display/Designs.jsx",["956","957","958","959","960","961","962"],"/home/aureen/the_odin_project/room_homepage/src/components/shop/display/Recommendations.jsx",["963","964","965","966","967"],"/home/aureen/the_odin_project/room_homepage/src/components/shop/display/ImagesPreview.jsx",["968","969","970"],"/home/aureen/the_odin_project/room_homepage/src/components/shop/cart/CartPreview.jsx",["971","972","973","974","975","976","977","978"],"/home/aureen/the_odin_project/room_homepage/src/components/shop/checkout/Order.jsx",["979","980","981","982","983","984","985","986","987","988","989"],"/home/aureen/the_odin_project/room_homepage/src/components/account/AccessSettings.jsx",[],"/home/aureen/the_odin_project/room_homepage/src/components/shop/nav/SideNav.jsx",["990","991","992","993","994","995"],"/home/aureen/the_odin_project/room_homepage/src/components/shop/display/ImageMagnifier.jsx",[],"/home/aureen/the_odin_project/room_homepage/src/components/shop/cart/CartItem.jsx",["996","997","998","999","1000","1001","1002","1003","1004","1005","1006"],"/home/aureen/the_odin_project/room/src/index.jsx",[],["1007","1008","1009","1010","1011"],"/home/aureen/the_odin_project/room/src/App.jsx",[],"/home/aureen/the_odin_project/room/src/contexts/AuthContext.jsx",["1012"],"/home/aureen/the_odin_project/room/src/contexts/FavoriteContext.jsx",["1013","1014","1015","1016"],"/home/aureen/the_odin_project/room/src/routes/general/About.jsx",["1017"],"import React from \"react\";\nimport styled from \"styled-components\";\nimport Nav from \"../../components/Nav\";\n\nfunction About() {\n return (\n <Container>\n <Nav />\n <Image\n src=\"https://firebasestorage.googleapis.com/v0/b/room-f191c.appspot.com/o/about%2Fabout.jpg?alt=media&token=cdb4b49d-b7dd-4db1-87fb-3388ba0b0dd6\"\n alt=\"Furnitures\"\n />\n <Center>\n <Content>\n <Title>About Us</Title>\n\n <Heading>\n Our design philosophy is simple: interiors matter. They matter\n because they influence how we feel, how we act and how we live,\n often without us realising it.\n </Heading>\n\n <TextDropCap>\n These, and many more, are the backdrops to life’s most memorable\n moments and each one has a significant impact on us, some without us\n even realising. And, so, we create interiors that matter—the kind of\n interiors that are worthy of life’s memorable moments.\n </TextDropCap>\n\n <Text>\n Extraordinary interiors may call for bespoke furniture which is why\n we offer a custom furniture service for our discerning clients. To\n design and manufacture extra special furniture designs for our\n clients, we commission the best the industry has to offer in the\n form of proven and reliable product designers and artisans. Whether\n built-in cabinetry or a unique custom-made furniture piece, we\n guarantee that we will create the perfect piece for your project\n when the right thing just can’t be found.\n </Text>\n </Content>\n </Center>\n </Container>\n );\n}\n\nexport default About;\n\nconst colors = {\n black: \"hsl(0, 0%, 0%)\",\n grey: \"hsl(0, 0%, 63%)\",\n gold: \"hsl(35, 49%, 78%)\",\n};\n\nconst Container = styled.div`\n display: flex;\n height: 100vh;\n max-width: 100%;\n max-height: 100%;\n\n @media all and (max-width: 576px) {\n flex-direction: column;\n }\n`;\n\nconst Center = styled.div`\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 3rem 0;\n max-width: 50%;\n\n @media all and (max-width: 1000px) {\n max-width: initial;\n }\n`;\n\nconst Title = styled.div`\n text-transform: uppercase;\n text-align: center;\n color: ${colors.gold};\n`;\n\nconst Content = styled.section`\n max-width: 70%;\n`;\n\nconst Heading = styled.div`\n font-family: \"Spartan\", sans-serif;\n text-transform: lowercase;\n font-size: 1.5rem;\n text-align: center;\n margin: 2rem 0;\n\n &:after {\n position: relative;\n display: inline-block;\n content: \"\";\n height: 1px;\n width: 3rem;\n background-color: ${colors.gold};\n margin-top: 2rem;\n }\n`;\n\nconst TextDropCap = styled.p`\n margin: 2rem 0;\n font-weight: 600;\n line-height: 1.5rem;\n\n &:first-letter {\n float: left;\n font-size: 3rem;\n line-height: 1;\n margin-right: 0.5rem;\n }\n`;\n\nconst Text = styled.p`\n line-height: 1.5rem;\n color: ${colors.grey};\n`;\n\nconst Image = styled.img`\n width: 100%;\n min-width: 0;\n object-fit: cover;\n`;\n\n","/home/aureen/the_odin_project/room/src/routes/general/Contact.jsx",["1018","1019"],"import React, { useState } from \"react\";\nimport styled from \"styled-components\";\nimport Nav from \"../../components/Nav\";\n\n// Social Icons\nimport { ReactComponent as Facebook } from \"../../assets/icons/icon-facebook.svg\";\nimport { ReactComponent as Instagram } from \"../../assets/icons/icon-instagram.svg\";\nimport { ReactComponent as Pinterest } from \"../../assets/icons/icon-pinterest.svg\";\nimport { ReactComponent as Twitter } from \"../../assets/icons/icon-twitter.svg\";\n\nfunction Contact() {\n const [firstName, setFirstName] = useState(\"\");\n const [lastName, setLastName] = useState(\"\");\n const [email, setEmail] = useState(\"\");\n const [phone, setPhone] = useState(\"\");\n const [message, setMessage] = useState(\"\");\n const [success, setSuccess] = useState(\"\");\n\n const handleFormSubmit = (e) => {\n e.preventDefault();\n setSuccess(\"Your message has been sent.\");\n };\n\n return (\n <>\n <Nav />\n <Container>\n <Image>\n <Heading>We'd love to hear from you</Heading>\n </Image>\n <Center>\n <Heading2>Contact Us</Heading2>\n <Form onSubmit={handleFormSubmit}>\n <Field>\n <Label htmlFor=\"first_name\">First Name</Label>\n <Input\n type=\"text\"\n value={firstName}\n id=\"first_name\"\n onChange={(e) => setFirstName(e.target.value)}\n placeholder=\"Enter your first name\"\n required\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"last_name\">Last Name</Label>\n <Input\n type=\"text\"\n value={lastName}\n id=\"last_name\"\n onChange={(e) => setLastName(e.target.value)}\n placeholder=\"Enter your last name\"\n required\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"email\">Email</Label>\n <Input\n type=\"email\"\n id=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder=\"Enter your email\"\n required\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"phone\">Phone Number</Label>\n <Input\n type=\"tel\"\n id=\"phone\"\n value={phone}\n onChange={(e) => setPhone(e.target.value)}\n placeholder=\"Enter your phone number\"\n required\n />\n </Field>\n\n <MessageField>\n <Label htmlFor=\"message\">Message</Label>\n <TextArea\n value={message}\n id=\"message\"\n onChange={(e) => setMessage(e.target.value)}\n placeholder=\"Enter your message\"\n rows={1}\n required\n />\n </MessageField>\n\n <Field>\n <SubmitBtn>Send message ⟶</SubmitBtn>\n {success && <Success>{success}</Success>}\n </Field>\n </Form>\n\n <Information>\n <Field>\n <InformationType>Email</InformationType>\n <div>enquiries@room.com</div>\n </Field>\n\n <Field>\n <InformationType>Phone</InformationType>\n <div>+1 23 456 789</div>\n </Field>\n </Information>\n\n <Social>\n <InformationType>Follow us</InformationType>\n <Icon href=\"#\">\n <Facebook />\n </Icon>\n\n <Icon href=\"#\">\n <Instagram />\n </Icon>\n\n <Icon href=\"#\">\n <Pinterest />\n </Icon>\n\n <Icon href=\"#\">\n <Twitter />\n </Icon>\n </Social>\n </Center>\n </Container>\n </>\n );\n}\n\nexport default Contact;\n\n// Styled Components\nconst colors = {\n white: \"hsl(0, 100%, 100%)\",\n black: \"hsl(0, 0%, 0%)\",\n background: \"hsl(10, 5%, 90%)\",\n darkGrey: \"hsl(0, 0%, 20%)\",\n grey: \"hsl(0, 0%, 50%)\",\n border: \"hsl(0, 0%, 70%)\",\n};\n\nconst grid = ` \n display: grid;\n grid-template-columns: repeat(2, 1fr);\n grid-gap: 3rem;\n\n @media all and (max-width: 576px) {\n grid-template-columns: 1fr;\n }\n`;\n\nconst input = `\n border: none;\n border-bottom: 1px solid ${colors.border};\n padding: .5rem 0 .25rem 0;\n font-family: 'Source Sans Pro', sans-serif;\n\n &::placeholder {\n color: ${colors.border};\n }\n\n &:focus {\n border-bottom: 1px solid ${colors.black};\n }`;\n\nconst label = `\n text-transform: uppercase;\n font-size: .825rem;\n letter-spacing: 1px;\n`;\n\n// Left - Image\nconst Container = styled.div`\n position: relative;\n width: 100vw;\n height: 100vh;\n max-width: 100%;\n max-height: 100%;\n display: flex;\n\n @media all and (max-width: 830px) {\n flex-direction: column;\n }\n`;\n\nconst Image = styled.div`\n background: url(\"https://firebasestorage.googleapis.com/v0/b/room-f191c.appspot.com/o/contact%2Froom.png?alt=media&token=758d37b5-6d9d-427b-a387-f81f6380fdd4\");\n background-size: cover;\n background-position: center;\n background-repeat: no-repeat;\n width: 50%;\n height: 100%;\n display: flex;\n justify-content: center;\n\n @media all and (max-width: 830px) {\n width: 100%;\n background-position: 0 60%;\n align-items: center;\n padding: 5rem 0;\n }\n`;\n\nconst Heading = styled.h2`\n font-size: 3.5rem;\n line-height: 4rem;\n color: ${colors.white};\n font-family: \"Playfair Display\", sans-serif;\n max-width: 35rem;\n margin-top: 10rem;\n padding: 0 5rem;\n\n @media all and (max-width: 830px) {\n margin-top: 0rem;\n }\n`;\n\n// Right - Contact\n// Contact Form\nconst Heading2 = styled.h3`\n font-size: 2rem;\n line-height: 2.75rem;\n font-family: \"Playfair Display\", sans-serif;\n margin: 5rem 0;\n\n @media all and (max-width: 830px) {\n margin: 3rem 0;\n }\n`;\n\nconst Center = styled.div`\n display: flex;\n flex-direction: column;\n padding: 5rem;\n flex: 1;\n`;\n\nconst Form = styled.form`\n ${grid}\n`;\n\nconst Field = styled.div`\n display: flex;\n flex-direction: column;\n`;\n\nconst MessageField = styled(Field)`\n grid-column: 1 / -1;\n`;\n\nconst Label = styled.label`\n ${label}\n`;\n\nconst Input = styled.input`\n ${input}\n`;\n\nconst TextArea = styled.textarea`\n ${input}\n`;\n\nconst SubmitBtn = styled.button`\n align-self: flex-start;\n padding: 0;\n cursor: pointer;\n transition: all 0.2s linear;\n\n &:hover {\n letter-spacing: 0.5px;\n }\n`;\n\n// Room Informations\nconst Social = styled.div`\n display: flex;\n align-items: center;\n margin-top: 3rem;\n\n & > div:first-child:after {\n content: \"\";\n display: inline-block;\n height: 1px;\n width: 5rem;\n vertical-align: middle;\n margin: 0 1rem;\n background-color: ${colors.grey};\n }\n`;\n\nconst Information = styled.div`\n ${grid}\n margin-top: 5rem;\n`;\n\nconst InformationType = styled.div`\n ${label};\n color: ${colors.grey};\n margin-bottom: 0.25rem;\n`;\n\nconst Icon = styled.a`\n display: inline-block;\n color: ${colors.grey};\n cursor: pointer;\n margin: 0 0.25rem;\n\n &:hover {\n color: ${colors.black};\n }\n`;\n\nconst Success = styled.div`\n color: ${colors.grey};\n margin: 1rem 0;\n`;","/home/aureen/the_odin_project/room/src/routes/general/Home.jsx",[],"/home/aureen/the_odin_project/room/src/routes/shop/Shop.jsx",["1020"],"import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport styled from \"styled-components\";\nimport { Switch, Route } from \"react-router-dom\";\nimport useWindowSize from \"../../hooks/useWindowSize\";\nimport Nav from \"../../components/shop/nav/Nav\";\nimport ShopNav from \"../../components/shop/nav/ShopNav\";\nimport Footer from \"../../components/shop/nav/Footer\";\nimport Favorite from \"../account/Favorite\";\nimport Entry from \"../account/Entry\";\nimport PublicRoute from \"../types/PublicRoute\";\nimport HandleShop from \"../general/HandleShop\";\nimport Tracking from \"./orders/Tracking\";\nimport Category from \"./display/Category\";\nimport ItemDetails from \"./display/ItemDetails\";\nimport Main from \"./display/Main\";\nimport NewIn from \"./display/NewIn\";\nimport Design from \"./display/Design\";\nimport Cart from \"./checkout/Cart\";\nimport Payment from \"./checkout/Payment\";\nimport Personal from \"./checkout/Personal\";\nimport Confirmation from \"./checkout/Confirmation\";\n\nfunction Shop({ match }) {\n const { windowSize } = useWindowSize();\n\n return (\n <Wrapper>\n <header>\n <Nav />\n {windowSize.width > 500 && <ShopNav />}\n </header>\n\n <Container>\n <Switch>\n <Route exact path={`${match.path}`} component={Main} />\n <PublicRoute exact path={`${match.path}/entry`} component={Entry} />\n <Route exact path={`${match.path}/cart`} component={Cart} />\n <Route exact path={`${match.path}/payment`} component={Payment} />\n <Route exact path={`${match.path}/personal`} component={Personal} />\n <Route\n exact\n path={`${match.path}/confirmation/:id`}\n component={Confirmation}\n />\n <Route exact path={`${match.path}/favorite`} component={Favorite} />\n <Route exact path={`${match.path}/tracking`} component={Tracking} />\n <Route\n exact\n path={`${match.path}/handleshop`}\n component={HandleShop}\n />\n <Route\n exact\n path={`${match.path}/item/:itemId`}\n render={(props) => (\n <ItemDetails key={props.match.params.itemId} {...props} />\n )}\n />\n <Route exact path={`${match.path}/new_in`} component={NewIn} />\n <Route exact path={`${match.path}/design/:id`} component={Design} />\n <Route exact path={`${match.path}/:category`} component={Category} />\n </Switch>\n </Container>\n\n <Footer />\n </Wrapper>\n );\n}\n\nShop.propTypes = {\n match: PropTypes.shape({\n path: PropTypes.string,\n params: PropTypes.shape({\n itemId: PropTypes.string,\n }),\n }),\n};\n\nShop.defaultProps = {\n match: {\n path: \"\",\n },\n};\n\nexport default Shop;\n\nconst Wrapper = styled.div`\n display: flex;\n flex-direction: column;\n height: 100vh;\n`;\n\nconst Container = styled.div`\n display: flex;\n justify-content: center;\n flex: 1;\n`;\n","/home/aureen/the_odin_project/room/src/routes/account/Account.jsx",[],"/home/aureen/the_odin_project/room/src/firebase/firebase.js",[],"/home/aureen/the_odin_project/room/src/hooks/useWindowSize.js",[],"/home/aureen/the_odin_project/room/src/routes/account/Favorite.jsx",["1021","1022","1023"],"import React, { useState, useEffect } from \"react\";\nimport styled from \"styled-components\";\nimport { Link } from \"react-router-dom\";\nimport { useFavorite } from \"../../contexts/FavoriteContext\";\nimport ShopItemPreview from \"../../components/shop/display/ShopItemPreview\";\nimport useShop from \"../../hooks/useShop\";\n\n// Icons\nimport { ReactComponent as Basket } from \"../../assets/icons/icon-basket.svg\";\n\nfunction Favorite() {\n const { getItem } = useShop();\n const { favorites } = useFavorite([]);\n const [favoriteItems, setFavoriteItems] = useState([]);\n\n useEffect(() => {\n (async () => {\n const favoritesItems = [];\n for (const favorite of favorites) {\n const item = await getItem(favorite);\n favoritesItems.push(item);\n }\n setFavoriteItems(favoritesItems);\n })();\n }, [favorites]);\n\n return (\n <Container>\n <div>\n <Heading>Favorites</Heading>\n {favorites.length === 0 ? (\n <Empty>\n <Basket />\n <EmptyText>\n It seems that you haven't saved any items yet.\n </EmptyText>\n <div>We have a lot of lovely ideas to help you fill it.</div>\n <Link to=\"/shop\">\n <Button>Inspire Me</Button>\n </Link>\n </Empty>\n ) : (\n <>\n <ItemsList>\n {favoriteItems.map((item) => {\n return (\n <li key={item.id}>\n <ShopItemPreview\n name={item.name}\n images={item.images}\n price={item.price}\n id={item.id}\n isFavorite={favorites.includes(item.id)}\n />\n </li>\n );\n })}\n </ItemsList>\n </>\n )}\n </div>\n </Container>\n );\n}\n\nexport default Favorite;\n\n// Styled Components\nconst colors = {\n button: \"hsl(0, 0%, 27%)\", // Darker grey\n text: \"hsl(0, 0%, 95%)\", // White\n};\n\nconst Container = styled.div`\n display: flex;\n justify-content: center;\n flex: 1;\n\n padding: 5rem 0;\n\n @media all and (min-width: 600px) {\n padding: 5rem 3rem;\n }\n`;\n\nconst Heading = styled.h1`\n margin-bottom: 2rem;\n font-size: 2rem;\n line-height: 2.75rem;\n font-family: \"Playfair Display\", sans-serif;\n`;\n\nconst ItemsList = styled.ul`\n display: grid;\n grid-gap: 3vw;\n\n @media all and (min-width: 500px) {\n grid-template-columns: repeat(2, 1fr);\n }\n\n @media all and (min-width: 992px) {\n grid-template-columns: repeat(3, 1fr);\n }\n\n @media all and (min-width: 1300px) {\n grid-template-columns: repeat(4, 1fr);\n }\n`;\n\nconst Empty = styled.div`\n display: flex;\n flex-direction: column;\n align-items: center;\n`;\n\nconst EmptyText = styled.div`\n font-family: \"Playfair Display\", sans-serif;\n font-size: 1.125rem;\n`;\n\nconst Button = styled.button`\n margin-top: 2.5rem;\n font-family: \"Source Sans Pro\", sans-serif;\n text-transform: uppercase;\n font-size: 0.9rem;\n color: ${colors.text};\n background: ${colors.button};\n align-self: center;\n padding: 0.5rem 1rem;\n cursor: pointer;\n`;\n","/home/aureen/the_odin_project/room/src/routes/account/Entry.jsx",["1024"],"import React, { useState, useEffect } from \"react\";\nimport styled from \"styled-components\";\nimport PropTypes from \"prop-types\";\nimport SignIn from \"../../components/account/SignIn\";\nimport SignUp from \"../../components/account/SignUp\";\n\nimport background from \"../../assets/images/entry.png\";\n\nfunction Entry({ location }) {\n const [isFlipped, setIsFlipped] = useState(false);\n const [isPaying, setIsPaying] = useState(false);\n\n useEffect(() => {\n location.state && location.state.isPaying\n ? setIsPaying(true)\n : setIsPaying(false);\n }, []);\n\n const flip = () => {\n setIsFlipped(!isFlipped);\n };\n\n return (\n <Container>\n <Main>\n <Card>\n <CardInner isFlipped={isFlipped}>\n <CardSide>\n <SignUp flip={flip} isPaying={isPaying} />\n </CardSide>\n <CardBackSide>\n <SignIn flip={flip} isPaying={isPaying} />\n </CardBackSide>\n </CardInner>\n </Card>\n </Main>\n </Container>\n );\n}\n\nexport default Entry;\n\nEntry.propTypes = {\n location: PropTypes.shape({\n state: PropTypes.shape({\n isPaying: PropTypes.bool,\n }),\n }).isRequired,\n};\n\n// Styled components\nconst colors = {\n primary: \"hsl(0, 0%, 45%)\", // Grey\n secondary: \"hsl(0, 0%, 27%)\", // Darker grey\n background: \"hsl(0, 0%, 100%)\",\n};\n\nconst Container = styled.div`\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 1;\n background: url(${background});\n background-size: cover;\n padding: 3rem 0;\n`;\n\nconst Main = styled.div`\n display: flex;\n align-items: start;\n max-width: 1400px;\n`;\n\nconst Card = styled.div`\n width: calc(100vw - 16px);\n max-width: 500px;\n border: 1px solid ${colors.secondary};\n height: 45rem;\n perspective: 150rem;\n padding: 0 5rem;\n background: ${colors.background};\n`;\n\nconst CardInner = styled.div`\n position: relative;\n transition: transform 0.8s;\n transform-style: preserve-3d;\n transform: ${(props) => (props.isFlipped ? \"rotateY(180deg)\" : \"\")};\n height: 100%;\n width: 100%;\n`;\n\nconst CardSide = styled.div`\n position: absolute;\n width: 100%;\n height: 100%;\n backface-visibility: hidden;\n display: flex;\n flex-direction: column;\n justify-content: center;\n`;\n\nconst CardBackSide = styled(CardSide)`\n transform: rotateY(180deg);\n`;\n","/home/aureen/the_odin_project/room/src/routes/general/HandleShop.jsx",[],"/home/aureen/the_odin_project/room/src/components/Nav.jsx",["1025"],"import React, { useState } from \"react\";\nimport styled from \"styled-components\";\nimport { Link } from \"react-router-dom\";\nimport { ReactComponent as Logo } from \"../assets/icons/logo.svg\";\n\nfunction Nav() {\n // For mobile users\n const [isNavOpen, setIsNavOpen] = useState(false);\n\n const handleOpenNav = () => {\n setIsNavOpen(true);\n };\n\n const handleCloseNav = () => {\n setIsNavOpen(false);\n };\n\n return (\n <Container>\n <Button onClick={handleOpenNav}>\n <svg width=\"20\" height=\"14\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M20 12v2H0v-2h20zm0-6v2H0V6h20zm0-6v2H0V0h20z\"\n fill={`${colors.primary}`}\n fillRule=\"evenodd\"\n />\n </svg>\n </Button>\n <BrandMobile>\n <Logo />\n </BrandMobile>\n <Navigation isNavOpen={isNavOpen}>\n <Brand>\n <Logo />\n </Brand>\n <Button onClick={handleCloseNav}>\n <svg width=\"16\" height=\"16\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M14.364.222l1.414 1.414L9.414 8l6.364 6.364-1.414 1.414L8 9.414l-6.364 6.364-1.414-1.414L6.586 8 .222 1.636 1.636.222 8 6.586 14.364.222z\"\n fill=\"#000\"\n fillRule=\"evenodd\"\n opacity=\".201\"\n />\n </svg>\n </Button>\n <Link to=\"/\">\n <NavLink>home</NavLink>\n </Link>\n <Link to=\"/shop\">\n <NavLink>shop</NavLink>\n </Link>\n <Link to=\"/about\">\n <NavLink>about</NavLink>\n </Link>\n <Link to=\"/contact\">\n <NavLink>contact</NavLink>\n </Link>\n </Navigation>\n </Container>\n );\n}\n\nexport default Nav;\n\nconst colors = {\n primary: \"#fff\",\n};\n\nconst Container = styled.div`\n position: absolute;\n z-index: 1;\n padding: 1rem;\n display: grid;\n align-items: baseline;\n\n @media all and (max-width: 600px) {\n grid-template-columns: 1fr auto 1fr;\n width: 100vw;\n max-width: 100%;\n }\n`;\n\nconst Button = styled.button`\n display: none;\n padding: 1rem;\n justify-self: start;\n cursor: pointer;\n\n @media all and (max-width: 600px) {\n display: inline-block;\n }\n`;\n\nconst Navigation = styled.nav`\n // Absolute positioning for mobile navigation\n position: absolute;\n font-family: \"Spartan\", sans-serif;\n color: ${colors.primary};\n z-index: 2;\n display: flex;\n align-items: center;\n left: 5rem;\n top: 2.5rem;\n\n @media all and (max-width: 1000px) {\n flex-direction: column;\n left: 2.5rem;\n top: 2.5rem;\n }\n\n @media all and (max-width: 650px) {\n left: 1rem;\n top: 1rem;\n }\n\n @media all and (max-width: 600px) {\n display: ${(props) => (props.isNavOpen ? \"flex\" : \"none\")};\n flex-direction: row;\n background: ${colors.primary};\n width: 100vw;\n top: 0;\n left: 0;\n height: 3.5rem;\n }\n`;\n\nconst Brand = styled.span`\n font-size: 1.5rem;\n margin: 0 2rem;\n color: ${colors.primary};\n\n @media all and (max-width: 600px) {\n display: none;\n }\n`;\n\nconst BrandMobile = styled(Brand)`\n display: none;\n\n @media all and (max-width: 600px) {\n display: inline-block;\n }\n`;\n\nconst NavLink = styled.span`\n position: relative;\n margin: 0 0.5rem;\n color: ${colors.primary};\n\n @media all and (max-width: 600px) {\n color: #000;\n }\n\n &:hover:after {\n content: \"\";\n position: absolute;\n bottom: -1rem;\n left: 50%;\n margin-left: -12.5px;\n width: 25px;\n height: 2px;\n background: ${colors.primary};\n\n @media all and (max-width: 1000px) {\n bottom: 0;\n height: 1px;\n }\n\n @media all and (max-width: 600px) {\n background: #000;\n height: 2px;\n bottom: -1rem;\n }\n }\n`;\n","/home/aureen/the_odin_project/room/src/components/Carousel.jsx",["1026","1027","1028","1029"],"import React, { useState, useEffect, useRef } from \"react\";\nimport styled from \"styled-components\";\nimport PropTypes from \"prop-types\";\nimport { Link } from \"react-router-dom\";\n\n// Images\nimport { ReactComponent as AngleLeft } from \"../assets/icons/icon-angle-left.svg\";\nimport { ReactComponent as AngleRight } from \"../assets/icons/icon-angle-right.svg\";\n\nfunction Carousel({ images, text }) {\n const cardRef = useRef();\n const [currentSlide, setCurrentSlide] = useState(0);\n const [slides, setSlides] = useState([images[images.length - 1], ...images]);\n const [transition, setTransition] = useState(-100);\n const [transitionDuration, setTransitionDuration] = useState(0.3);\n const [isNext, setIsNext] = useState(false); // Indicates the carousel direction (previous/next)\n\n // Functions\n const next = () => {\n setIsNext(true);\n setTransition((prev) => prev - 100);\n setCurrentSlide((prev) => {\n return prev === images.length - 1 ? 0 : prev + 1;\n });\n cardRef.current.classList.add(\"active\");\n };\n\n const previous = () => {\n setIsNext(false);\n setTransition((prev) => prev + 100);\n setCurrentSlide((prev) => {\n return prev === 0 ? images.length - 1 : prev - 1;\n });\n cardRef.current.classList.add(\"active\");\n };\n\n /* At the end of each transition:\n - The transition duration is set to 0. It allows us to silently reset transform: translateX to 0.\n - The slides order is changed so that there is always a \"previous slide\" and a \"next slide\" to go to without jumping too far.\n - Thanks to useEffect, the transition duration is put back to 0.3s to have a smooth animation.\n */\n const handleTransitionEnd = () => {\n setTransitionDuration(0);\n setTransition(-100);\n\n if (isNext) {\n setSlides((prev) => {\n const slides = [...prev];\n slides.pop();\n const prevSlide = slides.shift();\n slides.push(prevSlide);\n slides.push(slides[0]);\n return slides;\n });\n } else {\n setSlides((prev) => {\n const slides = [...prev];\n slides.shift();\n const lastSlide = slides.pop();\n slides.unshift(lastSlide);\n slides.unshift(slides[slides.length - 1]);\n return slides;\n });\n }\n cardRef.current.classList.remove(\"active\");\n };\n\n useEffect(() => {\n if (transitionDuration === 0) {\n setTransitionDuration(0.3);\n }\n }, [transitionDuration]);\n\n return (\n <Container>\n <CarouselComponent>\n <Slider>\n <Images\n onTransitionEnd={handleTransitionEnd}\n transition={transition}\n transitionDuration={transitionDuration}\n >\n {slides.map((image, index) => {\n return <Image key={index} src={image} alt=\"Hero\" />;\n })}\n </Images>\n </Slider>\n <Menu>\n <Button type=\"button\" onClick={previous}>\n <AngleLeft />\n </Button>\n <Button type=\"button\" onClick={next}>\n <AngleRight />\n </Button>\n </Menu>\n </CarouselComponent>\n\n <Center>\n <Card ref={cardRef}>\n <Title>{text[currentSlide].title}</Title>\n <Text>{text[currentSlide].description}</Text>\n <Link to=\"/shop\">\n <ShopLink>\n Shop now\n <Arrow width=\"40\" height=\"12\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M34.05 0l5.481 5.527h.008v.008L40 6l-.461.465v.063l-.062-.001L34.049 12l-.662-.668 4.765-4.805H0v-1h38.206l-4.82-4.86L34.05 0z\"\n fill=\"currentColor\"\n fillRule=\"nonzero\"\n />\n </Arrow>\n </ShopLink>\n </Link>\n </Card>\n </Center>\n </Container>\n );\n}\n\nCarousel.propTypes = {\n images: PropTypes.arrayOf(PropTypes.string),\n text: PropTypes.arrayOf(\n PropTypes.shape({\n title: PropTypes.string,\n description: PropTypes.string,\n })\n ),\n};\n\nCarousel.defaultProps = {\n images: [],\n text: [{ title: \"\", description: \"\" }],\n};\n\nexport default Carousel;\n\n\nconst colors = {\n black: \"hsl(0, 0%, 0%)\",\n darkGrey: \"hsl(0, 0%, 27%)\",\n};\n\nconst size = `\n width: 100%;\n height: 100%;\n`;\n\nconst Container = styled.div`\n display: flex;\n\n @media all and (max-width: 600px) {\n flex-direction: column;\n }\n`;\n\nconst CarouselComponent = styled.div`\n position: relative;\n max-width: 840px;\n max-height: 534px;\n min-width: 0;\n height: 100%;\n`;\n\nconst Slider = styled.div`\n ${size}\n overflow: hidden;\n`;\n\nconst Images = styled.div`\n ${size}\n transform: translateX(${(props) => props.transition}%);\n transition: transform ${(props) => props.transitionDuration}s ease-in;\n display: flex;\n`;\n\nconst Menu = styled.div`\n position: absolute;\n display: flex;\n left: 100%;\n bottom: 0;\n\n @media all and (max-width: 1170px) {\n left: initial;\n right: 0;\n }\n`;\n\nconst Button = styled.button`\n background: ${colors.black};\n padding: 1.5rem 2rem;\n cursor: pointer;\n color: #fff;\n\n &:hover {\n background: ${colors.darkGrey};\n }\n`;\n\nconst Image = styled.img`\n width: 100%;\n object-fit: cover;\n`;\n\nconst Center = styled.div`\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1rem 0;\n`;\n\nconst Card = styled.div`\n max-width: 70%;\n min-width: 450px;\n padding: 2rem;\n transition: all 0.25s ease-in-out;\n\n @media all and (max-width: 576px) {\n min-width: 0;\n padding: 1rem;\n }\n`;\n\nconst ShopLink = styled.span`\n text-transform: uppercase;\n letter-spacing: 0.5rem;\n font-weight: 300;\n font-size: 1.25rem;\n margin-top: 2rem;\n display: inline-block;\n cursor: pointer;\n\n &:hover {\n color: ${colors.grey};\n }\n`;\n\nconst Text = styled.p`\n line-height: 1.25rem;\n color: ${colors.grey};\n`;\n\nconst Arrow = styled.svg`\n margin-left: 2rem;\n`;\n\nconst Title = styled.h1`\n font-size: 2.75rem;\n font-weight: 300;\n margin-bottom: 2rem;\n`;\n","/home/aureen/the_odin_project/room/src/routes/types/PublicRoute.jsx",["1030","1031","1032"],"/home/aureen/the_odin_project/room/src/routes/types/PrivateRoute.jsx",["1033","1034","1035"],"/home/aureen/the_odin_project/room/src/routes/shop/orders/Tracking.jsx",["1036","1037"],"import React, { useState } from \"react\";\nimport styled from \"styled-components\";\nimport useOrder from \"../../../hooks/useOrder\";\nimport Order from \"../../../components/account/Order\";\n\nfunction Tracking() {\n const [email, setEmail] = useState(\"\");\n const [orderId, setOrderId] = useState(\"\");\n const [order, setOrder] = useState();\n const [message, setMessage] = useState(\"\");\n const { searchOrder } = useOrder();\n\n const handleSearchOrder = async (e) => {\n e.preventDefault();\n setMessage(\"\");\n const order = await searchOrder(email, orderId);\n order\n ? setOrder(order)\n : setMessage(\"Sorry, we could not find your order.\");\n };\n\n return (\n <Container>\n <Heading>Order Tracking</Heading>\n\n <div>\n <Category>Track your order</Category>\n <Form onSubmit={handleSearchOrder}>\n <Fields>\n <Field>\n <Label htmlFor=\"email\">Email</Label>\n <Input\n type=\"email\"\n value={email}\n id=\"email\"\n onChange={(e) => setEmail(e.target.value)}\n placeholder=\"Enter your email\"\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"order_id\">Order</Label>\n <Input\n type=\"text\"\n value={orderId}\n id=\"order_id\"\n onChange={(e) => setOrderId(e.target.value)}\n placeholder=\"Enter your order number\"\n />\n </Field>\n </Fields>\n <Button type=\"submit\">Track your order</Button>\n <Message>{message}</Message>\n </Form>\n </div>\n\n {order && (\n <div>\n <Category>Order</Category>\n <Order order={order} />\n </div>\n )}\n </Container>\n );\n}\n\nexport default Tracking;\n\n// Styled Components\nconst colors = {\n primary: \"hsl(0, 0%, 45%)\", // Grey\n secondary: \"hsl(0, 0%, 27%)\", // Dark Grey\n tertiary: \"hsl(0, 0%, 70%)\", // Bright Grey\n text: \"hsl(0, 0%, 85%)\",\n label: \"hsl(0, 0%, 100%)\",\n dark: \"hsl(0, 0%, 0%)\",\n};\n\nconst Container = styled.div`\n margin: 5rem;\n`;\n\nconst Heading = styled.h1`\n margin-bottom: 2rem;\n font-size: 2rem;\n line-height: 2.75rem;\n font-family: \"Playfair Display\", sans-serif;\n`;\n\nconst Category = styled.div`\n border-bottom: 1px solid ${colors.tertiary};\n text-transform: uppercase;\n font-size: 0.9rem;\n color: ${colors.primary};\n padding-bottom: 0.25rem;\n margin-bottom: 1.5rem;\n`;\n\nconst Form = styled.form`\n display: flex;\n flex-direction: column;\n min-width: 40vw;\n`;\n\nconst Fields = styled.div`\n display: grid;\n grid-gap: 3rem 5rem;\n margin-bottom: 2.5rem;\n\n @media all and (min-width: 576px) {\n grid-template-columns: repeat(2, 1fr);\n }\n`;\n\nconst Field = styled.div`\n display: flex;\n flex-direction: column;\n`;\n\nconst Label = styled.label`\n text-transform: uppercase;\n font-size: 0.825rem;\n letter-spacing: 1px;\n`;\n\nconst Input = styled.input`\n border: none;\n border-bottom: 1px solid ${colors.input};\n padding: 0.5rem 0 0.25rem 0;\n font-family: \"Source Sans Pro\", sans-serif;\n\n &::placeholder {\n color: ${colors.input};\n }\n\n &:focus {\n border-bottom: 1px solid ${colors.black};\n }\n`;\n\nconst Button = styled.button`\n margin-top: 1.5rem;\n text-transform: uppercase;\n font-size: 0.9rem;\n color: ${colors.text};\n background: ${colors.secondary};\n align-self: center;\n padding: 0.5rem 1rem;\n cursor: pointer;\n\n &:hover {\n color: ${colors.label};\n }\n`;\n\nconst Message = styled.div`\n text-align: center;\n font-size: 0.825rem;\n color: ${colors.primary};\n margin-top: 0.25rem;\n`;\n","/home/aureen/the_odin_project/room/src/routes/shop/display/Category.jsx",["1038","1039","1040"],"import React, { useState, useEffect } from \"react\";\nimport styled from \"styled-components\";\nimport PropTypes from \"prop-types\";\nimport { useFavorite } from \"../../../contexts/FavoriteContext\";\nimport useShop from \"../../../hooks/useShop\";\nimport useWindowSize from \"../../../hooks/useWindowSize\";\nimport SideFilters from \"../../../components/shop/display/SideFilters\";\nimport Filters from \"../../../components/shop/display/Filters\";\nimport Sort from \"../../../components/shop/display/Sort\";\nimport ShopItemPreview from \"../../../components/shop/display/ShopItemPreview\";\n\nfunction Category({ match }) {\n const [items, setItems] = useState([]); // All items that belong in the category\n const [unsortedItems, setUnsortedItems] = useState([]); // Items when \"sorted\" by \"featured\".\n const [sort, setSort] = useState(\"featured\");\n const [filters, setFilters] = useState({\n colors: [],\n materials: [],\n price: Infinity,\n dimensions: {\n width: Infinity,\n height: Infinity,\n depth: Infinity,\n },\n seats: [],\n });\n const [displayedItems, setDisplayedItems] = useState([]); // Items displayed after filters are applied\n const { getCategoryItems } = useShop();\n const { favorites } = useFavorite();\n const { windowSize } = useWindowSize();\n\n // Loads all category items and sets up filters\n useEffect(() => {\n (async () => {\n const itemsList = await getCategoryItems(\n decodeURIComponent(match.params.category)\n );\n setItems(itemsList);\n setUnsortedItems(itemsList);\n })();\n }, [match]);\n\n // Modify filters\n const handleFilters = (field, value) => {\n setFilters((filters) => {\n return { ...filters, [field]: value };\n });\n };\n\n // Sorting items\n const handleSort = (sort) => {\n setSort(sort);\n };\n\n // Update displayed items depending on which filters are applied.\n useEffect(() => {\n let displayedItems = [...items];\n\n // Colors filter\n if (filters.colors.length > 0) {\n displayedItems = displayedItems.filter((item) =>\n item.queries.colors.some((color) => filters.colors.includes(color))\n );\n }\n\n // Materials filter\n if (filters.materials.length > 0) {\n displayedItems = displayedItems.filter((item) =>\n item.queries.materials.some((material) =>\n filters.materials.includes(material)\n )\n );\n }\n\n // Price filter\n displayedItems = displayedItems.filter(\n (item) => item.queries.price.min <= filters.price\n );\n\n // Dimensions filter\n displayedItems = displayedItems.filter(\n (item) =>\n item.queries.dimensions.width.min <= filters.dimensions.width &&\n item.queries.dimensions.height.min <= filters.dimensions.height &&\n item.queries.dimensions.depth.min <= filters.dimensions.depth\n );\n\n // Seats filter\n if (filters.seats.length > 0) {\n displayedItems = displayedItems.filter(\n (item) =>\n item.queries.seats &&\n item.queries.seats.some((number) => filters.seats.includes(number))\n );\n }\n setDisplayedItems(displayedItems);\n setUnsortedItems(displayedItems);\n }, [items, filters]);\n\n // Update displayed items depending on the sorting filter the user chooses.\n useEffect(() => {\n switch (sort) {\n case \"featured\":\n setItems(unsortedItems);\n break;\n case \"new\":\n setDisplayedItems([...displayedItems].sort((a, b) => a.date - b.date));\n break;\n case \"alphabetical_increasing\":\n setDisplayedItems(\n [...displayedItems].sort((a, b) => a.name.localeCompare(b.name))\n );\n break;\n case \"alphabetical_decreasing\":\n setDisplayedItems(\n [...displayedItems].sort((a, b) => b.name.localeCompare(a.name))\n );\n break;\n case \"price_increasing\":\n setDisplayedItems(\n [...displayedItems].sort((a, b) => a.price - b.price)\n );\n break;\n case \"price_decreasing\":\n setDisplayedItems(\n [...displayedItems].sort((a, b) => b.price - a.price)\n );\n break;\n default:\n }\n }, [sort]);\n\n return (\n <Shop>\n {windowSize.width > 830 && (\n <SideFilters items={items} handleFilters={handleFilters} />\n )}\n <Content>\n <Buttons>\n <Sort handleSort={handleSort} />\n {windowSize.width <= 830 && (\n <Filters items={items} handleFilters={handleFilters} />\n )}\n </Buttons>\n <ShopList>\n {displayedItems.map((item) => {\n return (\n <li key={item.id}>\n <ShopItemPreview\n name={item.name}\n images={item.images}\n price={item.price}\n id={item.id}\n isFavorite={favorites.includes(item.id)}\n isNew={item.new}\n />\n </li>\n );\n })}\n </ShopList>\n </Content>\n </Shop>\n );\n}\n\nexport default Category;\n\nCategory.propTypes = {\n match: PropTypes.shape({\n params: PropTypes.shape({\n category: PropTypes.string,\n }),\n }).isRequired,\n};\n\nconst ShopList = styled.ul`\n display: grid;\n grid-gap: 3vw;\n\n @media all and (min-width: 576px) {\n grid-template-columns: repeat(2, auto);\n }\n\n @media all and (min-width: 1350px) {\n grid-template-columns: repeat(3, auto);\n }\n`;\n\nconst Content = styled.div`\n justify-self: stretch;\n`;\n\nconst Shop = styled.div`\n display: grid;\n grid-column-gap: 1rem;\n padding: 5rem 0;\n justify-items: center;\n\n @media all and (min-width: 768px) {\n grid-template-columns: auto 1fr;\n }\n\n @media all and (min-width: 992px) {\n width: 80%;\n }\n`;\n\nconst Buttons = styled.div`\n display: grid;\n justify-items: stretch;\n grid-gap: 2rem;\n margin-bottom: 1rem;\n\n @media all and (min-width: 576px) {\n grid-template-columns: repeat(2, 1fr);\n }\n\n @media all and (min-width: 830px) {\n display: flex;\n justify-content: flex-end;\n }\n`;\n","/home/aureen/the_odin_project/room/src/routes/shop/display/ItemDetails.jsx",["1041","1042","1043","1044","1045","1046","1047","1048","1049","1050","1051","1052","1053","1054","1055","1056","1057"],"import React, { useState, useEffect } from \"react\";\nimport styled from \"styled-components\";\nimport PropTypes from \"prop-types\";\nimport { Link } from \"react-router-dom\";\nimport { CSSTransition } from \"react-transition-group\";\nimport { useAuth } from \"../../../contexts/AuthContext\";\nimport { useFavorite } from \"../../../contexts/FavoriteContext\";\nimport useShop from \"../../../hooks/useShop\";\nimport useCart from \"../../../hooks/useCart\";\nimport useWindowSize from \"../../../hooks/useWindowSize\";\nimport { formatNavLink } from \"../../../utils/utils\";\nimport Recommendations from \"../../../components/shop/display/Recommendations\";\nimport ImagesPreview from \"../../../components/shop/display/ImagesPreview\";\n\n// Icons\nimport { ReactComponent as AngleRight } from \"../../../assets/icons/icon-small-arrow.svg\";\nimport { ReactComponent as Plus } from \"../../../assets/icons/icon-plus.svg\";\nimport { ReactComponent as Minus } from \"../../../assets/icons/icon-minus.svg\";\nimport { ReactComponent as Heart } from \"../../../assets/icons/icon-heart.svg\";\nimport { ReactComponent as HeartFilled } from \"../../../assets/icons/icon-heart-filled.svg\";\nimport iconX from \"../../../assets/icons/icon-x.svg\";\n\nfunction ItemDetails({ match }) {\n const [item, setItem] = useState({});\n const [loading, setLoading] = useState(true);\n const [currentPrice, setCurrentPrice] = useState(0);\n const [currentDimensions, setCurrentDimensions] = useState({\n width: 0,\n height: 0,\n depth: 0,\n });\n const [currentColor, setCurrentColor] = useState(\"\");\n const [currentOption, setCurrentOption] = useState([]);\n const [quantity, setQuantity] = useState(1);\n const [areDetailsOpen, setAreDetailsOpen] = useState(false);\n const [message, setMessage] = useState(\"\");\n const [recommendations, setRecommendations] = useState([]);\n const { currentUser, signInAnonymously } = useAuth();\n const { favorites, addFavorite, deleteFavorite } = useFavorite();\n const { getItem, getRecommendations } = useShop();\n const { addToCart } = useCart();\n const { windowSize } = useWindowSize();\n\n const handleFavorite = async (id) => {\n let userId = currentUser && currentUser.uid;\n\n if (!currentUser) {\n const user = await signInAnonymously();\n userId = user.user.uid;\n }\n favorites.includes(id)\n ? deleteFavorite(userId, id)\n : addFavorite(userId, id);\n };\n\n // Fetch the item data and store it in the state\n useEffect(() => {\n (async () => {\n const { itemId } = match.params;\n const item = await getItem(itemId);\n setItem(item);\n setCurrentPrice(item.price);\n setCurrentDimensions(item.dimensions);\n setLoading(false);\n })();\n }, []);\n\n // Sets the default color and the default option (if there are any)\n useEffect(() => {\n if (Object.keys(item).length === 0) return;\n setCurrentColor(item.colors[0]);\n\n if (Object.keys(item.options).length !== 0) {\n const options = [];\n for (const key of Object.keys(item.options)) {\n options.push({ [key]: item.options[key][0] });\n }\n setCurrentOption(options);\n }\n }, [item]);\n\n // Changes the item's price and dimensions depending on the options (number of seats, size...) the user chooses.\n useEffect(() => {\n if (currentOption.length === 0) return;\n const optionName = Object.keys(currentOption[0])[0];\n setCurrentPrice(currentOption[0][optionName].price);\n setCurrentDimensions(currentOption[0][optionName].dimensions);\n }, [currentOption]);\n\n const handleAddToCart = async (e) => {\n e.preventDefault();\n setMessage(\"\");\n\n // If the user is not signed in, we sign him up anonymously to save his cart and allow him to order.\n\n let userId = currentUser && currentUser.uid;\n\n if (!currentUser) {\n const user = await signInAnonymously();\n userId = user.user.uid;\n }\n\n try {\n await addToCart(\n userId,\n item.id,\n item.name,\n currentColor.image,\n currentColor,\n currentOption,\n quantity,\n item.type,\n currentPrice\n );\n setMessage(\n `${item.name} in ${currentColor.description} was added to your cart.`\n );\n } catch (e) {\n setMessage(\n \"Sorry, there was an error: we were not able to add the item to your cart.\"\n );\n }\n };\n\n // Get Recommendations\n useEffect(() => {\n (async () => {\n if (!item.id) return;\n const recommendations = await getRecommendations(item.id);\n setRecommendations(recommendations);\n })();\n }, [item]);\n\n return (\n <Container>\n {!loading && (\n <Center>\n {window.size > 500 && (\n <Category>\n <Link to=\"/\">\n <CategoryLink>Home</CategoryLink>\n </Link>\n <ArrowIcon>\n <AngleRight />\n </ArrowIcon>\n <Link to=\"/shop\">\n <CategoryLink>Shop</CategoryLink>\n </Link>\n\n {item.categories.map((category) => {\n return (\n <React.Fragment key={category}>\n <ArrowIcon>\n <AngleRight />\n </ArrowIcon>\n <Link to={`/shop/${encodeURI(category)}`}>\n <CategoryLink>{formatNavLink(category)}</CategoryLink>\n </Link>\n </React.Fragment>\n );\n })}\n </Category>\n )}\n\n <Informations>\n {windowSize.width > 600 && (\n <ImagesPreview images={item.images} size=\"35rem\" />\n )}\n {windowSize.width < 600 && (\n <ImagesPreview images={item.images} size=\"80vw\" />\n )}\n <Details>\n <Row>\n <Name>{item.name}</Name>\n <Icon onClick={() => handleFavorite(item.id)}>\n {favorites.includes(item.id) ? <HeartFilled /> : <Heart />}\n </Icon>\n </Row>\n <Price>£{currentPrice}</Price>\n <Description>\n {item.description.map((paragraph, index) => {\n return <p key={`description${index}`}>{paragraph}</p>;\n })}\n </Description>\n\n <Selection onSubmit={handleAddToCart}>\n <div>\n <TextLabel>Color: </TextLabel>\n <Choice> {currentColor.description}</Choice>\n </div>\n <ColorList>\n {item.colors.map((color) => {\n return (\n <li key={color.description}>\n <ColorLabel\n htmlFor={color.description}\n value={color.value}\n title={color.description}\n isSelected={\n currentColor.description === color.description\n }\n />\n <Checkbox\n type=\"checkbox\"\n id={color.description}\n name={color.description}\n onClick={() => setCurrentColor(color)}\n />\n </li>\n );\n })}\n </ColorList>\n\n <div>\n {Object.keys(item.options).map((option, index) => {\n return (\n <OptionsField key={option}>\n <TextLabel>{option}: </TextLabel>\n <Options>\n {item.options[option].map((choice) => {\n return (\n <React.Fragment key={choice.option}>\n <OptionLabel\n htmlFor={choice.option}\n isSelected={\n currentOption[index][option].option ===\n choice.option\n }\n >\n {choice.option}\n </OptionLabel>\n <Checkbox\n type=\"checkbox\"\n id={choice.option}\n name={choice.option}\n onChange={() =>\n setCurrentOption((prev) => {\n return [...prev].map((prevOption) => {\n if (\n Object.keys(prevOption)[0] === option\n ) {\n return { [option]: choice };\n }\n return prevOption;\n });\n })\n }\n />\n </React.Fragment>\n );\n })}\n </Options>\n </OptionsField>\n );\n })}\n </div>\n\n <Row>\n <div>\n <Label htmlFor=\"quantity\">Quantity: </Label>\n <Quantity\n type=\"text\"\n id=\"quantity\"\n name=\"quantity\"\n value={quantity}\n required\n onChange={(e) => {\n const quantity = e.target.value.replace(/[^0-9]/g, \"\");\n setQuantity(quantity);\n }}\n onBlur={(e) => {\n if (e.target.value < 1) setQuantity(1);\n }}\n />\n </div>\n <Column>\n <SubmitBtn type=\"submit\">Add to Basket</SubmitBtn>\n <CSSTransition\n in={message.length !== 0}\n timeout={300}\n classNames=\"fade\"\n >\n <Message>{message}</Message>\n </CSSTransition>\n </Column>\n </Row>\n </Selection>\n\n <Additional>\n <AdditionalBtn\n onClick={() => setAreDetailsOpen(!areDetailsOpen)}\n >\n Additional Information\n {areDetailsOpen ? <Minus /> : <Plus />}\n </AdditionalBtn>\n\n <CSSTransition\n in={areDetailsOpen}\n timeout={500}\n classNames=\"dropdown\"\n mountOnEnter\n >\n <Dropdown>\n <DropdownColumn>\n <TextLabel>Dimensions (cm)</TextLabel>\n <ul>\n {Object.keys(currentDimensions).map((dimension) => {\n return (\n <Li key={dimension}>\n <AdditionalLabel>{dimension}: </AdditionalLabel>\n <AdditionalInfo>\n {\" \"}\n {currentDimensions[dimension]}\n </AdditionalInfo>\n </Li>\n );\n })}\n </ul>\n </DropdownColumn>\n\n {Object.keys(item.additional).length !== 0 && (\n <DropdownColumn>\n <TextLabel>Details</TextLabel>\n <ul>\n {Object.keys(item.additional).map((info) => {\n return (\n <Li key={info}>\n <AdditionalLabel>{info}: </AdditionalLabel>\n <AdditionalInfo>\n {\" \"}\n {item.additional[info]}\n </AdditionalInfo>\n </Li>\n );\n })}\n </ul>\n </DropdownColumn>\n )}\n </Dropdown>\n </CSSTransition>\n </Additional>\n </Details>\n </Informations>\n </Center>\n )}\n {recommendations.length !== 0 && windowSize.width > 1300 && (\n <Recommendations recommendations={recommendations} number={4} />\n )}\n {recommendations.length !== 0 &&\n windowSize.width > 800 &&\n windowSize.width <= 1300 && (\n <Recommendations recommendations={recommendations} number={3} />\n )}\n {recommendations.length !== 0 &&\n windowSize.width > 500 &&\n windowSize.width <= 800 && (\n <Recommendations recommendations={recommendations} number={2} />\n )}\n {recommendations.length !== 0 && windowSize.width <= 500 && (\n <Recommendations recommendations={recommendations} number={1} />\n )}\n </Container>\n );\n}\n\nexport default ItemDetails;\n\nItemDetails.propTypes = {\n match: PropTypes.shape({\n params: PropTypes.shape({\n itemId: PropTypes.string,\n }),\n }).isRequired,\n};\n\n// Styled Components\nconst colors = {\n primary: \"hsl(0, 0%, 45%)\", // Grey\n secondary: \"hsl(0, 0%, 15%)\", // Dark Grey\n tertiary: \"hsl(0, 0%, 70%)\", // Bright Grey\n text: \"hsl(0, 0%, 35%)\",\n button: \"hsl(0, 0%, 100%)\", // White\n};\n\nconst Container = styled.div`\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n margin-top: 2rem;\n\n @media all and (min-width: 1200px) {\n padding: 1rem 3rem 5rem 3rem;\n }\n`;\n\nconst Center = styled.section`\n max-width: 1200px;\n display: grid;\n justify-items: center;\n\n @media all and (min-width: 1000px) {\n display: block;\n margin-bottom: 3rem;\n }\n`;\n\n// Category Links above the item preview\nconst Category = styled.div`\n display: flex;\n align-items: center;\n text-transform: uppercase;\n font-size: 0.825rem;\n font-weight: 600;\n margin-bottom: 0.5rem;\n\n @media all and (min-width: 1000px) {\n padding: 0;\n padding-left: 2rem;\n }\n\n @media all and (min-width: 1200px) {\n padding-left: 0;\n }\n`;\n\nconst CategoryLink = styled.span`\n color: ${colors.primary};\n\n &:hover {\n color: ${colors.secondary};\n }\n`;\n\nconst ArrowIcon = styled.span`\n display: inline-block;\n margin: 2px 0.5rem 0 0.5rem;\n color: ${colors.primary};\n`;\n\n// Informations about the item\nconst Informations = styled.div`\n display: grid;\n justify-items: center;\n\n @media all and (min-width: 1000px) {\n grid-template-columns: repeat(2, 1fr);\n }\n`;\n\nconst Description = styled.div`\n display: grid;\n grid-gap: 1rem;\n text-align: justify;\n color: ${colors.text};\n line-height: 1.25rem;\n`;\n\nconst Details = styled.div`\n padding: 3rem 1rem 0 1rem;\n\n & > * {\n margin-bottom: 1.5rem;\n }\n\n @media all and (min-width: 500px) {\n padding: 5rem 5rem 2rem 5rem;\n }\n\n @media all and (min-width: 1100px) {\n padding: 0 5rem;\n }\n`;\n\nconst Name = styled.h2`\n text-transform: uppercase;\n letter-spacing: 1px;\n font-size: 1.25rem;\n`;\n\nconst Price = styled.div`\n text-transform: uppercase;\n letter-spacing: 1px;\n color: ${colors.secondary};\n`;\n\n// Selection and adding to basket\n\nconst Selection = styled.form`\n border-top: 1px solid ${colors.tertiary};\n border-bottom: 1px solid ${colors.tertiary};\n padding: 0.5rem 0;\n\n & > * {\n margin: 1rem 0;\n }\n`;\n\nconst Choice = styled.span`\n text-transform: uppercase;\n font-size: 0.9rem;\n color: ${colors.text};\n`;\n\nconst TextLabel = styled.span`\n display: inline-block;\n text-transform: uppercase;\n color: ${colors.secondary};\n font-weight: 600;\n`;\n\nconst Label = styled.label`\n text-transform: uppercase;\n color: ${colors.secondary};\n font-weight: 600;\n`;\n\nconst Row = styled.div`\n display: flex;\n justify-content: space-between;\n`;\n\nconst Checkbox = styled.input`\n opacity: 0;\n appearance: none;\n`;\n\nconst SubmitBtn = styled.button`\n font-family: \"Source Sans Pro\", sans-serif;\n text-transform: uppercase;\n letter-spacing: 1px;\n font-size: 0.825rem;\n padding: 0.75rem 1.25rem;\n color: ${colors.button};\n background: ${colors.primary};\n transition: all 0.15s linear;\n cursor: pointer;\n width: 10.5rem;\n\n &:hover {\n letter-spacing: 1.5px;\n }\n`;\n\n// Select the item's color\nconst ColorList = styled.ul`\n display: flex;\n`;\n\nconst ColorLabel = styled.label`\n display: inline-block;\n width: 2rem;\n height: 2rem;\n background-color: ${(props) => props.value};\n border: 1px solid\n ${(props) => (props.isSelected ? colors.primary : colors.tertiary)};\n cursor: pointer;\n margin-right: 0.5rem;\n`;\n\n// Select an option\nconst Options = styled.div`\n display: grid;\n grid-template-columns: repeat(3, 1fr auto);\n`;\n\nconst OptionsField = styled.div`\n display: flex;\n align-items: center;\n`;\n\nconst OptionLabel = styled.label`\n cursor: pointer;\n border: 1px solid\n ${(props) => (props.isSelected ? colors.secondary : colors.text)};\n color: ${(props) => (props.isSelected ? colors.secondary : colors.text)};\n outline: 1px solid\n ${(props) => (props.isSelected ? colors.secondary : \"transparent\")};\n padding: 0.5rem 1rem;\n margin: 0 0 0.5rem 1rem;\n`;\n\n// Select a quantity\nconst Quantity = styled.input`\n font-family: \"Source Sans Pro\", sans-serif;\n width: 2rem;\n height: 2rem;\n text-align: center;\n margin: 0 1rem;\n`;\n\n// Additional informations dropdown\n\nconst Additional = styled.div`\n border-bottom: 1px solid ${colors.tertiary};\n`;\n\nconst AdditionalBtn = styled.button`\n width: 100%;\n display: flex;\n justify-content: space-between;\n font-family: \"Source Sans Pro\", sans-serif;\n text-transform: uppercase;\n color: ${colors.secondary};\n font-weight: 600;\n font-size: 0.95rem;\n cursor: pointer;\n padding: 0;\n padding-bottom: 1.5rem;\n`;\n\nconst Li = styled.li`\n padding-left: 1rem;\n text-indent: -1rem;\n line-height: 1.25rem;\n\n &:before {\n content: \"\";\n display: inline-block;\n width: 15px;\n height: 15px;\n margin-bottom: -5px;\n background: url(${iconX});\n }\n`;\n\nconst AdditionalLabel = styled.span`\n font-weight: 600;\n text-transform: capitalize;\n`;\n\nconst AdditionalInfo = styled.span`\n color: ${colors.text};\n`;\n\nconst Dropdown = styled.div`\n display: grid;\n\n @media all and (min-width: 500px) {\n grid-template-columns: 1fr 1.5fr;\n }\n`;\n\nconst DropdownColumn = styled.div`\n padding-bottom: 1.5rem;\n\n & > *:first-child {\n margin-bottom: 0.5rem;\n }\n`;\n\nconst Column = styled.div`\n display: flex;\n flex-direction: column;\n`;\n\nconst Message = styled.div`\n text-align: center;\n font-size: 0.825rem;\n color: ${colors.primary};\n margin-top: 0.25rem;\n max-width: 168px; // Size of button\n`;\n\nconst Icon = styled.span`\n color: ${colors.primary};\n cursor: pointer;\n`;\n","/home/aureen/the_odin_project/room/src/routes/shop/display/Main.jsx",["1058","1059","1060","1061"],"import React, { useState, useEffect } from \"react\";\nimport styled from \"styled-components\";\nimport useDesign from \"../../../hooks/useDesign\";\nimport FullCarousel from \"../../../components/FullCarousel\";\nimport Designs from \"../../../components/shop/display/Designs\";\n\nfunction Main() {\n const [designs, setDesigns] = useState([]);\n const { getDesigns } = useDesign();\n\n useEffect(() => {\n (async () => {\n const designs = await getDesigns();\n setDesigns(designs);\n })();\n }, []);\n\n return (\n <Container>\n <FullCarousel />\n <Presentation>\n <Heading>Room</Heading>\n <Decoration>⬧</Decoration>\n <p>\n The furniture is the foundation of a home. That's why Room is\n passionate about offering a huge variety of furniture at all prices.\n Whatever your style, whatever your needs, find furniture that's made\n for you.\n </p>\n\n <p>\n Each year, the collection is refreshed to stay on trend and keep up\n with your needs, whilst also taking more care of the planet and its\n inhabitants. Over half of our wooden furniture meets sustainable\n criteria. Every year we progress with our products, but also in\n raising awareness among design students and young designers to\n encourage them to think about eco-design. We believe we can reduce the\n impact on the environment without compromising on style. The second\n life of products starts here!\n </p>\n\n <p>So, you're free to have your own style!</p>\n </Presentation>\n\n {designs.length !== 0 && (\n <>\n <Featured id=\"featured\">Featured Rooms</Featured>\n <Designs designs={designs} />\n </>\n )}\n </Container>\n );\n}\n\nexport default Main;\n\nconst colors = {\n primary: \"hsl(0, 0%, 27%)\", // Grey\n secondary: \"hsl(0, 0%, 40%)\",\n dark: \"hsl(0, 0%, 17%)\",\n accent: \"hsl(46, 65%, 52%)\", // Gold\n};\n\nconst Container = styled.div`\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n`;\n\nconst Presentation = styled.div`\n display: flex;\n flex-direction: column;\n color: ${colors.secondary};\n max-width: 40rem;\n border: 5px solid ${colors.primary};\n outline: 2px solid ${colors.primary};\n outline-offset: 5px;\n margin: 5rem;\n padding: 3rem;\n line-height: 1.5rem;\n text-align: justify;\n\n & > p {\n margin-bottom: 1rem;\n }\n\n & > p:last-child {\n margin-bottom: 0;\n }\n`;\n\nconst Decoration = styled.span`\n display: flex;\n align-items: center;\n align-self: center;\n color: ${colors.accent};\n margin: 1rem 0;\n\n &:before,\n &:after {\n content: \"\";\n display: inline-block;\n margin: 0 1rem;\n height: 1px;\n width: 5rem;\n background: ${colors.accent};\n background: linear-gradient(270deg, transparent, ${colors.accent});\n }\n\n &:before {\n background: linear-gradient(270deg, ${colors.accent}, transparent);\n }\n`;\n\nconst Heading = styled.h2`\n color: ${colors.dark};\n text-align: center;\n text-transform: uppercase;\n font-weight: 300;\n font-size: 1.5rem;\n`;\n\nconst Featured = styled(Heading)`\n display: flex;\n align-items: center;\n align-self: stretch;\n justify-content: center;\n color: ${colors.secondary};\n\n &:before,\n &:after {\n content: \"\";\n display: inline-block;\n margin: 0 1rem;\n height: 1px;\n width: 20%;\n background: ${colors.secondary};\n background: linear-gradient(270deg, transparent, ${colors.secondary});\n }\n\n &:before {\n background: linear-gradient(270deg, ${colors.secondary}, transparent);\n }\n`;\n","/home/aureen/the_odin_project/room/src/routes/shop/display/NewIn.jsx",["1062","1063","1064"],"import React, { useState, useEffect } from \"react\";\nimport styled from \"styled-components\";\nimport { useFavorite } from \"../../../contexts/FavoriteContext\";\nimport useShop from \"../../../hooks/useShop\";\nimport useWindowSize from \"../../../hooks/useWindowSize\";\nimport ShopItemPreview from \"../../../components/shop/display/ShopItemPreview\";\nimport SideFilters from \"../../../components/shop/display/SideFilters\";\nimport Filters from \"../../../components/shop/display/Filters\";\nimport Sort from \"../../../components/shop/display/Sort\";\n\nfunction NewIn() {\n const [items, setItems] = useState([]); // All items that belong in the category\n const [unsortedItems, setUnsortedItems] = useState([]); // Items when \"sorted\" by \"featured\".\n const [sort, setSort] = useState(\"featured\");\n const [filters, setFilters] = useState({\n colors: [],\n materials: [],\n price: Infinity,\n dimensions: {\n width: Infinity,\n height: Infinity,\n depth: Infinity,\n },\n seats: [],\n });\n const [displayedItems, setDisplayedItems] = useState([]); // Items displayed after filters are applied\n const { getNewItems } = useShop();\n const { favorites } = useFavorite();\n const { windowSize } = useWindowSize();\n\n // Loads all category items and sets up filters\n useEffect(() => {\n (async () => {\n const itemsList = await getNewItems();\n setItems(itemsList);\n })();\n }, []);\n\n // Modify filters\n const handleFilters = (field, value) => {\n setFilters((filters) => {\n return { ...filters, [field]: value };\n });\n };\n\n // Sorting items\n const handleSort = (sort) => {\n setSort(sort);\n };\n\n // Update displayed items depending on which filters are applied.\n useEffect(() => {\n let displayedItems = [...items];\n\n // Colors filter\n if (filters.colors.length > 0) {\n displayedItems = displayedItems.filter((item) =>\n item.queries.colors.some((color) => filters.colors.includes(color))\n );\n }\n\n // Materials filter\n if (filters.materials.length > 0) {\n displayedItems = displayedItems.filter((item) =>\n item.queries.materials.some((material) =>\n filters.materials.includes(material)\n )\n );\n }\n\n // Price filter\n displayedItems = displayedItems.filter(\n (item) => item.queries.price.min <= filters.price\n );\n\n // Dimensions filter\n displayedItems = displayedItems.filter(\n (item) =>\n item.queries.dimensions.width.min <= filters.dimensions.width &&\n item.queries.dimensions.height.min <= filters.dimensions.height &&\n item.queries.dimensions.depth.min <= filters.dimensions.depth\n );\n\n // Seats filter\n if (filters.seats.length > 0) {\n displayedItems = displayedItems.filter(\n (item) =>\n item.queries.seats &&\n item.queries.seats.some((number) => filters.seats.includes(number))\n );\n }\n setDisplayedItems(displayedItems);\n setUnsortedItems(displayedItems);\n }, [items, filters]);\n\n // Update displayed items depending on the sorting filter the user chooses.\n useEffect(() => {\n switch (sort) {\n case \"featured\":\n setItems(unsortedItems);\n break;\n case \"new\":\n setDisplayedItems([...displayedItems].sort((a, b) => a.date - b.date));\n break;\n case \"alphabetical_increasing\":\n setDisplayedItems(\n [...displayedItems].sort((a, b) => a.name.localeCompare(b.name))\n );\n break;\n case \"alphabetical_decreasing\":\n setDisplayedItems(\n [...displayedItems].sort((a, b) => b.name.localeCompare(a.name))\n );\n break;\n case \"price_increasing\":\n setDisplayedItems(\n [...displayedItems].sort((a, b) => a.price - b.price)\n );\n break;\n case \"price_decreasing\":\n setDisplayedItems(\n [...displayedItems].sort((a, b) => b.price - a.price)\n );\n break;\n default:\n }\n }, [sort]);\n\n return (\n <Shop>\n {windowSize.width > 830 && (\n <SideFilters items={items} handleFilters={handleFilters} />\n )}\n <Content>\n <Buttons>\n <Sort handleSort={handleSort} />\n {windowSize.width <= 830 && (\n <Filters items={items} handleFilters={handleFilters} />\n )}\n </Buttons>\n <ShopList>\n {displayedItems.map((item) => {\n return (\n <li key={item.id}>\n <ShopItemPreview\n name={item.name}\n images={item.images}\n price={item.price}\n id={item.id}\n isFavorite={favorites.includes(item.id)}\n isNew={item.new}\n />\n </li>\n );\n })}\n </ShopList>\n </Content>\n </Shop>\n );\n}\n\nexport default NewIn;\n\nconst ShopList = styled.ul`\n display: grid;\n grid-gap: 3vw;\n\n @media all and (min-width: 576px) {\n grid-template-columns: repeat(2, auto);\n }\n\n @media all and (min-width: 1350px) {\n grid-template-columns: repeat(3, auto);\n }\n`;\n\nconst Shop = styled.div`\n display: grid;\n grid-column-gap: 1rem;\n padding: 5rem 0;\n justify-items: center;\n\n @media all and (min-width: 768px) {\n grid-template-columns: auto 1fr;\n }\n\n @media all and (min-width: 992px) {\n width: 80%;\n }\n`;\n\nconst Content = styled.div`\n justify-self: stretch;\n`;\n\nconst Buttons = styled.div`\n display: grid;\n justify-items: stretch;\n grid-gap: 2rem;\n margin-bottom: 1rem;\n\n @media all and (min-width: 576px) {\n grid-template-columns: repeat(2, 1fr);\n }\n\n @media all and (min-width: 830px) {\n display: flex;\n justify-content: flex-end;\n }\n`;\n","/home/aureen/the_odin_project/room/src/routes/shop/display/Design.jsx",["1065","1066","1067","1068"],"import React, { useState, useEffect } from \"react\";\nimport styled from \"styled-components\";\nimport PropTypes from \"prop-types\";\nimport useDesign from \"../../../hooks/useDesign\";\nimport useShop from \"../../../hooks/useShop\";\nimport { useFavorite } from \"../../../contexts/FavoriteContext\";\nimport ShopItemPreview from \"../../../components/shop/display/ShopItemPreview\";\n\nfunction Design({ match }) {\n const [design, setDesign] = useState();\n const [items, setItems] = useState([]);\n const { favorites } = useFavorite();\n const { getDesign } = useDesign();\n const { getItem } = useShop();\n\n useEffect(() => {\n (async () => {\n const design = await getDesign(match.params.id);\n setDesign(design);\n\n const items = [];\n for (const itemId of design.items) {\n const item = await getItem(itemId);\n items.push(item);\n }\n setItems(items);\n })();\n }, []);\n\n return (\n <Container>\n {design && (\n <>\n <Presentation>\n <ImageContainer>\n <Image src={design.image} alt={design.name} />\n </ImageContainer>\n\n <Text>\n <Heading>{design.name}</Heading>\n <Decoration>⬧</Decoration>\n {design.description.map((paragraph) => {\n return <p key={paragraph}>{paragraph}</p>;\n })}\n </Text>\n </Presentation>\n\n <ShopList>\n {items.map((item) => {\n return (\n <ShopItemPreview\n key={item.id}\n name={item.name}\n images={item.images}\n price={item.price}\n id={item.id}\n isFavorite={favorites.includes(item.id)}\n isNew={item.new}\n />\n );\n })}\n </ShopList>\n </>\n )}\n </Container>\n );\n}\n\nexport default Design;\n\nDesign.propTypes = {\n match: PropTypes.shape({\n params: PropTypes.shape({\n id: PropTypes.string,\n }),\n }).isRequired,\n};\n\nconst colors = {\n primary: \"hsl(0, 0%, 27%)\", // Grey\n secondary: \"hsl(0, 0%, 40%)\",\n background: \"hsl(0, 0%, 100%)\",\n accent: \"hsl(46, 65%, 52%)\", // Gold\n};\n\nconst Container = styled.div`\n padding: 5rem 0;\n max-width: 80%;\n`;\n\nconst ShopList = styled.ul`\n display: grid;\n margin-top: 3rem;\n grid-gap: 3vw;\n\n @media all and (min-width: 500px) {\n grid-template-columns: repeat(2, 1fr);\n }\n\n @media all and (min-width: 1000px) {\n grid-template-columns: repeat(3, 1fr);\n }\n`;\n\nconst ImageContainer = styled.div`\n width: 100%;\n height: 100%;\n\n @media all and (min-width: 900px) {\n width: 40rem;\n height: 25rem;\n }\n\n @media all and (min-width: 1000px) {\n width: 50rem;\n height: 35rem;\n }\n`;\n\nconst Presentation = styled.div`\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n\n & > *:first-child {\n margin-bottom: 5rem;\n }\n\n @media all and (min-width: 1000px) {\n margin-bottom: 7.5rem;\n }\n`;\n\nconst Heading = styled.h2`\n color: ${colors.dark};\n text-align: center;\n text-transform: uppercase;\n font-weight: 300;\n font-size: 1.5rem;\n`;\n\nconst Decoration = styled.span`\n display: flex;\n align-items: center;\n align-self: center;\n color: ${colors.accent};\n margin: 1rem 0;\n\n &:before,\n &:after {\n content: \"\";\n display: inline-block;\n margin: 0 1rem;\n height: 1px;\n width: 5rem;\n background: ${colors.accent};\n background: linear-gradient(270deg, transparent, ${colors.accent});\n }\n\n &:before {\n background: linear-gradient(270deg, ${colors.accent}, transparent);\n }\n`;\n\nconst Image = styled.img`\n width: 100%;\n max-height: 100%;\n object-fit: cover;\n`;\n\nconst Text = styled.div`\n display: flex;\n flex-direction: column;\n background: ${colors.background};\n opacity: 0.95;\n color: ${colors.secondary};\n max-width: 25rem;\n border: 5px solid ${colors.primary};\n outline: 2px solid ${colors.primary};\n outline-offset: 5px;\n padding: 2rem 1rem;\n line-height: 1.5rem;\n text-align: justify;\n\n & > p {\n margin-bottom: 1rem;\n }\n\n & > p:last-child {\n margin-bottom: 0;\n }\n\n @media all and (min-width: 500px) {\n padding: 3rem;\n }\n\n @media all and (min-width: 1000px) {\n position: absolute;\n bottom: -5rem;\n right: -5rem;\n }\n`;\n","/home/aureen/the_odin_project/room/src/routes/shop/checkout/Cart.jsx",["1069","1070","1071","1072","1073","1074","1075"],"import React, { useState, useEffect } from \"react\";\nimport styled from \"styled-components\";\nimport { Link } from \"react-router-dom\";\nimport { useAuth } from \"../../../contexts/AuthContext\";\nimport useCart from \"../../../hooks/useCart\";\nimport useSignIn from \"../../../hooks/useSignIn\";\nimport useWindowSize from \"../../../hooks/useWindowSize\";\nimport CartItem from \"../../../components/shop/cart/CartItem\";\n\n// Icons\nimport { ReactComponent as Basket } from \"../../../assets/icons/icon-basket.svg\";\n\nfunction Cart() {\n const [cart, setCart] = useState([]);\n const { getCart, cartListener } = useCart();\n const { windowSize } = useWindowSize();\n\n // Used to sign in before checking out.\n const { currentUser } = useAuth();\n const {\n email,\n setEmail,\n password,\n setPassword,\n emailError,\n passwordError,\n loading,\n handleSignIn,\n handleForgotPassword,\n } = useSignIn();\n\n useEffect(() => {\n (async () => {\n if (!currentUser) return;\n const cart = await getCart(currentUser.uid);\n setCart(cart);\n })();\n }, []);\n\n useEffect(() => {\n if (!currentUser) return;\n const unsubscribe = cartListener(currentUser.uid, async () => {\n const cart = await getCart(currentUser.uid);\n setCart(cart);\n });\n return unsubscribe;\n }, []);\n\n // Helper functions to render\n const renderCart = (cart) => {\n if (cart.length === 0) {\n return (\n <EmptyCart>\n <Heading>Shopping Cart</Heading>\n <BasketIcon />\n <EmptyCartText>\n Oh no, it seems that your cart is empty.\n </EmptyCartText>\n <div>We have a lot of lovely ideas to help you fill it.</div>\n <Link to=\"/shop\">\n <Button>Inspire Me</Button>\n </Link>\n </EmptyCart>\n );\n }\n return (\n <ItemList>\n <Heading>Shopping Cart</Heading>\n {windowSize.width > 620 && (\n <Legend>\n <Product>Product</Product>\n <div>Price</div>\n <div>Quantity</div>\n <div>Total</div>\n {/* Replace the \"X\" Icon to align the grid */}\n <Placeholder />\n </Legend>\n )}\n <div>\n <ul>\n {cart.map((item) => {\n return (\n <li key={item.id}>\n <CartItem item={item} />\n </li>\n );\n })}\n </ul>\n </div>\n\n <Bottom>\n <Link to=\"/shop\">← Continue Shopping</Link>\n <Subtotal>\n Subtotal: £\n {cart.reduce((sum, item) => +item.price * +item.quantity + sum, 0)}\n </Subtotal>\n </Bottom>\n </ItemList>\n );\n };\n\n const renderBox = (cart, currentUser) => {\n if (cart.length === 0) return <></>;\n\n // If the user isn't logged in, we'll suggest him to create an account / log in.\n if (currentUser && currentUser.isAnonymous) {\n return (\n <ToPayment>\n <PaymentHeading>\n <PaymentTitle>Thank you for shopping with us!</PaymentTitle>\n <PaymentText>\n We sincerely hope that all our products will satisfy your needs\n and enhance your interior.\n </PaymentText>\n </PaymentHeading>\n\n <PaymentChoice>Already a customer ?</PaymentChoice>\n <PaymentText>Sign in to continue shopping.</PaymentText>\n\n <form\n onSubmit={(e) => {\n e.preventDefault();\n handleSignIn(true);\n }}\n >\n <Form>\n <Field>\n <Label>Email</Label>\n <Input\n type=\"text\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n />\n {emailError && <Error>{emailError}</Error>}\n </Field>\n\n <Field>\n <Label>Password</Label>\n <Input\n type=\"password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n />\n {passwordError && <Error>{passwordError}</Error>}\n </Field>\n <Message onClick={handleForgotPassword}>\n Forgot your password?\n </Message>\n </Form>\n\n <Flex>\n <PaymentBtn type=\"submit\" disabled={loading}>\n Sign In\n </PaymentBtn>\n </Flex>\n </form>\n\n <PaymentChoice>Don't have an account yet?</PaymentChoice>\n <PaymentText>\n Create one to quickly manage your orders and checkout. We promise it\n will only take a minute.\n </PaymentText>\n <PaymentLink\n to={{\n pathname: \"/account/entry\",\n state: {\n isPaying: true,\n },\n }}\n >\n Create an account\n </PaymentLink>\n\n <PaymentText>Or simply proceed to checkout as a guest.</PaymentText>\n <PaymentLink\n to={{\n pathname: \"/shop/personal\",\n state: {\n isPaying: true,\n },\n }}\n >\n Checkout as a guest\n </PaymentLink>\n </ToPayment>\n );\n // Else, we'll just let him proceed.\n }\n return (\n <ToPayment>\n <PaymentHeading>\n <PaymentTitle>Thank you for shopping with us!</PaymentTitle>\n </PaymentHeading>\n\n <PaymentText>\n We sincerely hope that all our products will satisfy your needs and\n enhance your interior.\n </PaymentText>\n\n <PaymentLink\n to={{\n pathname: \"/shop/personal\",\n state: {\n isPaying: true,\n },\n }}\n >\n Continue\n </PaymentLink>\n </ToPayment>\n );\n };\n\n return (\n <Container>\n <ShoppingCart>\n {renderCart(cart)}\n {renderBox(cart, currentUser)}\n </ShoppingCart>\n </Container>\n );\n}\n\nexport default Cart;\n\n// Styled components\nconst colors = {\n primary: \"hsl(0, 0%, 45%)\", // Grey\n secondary: \"hsl(0, 0%, 27%)\", // Darker grey - for payment background\n text: \"hsl(0, 0%, 95%)\", // White - for payment text\n button: \"hsl(0, 0%, 100%)\",\n border: \"hsl(0, 0%, 90%)\",\n hover: \"hsl(0, 0%, 0%)\", // Black - Continue Shopping Hover\n};\n\nconst Container = styled.div`\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 1;\n margin-top: 3rem;\n\n @media all and (min-width: 576px) {\n margin: 5rem;\n }\n`;\n\nconst ShoppingCart = styled.div`\n @media all and (min-width: 900px) {\n display: flex;\n align-items: start;\n max-width: 1400px;\n }\n`;\n\nconst ItemList = styled.div`\n @media all and (min-width: 576px) {\n padding: 0 2rem;\n }\n\n @media all and (min-width: 900px) {\n padding: 0;\n padding-left: 2rem;\n }\n`;\n\nconst Heading = styled.h1`\n margin-left: 3rem;\n margin-bottom: 2rem;\n font-size: 2rem;\n line-height: 2.75rem;\n font-family: \"Playfair Display\", sans-serif;\n\n @media all and (min-width: 900px) {\n margin-left: initial;\n }\n`;\n\nconst Legend = styled.div`\n padding-left: 0.25rem;\n display: grid;\n grid-template-columns: repeat(4, 1fr) auto;\n border-bottom: 1px solid ${colors.border};\n text-transform: uppercase;\n font-size: 0.9rem;\n color: ${colors.primary};\n justify-items: center;\n padding-bottom: 0.75rem;\n`;\n\nconst Product = styled.div`\n min-width: 320px;\n`;\n\nconst Placeholder = styled.div`\n width: 32px;\n`;\n\nconst Subtotal = styled.div`\n text-transform: uppercase;\n font-size: 0.9rem;\n color: ${colors.primary};\n`;\n\nconst Bottom = styled.div`\n margin: 1rem;\n color: ${colors.secondary};\n display: flex;\n justify-content: space-between;\n\n &:hover {\n color: ${colors.hover};\n }\n`;\n\n// Empty Cart\nconst EmptyCart = styled.div`\n display: flex;\n flex-direction: column;\n align-items: center;\n margin: 1rem;\n`;\n\nconst EmptyCartText = styled.div`\n font-family: \"Playfair Display\", sans-serif;\n font-size: 1.125rem;\n`;\n\nconst Button = styled.button`\n margin-top: 2.5rem;\n font-family: \"Source Sans Pro\", sans-serif;\n text-transform: uppercase;\n font-size: 0.9rem;\n color: ${colors.text};\n background: ${colors.secondary};\n align-self: center;\n padding: 0.5rem 1rem;\n cursor: pointer;\n`;\n\n// Proceed to payment window\nconst ToPayment = styled.div`\n background: ${colors.secondary};\n color: ${colors.text};\n display: flex;\n flex-direction: column;\n margin: 3rem;\n padding: 3rem;\n\n @media all and (min-width: 900px) {\n padding: 2rem;\n }\n\n @media all and (min-width: 1100px) {\n padding: 3rem;\n }\n`;\n\nconst PaymentText = styled.div`\n font-size: 0.9rem;\n line-height: 1.1rem;\n text-align: center;\n\n @media all and (min-width: 900px) {\n text-align: initial;\n }\n`;\n\nconst PaymentTitle = styled.h2`\n font-size: 1.25rem;\n margin-bottom: 0.25rem;\n`;\n\nconst PaymentHeading = styled.div`\n align-self: center;\n text-align: center;\n margin-bottom: 1.5rem;\n`;\n\nconst PaymentChoice = styled.span`\n font-size: 1.125rem;\n`;\n\nconst button = `\n display: inline-block;\n background: ${colors.text};\n color: ${colors.secondary};\n padding: 0.5rem 1rem;\n margin: 1rem 0;\n cursor: pointer;\n text-align: center;\n text-transform: uppercase;\n font-size: 0.9rem;\n font-family: 'Source Sans Pro', sans-serif;\n\n &:hover {\n background: ${colors.button};\n}`;\n\nconst PaymentLink = styled(Link)`\n ${button}\n align-self: center;\n`;\n\nconst PaymentBtn = styled.button`\n ${button}\n\n &:disabled {\n background: ${colors.primary};\n }\n`;\n\nconst Flex = styled.div`\n display: flex;\n justify-content: center;\n`;\n\nconst Form = styled.div`\n background: ${colors.text};\n padding: 1.25rem;\n margin: 1rem 1rem 0 1rem;\n border-radius: 3px;\n\n & > *:first-child {\n margin-bottom: 1.5rem;\n }\n`;\n\nconst Field = styled.div`\n display: flex;\n flex-direction: column;\n`;\n\nconst Label = styled.label`\n color: ${colors.secondary};\n text-transform: uppercase;\n font-size: 0.825rem;\n letter-spacing: 1px;\n`;\n\nconst Input = styled.input`\n border: none;\n background: none;\n border-bottom: 1px solid ${colors.lightGrey};\n padding: 0.5rem 0 0.25rem 0;\n font-family: \"Source Sans Pro\", sans-serif;\n\n &::placeholder {\n color: ${colors.lightGrey};\n }\n\n &:focus {\n border-bottom: 1px solid ${colors.black};\n }\n`;\n\nconst Error = styled.div`\n font-size: 0.825rem;\n color: ${colors.secondary};\n line-height: 1rem;\n`;\n\nconst Message = styled(Error)`\n cursor: pointer;\n`;\n\nconst BasketIcon = styled(Basket)`\n max-width: 30rem;\n max-height: 30rem;\n`;\n","/home/aureen/the_odin_project/room/src/routes/shop/checkout/Payment.jsx",["1076","1077","1078","1079","1080","1081","1082","1083","1084","1085","1086"],"import React, { useState, useEffect } from \"react\";\nimport styled from \"styled-components\";\nimport PropTypes from \"prop-types\";\nimport { Redirect, useHistory } from \"react-router-dom\";\nimport Order from \"../../../components/shop/checkout/Order\";\nimport { useAuth } from \"../../../contexts/AuthContext\";\nimport useCart from \"../../../hooks/useCart\";\nimport useOrder from \"../../../hooks/useOrder\";\nimport usePayment from \"../../../hooks/usePayment\";\nimport useWindowSize from \"../../../hooks/useWindowSize\";\n\n// Icon\nimport check from \"../../../assets/icons/icon-check.svg\";\nimport iconX from \"../../../assets/icons/icon-x.svg\";\n\nfunction Payment({ location }) {\n /* Props :\n - location.state.personal : informations the user entered on the informations page.\n */\n\n const [name, setName] = useState(\"\");\n const [number, setNumber] = useState(\"\");\n const [date, setDate] = useState(\"\");\n const [cvc, setCvc] = useState(\"\");\n const [remember, setRemember] = useState(false);\n const [cards, setCards] = useState([]);\n\n const history = useHistory();\n const { windowSize } = useWindowSize();\n const { currentUser } = useAuth();\n const { getCart, deleteCart } = useCart();\n const { addCard, getCards } = usePayment();\n const { createOrder } = useOrder();\n\n // If the user is logged in, they might have saved cards.\n // We display them so that they can checkout faster.\n useEffect(() => {\n if (currentUser.isAnonymous) return;\n (async () => {\n const cards = await getCards(currentUser.uid);\n setCards(cards);\n })();\n }, []);\n\n const confirmOrder = async (e) => {\n e.preventDefault();\n\n const cart = await getCart(currentUser.uid);\n\n // If the user is logged in, we add their id in the order so that we can add it to their orders list.\n const order = await createOrder(\n cart,\n location.state.personal,\n {\n name,\n number,\n date,\n cvc,\n },\n currentUser.uid\n );\n await deleteCart(currentUser.uid);\n\n if (remember) {\n addCard(currentUser.uid, name, number, date, cvc);\n }\n\n history.push({\n pathname: `/shop/confirmation/${order}`,\n state: {\n payment: true,\n },\n });\n };\n\n return (\n <>\n {location.state ? (\n <Container>\n <Content>\n <Left>\n <Heading>Checkout</Heading>\n\n <Category>\n <Subheading>Shipping Details</Subheading>\n <Informations>\n <div>\n {location.state.personal.firstName}\n{\" \"}\n {location.state.personal.lastName}\n </div>\n <div>{location.state.personal.address}</div>\n <div>\n {location.state.personal.zipCode}\n{\" \"}\n {location.state.personal.city}\n </div>\n <div>{location.state.personal.country}</div>\n </Informations>\n </Category>\n\n <Category>\n <Subheading>Payment Details</Subheading>\n {cards.length !== 0 && (\n <>\n <CategoryName>Use an existing card</CategoryName>\n\n <Category>\n {cards.map((card) => {\n return (\n <Li key={card.id}>\n <div>\n <strong>{card.name}</strong>\n{' '}\n—{\" \"}\n {card.number.slice(-4)}\n </div>\n <CardButton\n type=\"button\"\n onClick={async () => {\n const cart = await getCart(currentUser.uid);\n const order = await createOrder(\n cart,\n location.state.personal,\n {\n name: card.name,\n number: card.number,\n date: card.date,\n cvc: card.cvc,\n },\n currentUser.uid\n );\n await deleteCart(currentUser.uid);\n\n history.push({\n pathname: `/shop/confirmation/${order}`,\n state: {\n payment: true,\n },\n });\n }}\n >\n Pay with this card →\n </CardButton>\n </Li>\n );\n })}\n </Category>\n\n <CategoryName>Use another card</CategoryName>\n </>\n )}\n\n <Form onSubmit={confirmOrder}>\n <Fields>\n <FieldLarge>\n <Label htmlFor=\"name\">Name on card</Label>\n <Input\n type=\"text\"\n value={name}\n id=\"name\"\n onChange={(e) => setName(e.target.value)}\n placeholder=\"Enter your full name\"\n />\n </FieldLarge>\n\n <FieldLarge>\n <Label htmlFor=\"card_number\">Card number</Label>\n <Input\n type=\"text\"\n value={number}\n id=\"card_number\"\n onChange={(e) => {\n const number = e.target.value.replace(/[^0-9]/g, \"\");\n setNumber(number);\n }}\n placeholder=\"Enter your card number\"\n />\n </FieldLarge>\n\n <Field>\n <Label htmlFor=\"date\">Valid Through</Label>\n <Input\n type=\"text\"\n id=\"date\"\n value={date}\n onChange={(e) => setDate(e.target.value)}\n placeholder=\"MM / YY\"\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"cvc\">CVC Code</Label>\n <Input\n type=\"text\"\n id=\"cvc\"\n value={cvc}\n onChange={(e) => {\n const cvc = e.target.value.replace(/[^0-9]/g, \"\");\n setCvc(cvc);\n }}\n placeholder=\"Enter your CVC code\"\n />\n </Field>\n\n {!currentUser.isAnonymous && (\n <>\n <CheckboxLabel htmlFor=\"remember\" isChecked={remember}>\n Remember my card for easier checkout.\n </CheckboxLabel>\n <HiddenInput\n type=\"checkbox\"\n id=\"remember\"\n name=\"remember\"\n checked={remember}\n onChange={() => setRemember(!remember)}\n />\n </>\n )}\n </Fields>\n\n <Button type=\"submit\">Confirm my order</Button>\n </Form>\n </Category>\n </Left>\n {windowSize.width > 900 && <Order />}\n </Content>\n </Container>\n ) : (\n <Redirect to=\"/shop/cart\" />\n )}\n </>\n );\n}\n\nexport default Payment;\n\nPayment.propTypes = {\n location: PropTypes.shape({\n state: PropTypes.shape({\n personal: PropTypes.shape({\n address: PropTypes.string,\n city: PropTypes.string,\n country: PropTypes.string,\n email: PropTypes.string,\n firstName: PropTypes.string,\n lastName: PropTypes.string,\n phone: PropTypes.string,\n zipCode: PropTypes.string,\n }),\n }),\n }).isRequired,\n};\n\n// Styled Components\nconst colors = {\n primary: \"hsl(0, 0%, 45%)\", // Grey\n secondary: \"hsl(0, 0%, 27%)\", // Button and checkbox\n tertiary: \"hsl(0, 0%, 90%)\",\n input: \"hsl(0, 0%, 70%)\", // Input lines\n black: \"hsl(0, 0%, 0%)\",\n};\n\nconst Container = styled.div`\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 1;\n margin: 5rem 2rem;\n\n @media all and (min-width: 576px) {\n margin: 5rem;\n }\n`;\n\nconst Content = styled.div`\n width: 100%;\n\n @media all and (min-width: 900px) {\n display: flex;\n align-items: start;\n max-width: 1400px;\n width: 80%;\n }\n`;\n\nconst Left = styled.div`\n min-width: 40vw;\n`;\n\nconst Category = styled.div`\n margin-bottom: 2.5rem;\n`;\n\nconst CategoryName = styled.div`\n border-bottom: 1px solid ${colors.tertiary};\n text-transform: uppercase;\n font-size: 0.9rem;\n color: ${colors.primary};\n padding-bottom: 0.25rem;\n margin-bottom: 1.25rem;\n`;\n\nconst Informations = styled.div`\n line-height: 1.125rem;\n`;\n\nconst Heading = styled.h1`\n margin-bottom: 2rem;\n font-size: 2rem;\n line-height: 2.75rem;\n font-family: \"Playfair Display\", sans-serif;\n`;\n\nconst Subheading = styled.div`\n border-bottom: 1px solid ${colors.black};\n text-transform: uppercase;\n color: ${colors.black};\n padding-bottom: 0.25rem;\n margin-bottom: 1.5rem;\n`;\n\nconst Form = styled.form`\n display: flex;\n flex-direction: column;\n align-items: center;\n`;\n\nconst Fields = styled.div`\n display: grid;\n grid-gap: 3rem 5rem;\n\n @media all and (min-width: 576px) {\n grid-template-columns: repeat(2, 1fr);\n }\n`;\n\nconst Field = styled.div`\n display: flex;\n flex-direction: column;\n`;\n\nconst FieldLarge = styled(Field)`\n grid-column: 1 / -1;\n`;\n\nconst Label = styled.label`\n text-transform: uppercase;\n font-size: 0.825rem;\n letter-spacing: 1px;\n`;\n\nconst Input = styled.input`\n border: none;\n border-bottom: 1px solid ${colors.input};\n padding: 0.5rem 0 0.25rem 0;\n font-family: \"Source Sans Pro\", sans-serif;\n\n &::placeholder {\n color: ${colors.input};\n }\n\n &:focus {\n border-bottom: 1px solid ${colors.black};\n }\n`;\n\nconst HiddenInput = styled.input`\n visibility: hidden;\n`;\n\nconst CheckboxLabel = styled.label`\n display: flex;\n align-items: center;\n\n &:before {\n display: inline-block;\n content: \"\";\n width: 1rem;\n height: 1rem;\n margin-right: 0.5rem;\n border-radius: 2px;\n border: 1px solid ${colors.secondary};\n background-color: ${(props) => props.isChecked && colors.secondary};\n background-image: ${(props) => props.isChecked && `url(${check})`};\n background-position: ${(props) => props.isChecked && \"center\"};\n }\n`;\n\nconst Li = styled.li`\n padding-left: 1rem;\n text-indent: 1rem;\n line-height: 1.25rem;\n display: flex;\n align-items: center;\n margin-bottom: 0.5rem;\n\n &:before {\n content: \"\";\n display: inline-block;\n width: 15px;\n height: 15px;\n background: url(${iconX});\n }\n`;\n\nconst CardButton = styled.button`\n margin-left: auto;\n color: ${colors.secondary};\n\n &:hover {\n color: ${colors.black};\n }\n`;\n\nconst Button = styled.button`\n margin-top: 2.5rem;\n font-family: \"Source Sans Pro\", sans-serif;\n text-transform: uppercase;\n font-size: 0.9rem;\n color: ${colors.tertiary};\n background: ${colors.secondary};\n align-self: center;\n padding: 0.5rem 1rem;\n cursor: pointer;\n`;\n","/home/aureen/the_odin_project/room/src/routes/shop/checkout/Personal.jsx",["1087","1088","1089","1090"],"import React, { useState, useEffect } from \"react\";\nimport styled from \"styled-components\";\nimport PropTypes from \"prop-types\";\nimport { Redirect, useHistory } from \"react-router-dom\";\nimport { useAuth } from \"../../../contexts/AuthContext\";\nimport useAddress from \"../../../hooks/useAddress\";\nimport useWindowSize from \"../../../hooks/useWindowSize\";\nimport Order from \"../../../components/shop/checkout/Order\";\n\n// Icon\nimport check from \"../../../assets/icons/icon-check.svg\";\n\nfunction Personal({ location }) {\n /* Props :\n - location.state.isPaying : true if user comes from /shop/cart.\n */\n\n const [additional, setAdditional] = useState(\"\");\n const [remember, setRemember] = useState(false);\n const [addresses, setAddresses] = useState([]);\n\n const { currentUser } = useAuth();\n const { windowSize } = useWindowSize();\n const {\n handleAddAddress,\n getAddresses,\n firstName,\n setFirstName,\n lastName,\n setLastName,\n address,\n setAddress,\n city,\n setCity,\n zipCode,\n setZipCode,\n country,\n setCountry,\n email,\n setEmail,\n phone,\n setPhone,\n } = useAddress();\n const history = useHistory();\n\n // If the user is logged in, they might have saved addresses.\n // We display them so that they can checkout faster.\n useEffect(() => {\n if (currentUser.isAnonymous) return;\n (async () => {\n const addresses = await getAddresses(currentUser.uid);\n setAddresses(addresses);\n })();\n }, []);\n\n const handleSubmit = (e) => {\n e.preventDefault();\n\n if (remember) {\n handleAddAddress(currentUser.uid);\n }\n\n history.push({\n pathname: \"/shop/payment\",\n state: {\n personal: {\n firstName,\n lastName,\n email,\n phone,\n address,\n city,\n zipCode,\n country,\n },\n },\n });\n };\n\n return (\n <>\n {/* If the user didn't access to this page via the cart links,\n - Redirect them to their cart.\n - Otherwise, ask for their personal details. */}\n {location.state ? (\n <Container>\n <Content>\n <Form onSubmit={handleSubmit}>\n <Heading>Personal Details</Heading>\n\n {!currentUser.isAnonymous && addresses.length !== 0 && (\n <>\n <Subheading>Address Book</Subheading>\n <Addresses>\n {addresses.map((address) => {\n return (\n <div key={address.id}>\n <div>\n {address.firstName} {address.lastName}\n </div>\n <div>{address.address}</div>\n <div>\n {address.zipCode} {address.city}\n </div>\n <div>{address.country}</div>\n <Button\n onClick={() => {\n history.push({\n pathname: \"/shop/payment\",\n state: {\n personal: {\n firstName: address.firstName,\n lastName: address.lastName,\n address: address.address,\n zipCode: address.zipCode,\n country: address.country,\n city: address.city,\n email: address.email,\n phone: address.phone,\n additional,\n },\n },\n });\n }}\n >\n Use this address\n </Button>\n </div>\n );\n })}\n </Addresses>\n\n <Subheading>Use another address</Subheading>\n </>\n )}\n\n <CategoryName>General</CategoryName>\n <Category>\n <Field>\n <Label htmlFor=\"first_name\">First Name</Label>\n <Input\n type=\"text\"\n value={firstName}\n id=\"first_name\"\n onChange={(e) => setFirstName(e.target.value)}\n placeholder=\"Enter your first name\"\n required\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"last_name\">Last Name</Label>\n <Input\n type=\"text\"\n value={lastName}\n id=\"last_name\"\n onChange={(e) => setLastName(e.target.value)}\n placeholder=\"Enter your last name\"\n required\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"email\">Email</Label>\n <Input\n type=\"email\"\n id=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder=\"Enter your email\"\n required\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"phone\">Phone Number</Label>\n <Input\n type=\"tel\"\n id=\"phone\"\n value={phone}\n onChange={(e) => setPhone(e.target.value)}\n placeholder=\"Enter your phone number\"\n required\n />\n </Field>\n </Category>\n\n <CategoryName>Delivery</CategoryName>\n <Category>\n <Field>\n <Label htmlFor=\"address\">Address</Label>\n <Input\n type=\"text\"\n id=\"address\"\n value={address}\n onChange={(e) => setAddress(e.target.value)}\n placeholder=\"Enter your address\"\n required\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"zip_code\">Zip Code</Label>\n <Input\n type=\"text\"\n id=\"zip_code\"\n value={zipCode}\n onChange={(e) => setZipCode(e.target.value)}\n placeholder=\"Enter your zip code\"\n required\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"city\">City</Label>\n <Input\n type=\"text\"\n id=\"city\"\n value={city}\n onChange={(e) => setCity(e.target.value)}\n placeholder=\"Enter your city\"\n required\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"country\">Country</Label>\n <Input\n type=\"text\"\n id=\"country\"\n value={country}\n onChange={(e) => setCountry(e.target.value)}\n placeholder=\"Enter your country\"\n required\n />\n </Field>\n\n <FieldLarge>\n <Label htmlFor=\"additional\">Additional Informations</Label>\n <Input\n type=\"text\"\n id=\"additional\"\n value={additional}\n onChange={(e) => setAdditional(e.target.value)}\n placeholder=\"Anything else you would like to tell us (building entrance codes, prefered delivery time...)\"\n />\n </FieldLarge>\n </Category>\n\n {currentUser && !currentUser.isAnonymous && (\n <>\n <CheckboxLabel htmlFor=\"remember\" isChecked={remember}>\n Remember my informations for easier checkout.\n </CheckboxLabel>\n <Checkbox\n type=\"checkbox\"\n id=\"remember\"\n name=\"remember\"\n checked={remember}\n onChange={() => setRemember(!remember)}\n />\n </>\n )}\n\n <Button type=\"submit\">Proceed to Payment</Button>\n </Form>\n {windowSize.width > 900 && <Order />}\n </Content>\n </Container>\n ) : (\n <Redirect to=\"/shop/cart\" />\n )}\n </>\n );\n}\n\nexport default Personal;\n\nPersonal.propTypes = {\n location: PropTypes.shape({\n state: PropTypes.shape({\n isPaying: PropTypes.bool,\n }),\n }).isRequired,\n};\n\n// Styled Components\nconst colors = {\n primary: \"hsl(0, 0%, 45%)\", // Grey\n secondary: \"hsl(0, 0%, 27%)\", // Button and checkbox\n tertiary: \"hsl(0, 0%, 90%)\",\n input: \"hsl(0, 0%, 70%)\", // Input lines\n black: \"hsl(0, 0%, 0%)\",\n};\n\nconst Container = styled.div`\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 1;\n margin: 5rem 0;\n\n @media all and (min-width: 576px) {\n margin: 5rem;\n }\n`;\n\nconst Content = styled.div`\n width: 80%;\n\n @media all and (min-width: 900px) {\n display: flex;\n align-items: start;\n max-width: 1400px;\n }\n`;\n\nconst Form = styled.form`\n display: flex;\n flex-direction: column;\n min-width: 40vw;\n`;\n\nconst Category = styled.div`\n display: grid;\n grid-gap: 3rem 5rem;\n margin: 1.25rem 0 3rem 0;\n\n @media all and (min-width: 576px) {\n grid-template-columns: repeat(2, 1fr);\n }\n`;\n\nconst CategoryName = styled.div`\n grid-column: 1 / -1;\n border-bottom: 1px solid ${colors.tertiary};\n text-transform: uppercase;\n font-size: 0.9rem;\n color: ${colors.primary};\n padding-bottom: 0.25rem;\n`;\n\nconst Field = styled.div`\n display: flex;\n flex-direction: column;\n`;\n\nconst FieldLarge = styled(Field)`\n grid-column: 1 / -1;\n`;\n\nconst Button = styled.button`\n margin-top: 1.5rem;\n font-family: \"Source Sans Pro\", sans-serif;\n text-transform: uppercase;\n font-size: 0.9rem;\n color: ${colors.tertiary};\n background: ${colors.secondary};\n align-self: center;\n padding: 0.5rem 1rem;\n cursor: pointer;\n`;\n\nconst Label = styled.label`\n text-transform: uppercase;\n font-size: 0.825rem;\n letter-spacing: 1px;\n`;\n\nconst Input = styled.input`\n border: none;\n border-bottom: 1px solid ${colors.input};\n padding: 0.5rem 0 0.25rem 0;\n font-family: \"Source Sans Pro\", sans-serif;\n\n &::placeholder {\n color: ${colors.input};\n }\n\n &:focus {\n border-bottom: 1px solid ${colors.black};\n }\n`;\n\nconst Checkbox = styled.input`\n visibility: hidden;\n`;\n\nconst CheckboxLabel = styled.label`\n display: flex;\n align-items: center;\n\n &:before {\n display: inline-block;\n content: \"\";\n width: 1rem;\n height: 1rem;\n margin-right: 0.5rem;\n border-radius: 2px;\n border: 1px solid ${colors.secondary};\n background-color: ${(props) => (props.isChecked ? colors.secondary : \"\")};\n background-image: ${(props) => (props.isChecked ? `url(${check})` : \"\")};\n background-position: ${(props) => (props.isChecked ? \"center\" : \"\")};\n }\n`;\n\nconst Heading = styled.h1`\n margin-bottom: 2rem;\n font-size: 2rem;\n line-height: 2.75rem;\n font-family: \"Playfair Display\", sans-serif;\n`;\n\nconst Subheading = styled.div`\n border-bottom: 1px solid ${colors.black};\n text-transform: uppercase;\n color: ${colors.black};\n padding-bottom: 0.25rem;\n margin-bottom: 1.5rem;\n`;\n\n// Address Book\n\nconst Addresses = styled.div`\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n grid-gap: 1rem;\n margin-bottom: 2.5rem;\n`;\n","/home/aureen/the_odin_project/room/src/routes/shop/checkout/Confirmation.jsx",["1091","1092","1093","1094","1095","1096","1097","1098","1099","1100"],"import React, { useState, useEffect } from \"react\";\nimport styled from \"styled-components\";\nimport PropTypes from \"prop-types\";\nimport { Link } from \"react-router-dom\";\nimport useOrder from \"../../../hooks/useOrder\";\nimport CartPreview from \"../../../components/shop/cart/CartPreview\";\n\nfunction Confirmation({ match }) {\n const [order, setOrder] = useState({});\n const [loading, setLoading] = useState(true);\n const { getOrder } = useOrder();\n\n useEffect(() => {\n (async () => {\n const order = await getOrder(match.params.id);\n setOrder(order);\n setLoading(false);\n })();\n }, []);\n\n return (\n <div>\n <Container>\n <Content>\n {!loading && (\n <Order>\n <Heading>Order Confirmation</Heading>\n\n <Summary>\n <CategoryName>Order Summary</CategoryName>\n <CartPreview cart={order.products} />\n </Summary>\n\n <div>\n <CategoryName>Shipping Details</CategoryName>\n {order.shipping.firstName} {order.shipping.lastName}\n <br />\n {order.shipping.address}\n <br />\n {order.shipping.zipCode} {order.shipping.city}\n <br />\n {order.shipping.country}\n </div>\n </Order>\n )}\n\n <Message>\n <MessageHeading>Confirmation</MessageHeading>\n\n <p>\n Your order n°\n <strong>{match.params.id}</strong>\n {' '}\n has been confirmed. You will be receiving a confirmation mail with your order details shortly.\n </p>\n\n <p>\n You can follow your order's status at any given time{\" \"}\n <MessageLink>\n <Link to=\"/\">here</Link>\n </MessageLink>\n . If you have any other questions, feel free to{\" \"}\n <MessageLink>\n <Link to=\"/contact\">contact us.</Link>\n </MessageLink>\n </p>\n\n <p>Thank you for shopping with us!</p>\n\n <Button>\n <Link to=\"/shop\">Continue Shopping</Link>\n </Button>\n </Message>\n </Content>\n </Container>\n </div>\n );\n}\n\nexport default Confirmation;\n\nConfirmation.propTypes = {\n match: PropTypes.shape({\n params: PropTypes.shape({\n id: PropTypes.string,\n }),\n }).isRequired,\n};\n\nconst colors = {\n primary: \"hsl(0, 0%, 45%)\", // Grey\n secondary: \"hsl(0, 0%, 27%)\", // Darker grey - for payment background\n text: \"hsl(0, 0%, 95%)\", // White - for payment text\n button: \"hsl(0, 0%, 100%)\",\n};\n\nconst Container = styled.div`\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 1;\n margin: 5rem;\n`;\n\nconst Content = styled.div`\n @media all and (min-width: 900px) {\n display: flex;\n align-items: start;\n max-width: 1400px;\n }\n`;\n\nconst Order = styled.div`\n min-width: 40vw;\n`;\n\nconst Summary = styled.div`\n display: flex;\n flex-direction: column;\n`;\n\nconst Message = styled.aside`\n @media all and (min-width: 900px) {\n margin-left: 5rem;\n margin-top: 0;\n }\n\n margin-top: 3rem;\n background: ${colors.secondary};\n color: ${colors.text};\n padding: 4rem;\n display: flex;\n flex-direction: column;\n max-width: 25rem;\n line-height: 1.25rem;\n text-align: justify;\n\n & > * {\n margin-bottom: 1rem;\n }\n`;\n\nconst MessageHeading = styled.h2`\n text-transform: uppercase;\n font-size: 1.125rem;\n letter-spacing: 1px;\n align-self: center;\n margin-bottom: 2rem;\n`;\n\nconst MessageLink = styled.span`\n text-decoration: underline;\n cursor: pointer;\n`;\n\nconst Heading = styled.h1`\n margin-bottom: 2rem;\n font-size: 2rem;\n line-height: 2.75rem;\n font-family: \"Playfair Display\", sans-serif;\n`;\n\nconst CategoryName = styled.div`\n border-bottom: 1px solid ${colors.tertiary};\n text-transform: uppercase;\n font-size: 0.9rem;\n color: ${colors.primary};\n padding-bottom: 0.25rem;\n margin-bottom: 1rem;\n`;\n\nconst Button = styled.button`\n display: inline-block;\n background: ${colors.text};\n color: ${colors.secondary};\n padding: 0.5rem 1rem;\n margin: 1rem 0;\n cursor: pointer;\n text-align: center;\n text-transform: uppercase;\n font-size: 0.9rem;\n font-family: \"Source Sans Pro\", sans-serif;\n\n &:hover {\n background: ${colors.button};\n }\n`;\n","/home/aureen/the_odin_project/room/src/components/account/AccountNav.jsx",["1101"],"import React, { useState } from \"react\";\nimport PropTypes from \"prop-types\";\nimport styled from \"styled-components\";\nimport { Link } from \"react-router-dom\";\n\nfunction AccountNav({ currentLink }) {\n const [links, setLinks] = useState([\n \"user\",\n \"orders\",\n \"addresses\",\n \"payment\",\n ]);\n\n return (\n <Nav>\n {links.map((link) => {\n return currentLink === link ? (\n <CurrentLink key={link} isSelected={currentLink === link}>\n {link}\n </CurrentLink>\n ) : (\n <NavLink to={`/account/${link}`} key={link}>\n {link}\n </NavLink>\n );\n })}\n </Nav>\n );\n}\n\nAccountNav.propTypes = {\n currentLink: PropTypes.string.isRequired,\n};\n\nexport default AccountNav;\n\nconst colors = {\n primary: \"hsl(0, 0%, 0%)\", // Black\n secondary: \"hsl(0, 0%, 37%)\", // Grey\n};\n\nconst Nav = styled.nav`\n margin-bottom: 1rem;\n display: flex;\n justify-content: space-between;\n font-family: \"Source Sans Pro\", sans-serif;\n text-transform: capitalize;\n max-width: 80vw;\n width: 100vw;\n\n & > * {\n margin: 0.5rem 0;\n }\n\n @media all and (min-width: 930px) {\n flex-direction: column;\n margin-bottom: 0;\n margin-right: 5rem;\n width: initial;\n }\n`;\n\nconst NavLink = styled(Link)`\n color: ${colors.secondary};\n transition: all 0.3s ease;\n\n &:hover {\n color: ${colors.primary};\n text-decoration: underline;\n }\n\n @media all and (min-width: 930px) {\n transform: translateX(${(props) => (props.selected ? \"0\" : \"3\")}%);\n }\n`;\n\nconst CurrentLink = styled.span`\n position: relative;\n color: ${colors.primary};\n font-weight: 600;\n\n &:after {\n background: none repeat scroll 0 0 transparent;\n left: 0;\n content: \"\";\n display: block;\n height: 2px;\n bottom: -0.5rem;\n position: absolute;\n background: ${colors.secondary};\n transition: all 0.3s ease 0s, top 0.3s ease 0s;\n width: ${(props) => (props.isSelected ? \"110%\" : \"0\")};\n left: ${(props) => (props.isSelected ? \"-2.5%\" : \"50%\")};\n }\n\n @media all and (min-width: 930px) {\n &:after {\n bottom: 0;\n width: 2px;\n left: -1rem;\n height: ${(props) => (props.isSelected ? \"110%\" : \"0\")};\n top: ${(props) => (props.isSelected ? \"5%\" : \"50%\")};\n }\n }\n`;\n","/home/aureen/the_odin_project/room/src/routes/account/settings/Orders.jsx",["1102"],"import React, { useState, useEffect } from \"react\";\nimport styled from \"styled-components\";\nimport { useAuth } from \"../../../contexts/AuthContext\";\nimport useOrder from \"../../../hooks/useOrder\";\nimport Order from \"../../../components/account/Order\";\n\nfunction Orders() {\n const { currentUser } = useAuth();\n const { getOrders } = useOrder();\n const [orders, setOrders] = useState([]);\n\n useEffect(() => {\n (async () => {\n const orders = await getOrders(currentUser.uid);\n setOrders(orders);\n })();\n }, []);\n\n return (\n <div>\n <Heading>Orders</Heading>\n <div>\n {orders.map((order) => {\n return <Order order={order} key={order.id} />;\n })}\n </div>\n </div>\n );\n}\n\nexport default Orders;\n\nconst Heading = styled.h1`\n margin-left: 2rem;\n margin-bottom: 2rem;\n font-size: 2rem;\n line-height: 2.75rem;\n font-family: \"Playfair Display\", sans-serif;\n\n @media all and (min-width: 500px) {\n margin-left: 0;\n }\n`;\n","/home/aureen/the_odin_project/room/src/routes/account/settings/Addresses.jsx",["1103","1104","1105","1106","1107","1108","1109"],"import React, { useState, useEffect } from \"react\";\nimport styled from \"styled-components\";\nimport Modal from \"react-modal\";\nimport { useAuth } from \"../../../contexts/AuthContext\";\nimport useAddress from \"../../../hooks/useAddress\";\n\n// Icons\nimport { ReactComponent as Plus } from \"../../../assets/icons/icon-plus.svg\";\nimport { ReactComponent as Minus } from \"../../../assets/icons/icon-minus.svg\";\nimport { ReactComponent as Close } from \"../../../assets/icons/icon-close.svg\";\n\nfunction Addresses() {\n const [addresses, setAddresses] = useState([]);\n const [isDropdownOpen, setIsDropdownOpen] = useState(false);\n const { currentUser } = useAuth();\n const {\n handleAddAddress,\n handleStartEditing,\n handleEditAddress,\n deleteAddress,\n getAddresses,\n addressListener,\n firstName,\n setFirstName,\n lastName,\n setLastName,\n address,\n setAddress,\n city,\n setCity,\n zipCode,\n setZipCode,\n country,\n setCountry,\n email,\n setEmail,\n phone,\n setPhone,\n message,\n isEditing,\n setIsEditing,\n firstNameEdit,\n setFirstNameEdit,\n lastNameEdit,\n setLastNameEdit,\n addressEdit,\n setAddressEdit,\n cityEdit,\n setCityEdit,\n zipCodeEdit,\n setZipCodeEdit,\n countryEdit,\n setCountryEdit,\n emailEdit,\n setEmailEdit,\n phoneEdit,\n setPhoneEdit,\n messageEdit,\n } = useAddress();\n\n useEffect(() => {\n (async () => {\n const addresses = await getAddresses(currentUser.uid);\n setAddresses(addresses);\n\n // If the user doesn't have any addresses yet, the \"add a new address\" form opens.\n addresses.length === 0 && setIsDropdownOpen(true);\n })();\n }, []);\n\n useEffect(() => {\n const unsubscribe = addressListener(currentUser.uid, async () => {\n const addresses = await getAddresses(currentUser.uid);\n setAddresses(addresses);\n });\n return unsubscribe;\n }, []);\n\n return (\n <div>\n <Heading>Address Book</Heading>\n <div>\n <Subheading>Current addresses</Subheading>\n {addresses.length === 0 ? (\n <Instructions>\n <div>You do not currently have any saved addresses.</div>\n <div>Add one by completing the form below.</div>\n </Instructions>\n ) : (\n <AddressBook>\n {addresses.map((address) => {\n return (\n <React.Fragment key={address.id}>\n <Address>\n <strong>\n {address.firstName} {address.lastName}\n </strong>\n <div>{address.address}</div>\n <div>\n {address.zipCode} {address.city}\n </div>\n <div>{address.country}</div>\n\n <Buttons>\n <ButtonEmpty onClick={() => handleStartEditing(address)}>\n Edit\n </ButtonEmpty>\n <Button\n onClick={() =>\n deleteAddress(currentUser.uid, address.id)\n }\n >\n Delete\n </Button>\n </Buttons>\n </Address>\n\n <EditModal\n isOpen={isEditing}\n onRequestClose={() => setIsEditing(false)}\n style={{\n overlay: {\n backgroundColor: \"rgba(255, 255, 255, .55)\",\n },\n }}\n >\n <EditHeading>Edit your address</EditHeading>\n <Icon onClick={() => setIsEditing(false)}>\n <Close />\n </Icon>\n <Form\n onSubmit={async (e) => {\n e.preventDefault();\n handleEditAddress(currentUser.uid, address.id);\n }}\n >\n <Category>General</Category>\n <Fields>\n <Field>\n <Label htmlFor=\"first_name_edit\">First Name</Label>\n <Input\n type=\"text\"\n value={firstNameEdit}\n id=\"first_name_edit\"\n onChange={(e) => setFirstNameEdit(e.target.value)}\n placeholder=\"Enter your first name\"\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"last_name_edit\">Last Name</Label>\n <Input\n type=\"text\"\n value={lastNameEdit}\n id=\"last_name_edit\"\n onChange={(e) => setLastNameEdit(e.target.value)}\n placeholder=\"Enter your last name\"\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"email_edit\">Email</Label>\n <Input\n type=\"email\"\n id=\"email_edit\"\n value={emailEdit}\n onChange={(e) => setEmailEdit(e.target.value)}\n placeholder=\"Enter your email\"\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"phone_edit\">Phone Number</Label>\n <Input\n type=\"tel\"\n id=\"phone_edit\"\n value={phoneEdit}\n onChange={(e) => setPhoneEdit(e.target.value)}\n placeholder=\"Enter your phone number\"\n />\n </Field>\n </Fields>\n\n <Category>Delivery</Category>\n\n <Fields>\n <Field>\n <Label htmlFor=\"address_edit\">Address</Label>\n <Input\n type=\"text\"\n id=\"address_edit\"\n value={addressEdit}\n onChange={(e) => setAddressEdit(e.target.value)}\n placeholder=\"Enter your address\"\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"zip_code_edit\">Zip Code</Label>\n <Input\n type=\"text\"\n id=\"zip_code_edit\"\n value={zipCodeEdit}\n onChange={(e) => setZipCodeEdit(e.target.value)}\n placeholder=\"Enter your zip code\"\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"city_edit\">City</Label>\n <Input\n type=\"text\"\n id=\"city_edit\"\n value={cityEdit}\n onChange={(e) => setCityEdit(e.target.value)}\n placeholder=\"Enter your city\"\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"country_edit\">Country</Label>\n <Input\n type=\"text\"\n id=\"country_edit\"\n value={countryEdit}\n onChange={(e) => setCountryEdit(e.target.value)}\n placeholder=\"Enter your country\"\n />\n </Field>\n </Fields>\n <Buttons>\n <ButtonEmpty onClick={() => setIsEditing(false)}>\n Cancel\n </ButtonEmpty>\n <Button type=\"submit\">Edit your address</Button>\n </Buttons>\n <Message>{messageEdit}</Message>\n </Form>\n </EditModal>\n </React.Fragment>\n );\n })}\n </AddressBook>\n )}\n\n <FormHeading onClick={() => setIsDropdownOpen(!isDropdownOpen)}>\n Add a new address\n {isDropdownOpen ? <Minus /> : <Plus />}\n </FormHeading>\n\n {isDropdownOpen && (\n <Form\n onSubmit={(e) => {\n e.preventDefault();\n handleAddAddress(currentUser.uid);\n }}\n >\n <Category>General</Category>\n <Fields>\n <Field>\n <Label htmlFor=\"first_name\">First Name</Label>\n <Input\n type=\"text\"\n value={firstName}\n id=\"first_name\"\n onChange={(e) => setFirstName(e.target.value)}\n placeholder=\"Enter your first name\"\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"last_name\">Last Name</Label>\n <Input\n type=\"text\"\n value={lastName}\n id=\"last_name\"\n onChange={(e) => setLastName(e.target.value)}\n placeholder=\"Enter your last name\"\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"email\">Email</Label>\n <Input\n type=\"email\"\n id=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder=\"Enter your email\"\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"phone\">Phone Number</Label>\n <Input\n type=\"tel\"\n id=\"phone\"\n value={phone}\n onChange={(e) => setPhone(e.target.value)}\n placeholder=\"Enter your phone number\"\n />\n </Field>\n </Fields>\n\n <Category>Delivery</Category>\n\n <Fields>\n <Field>\n <Label htmlFor=\"address\">Address</Label>\n <Input\n type=\"text\"\n id=\"address\"\n value={address}\n onChange={(e) => setAddress(e.target.value)}\n placeholder=\"Enter your address\"\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"zip_code\">Zip Code</Label>\n <Input\n type=\"text\"\n id=\"zip_code\"\n value={zipCode}\n onChange={(e) => setZipCode(e.target.value)}\n placeholder=\"Enter your zip code\"\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"city\">City</Label>\n <Input\n type=\"text\"\n id=\"city\"\n value={city}\n onChange={(e) => setCity(e.target.value)}\n placeholder=\"Enter your city\"\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"country\">Country</Label>\n <Input\n type=\"text\"\n id=\"country\"\n value={country}\n onChange={(e) => setCountry(e.target.value)}\n placeholder=\"Enter your country\"\n />\n </Field>\n </Fields>\n\n <Button type=\"submit\">Add a new address</Button>\n <Message>{message}</Message>\n </Form>\n )}\n </div>\n </div>\n );\n}\n\nexport default Addresses;\n\n// Styled Components\nconst colors = {\n primary: \"hsl(0, 0%, 45%)\", // Grey\n secondary: \"hsl(0, 0%, 27%)\", // Dark Grey\n tertiary: \"hsl(0, 0%, 70%)\", // Bright Grey\n text: \"hsl(0, 0%, 85%)\",\n label: \"hsl(0, 0%, 100%)\",\n dark: \"hsl(0, 0%, 0%)\",\n};\n\nconst Heading = styled.h1`\n margin-bottom: 2rem;\n font-size: 2rem;\n line-height: 2.75rem;\n font-family: \"Playfair Display\", sans-serif;\n`;\n\nconst Subheading = styled.div`\n border-bottom: 1px solid ${colors.black};\n text-transform: uppercase;\n color: ${colors.black};\n padding-bottom: 0.25rem;\n margin-bottom: 1.5rem;\n`;\n\nconst FormHeading = styled(Subheading)`\n cursor: pointer;\n display: flex;\n justify-content: space-between;\n`;\n\nconst Category = styled.div`\n border-bottom: 1px solid ${colors.tertiary};\n text-transform: uppercase;\n font-size: 0.9rem;\n color: ${colors.primary};\n padding-bottom: 0.25rem;\n margin-bottom: 1.5rem;\n`;\n\nconst Instructions = styled.div`\n text-align: center;\n margin: 1rem 0;\n color: ${colors.secondary};\n`;\n\nconst AddressBook = styled.div`\n display: grid;\n margin: 2rem;\n grid-gap: 2rem;\n\n @media all and (min-width: 576px) {\n grid-template-columns: repeat(2, 1fr);\n }\n\n @media all and (min-width: 992px) {\n grid-template-columns: repeat(3, 1fr);\n }\n`;\n\nconst Address = styled.div`\n padding: 1rem;\n border: 1px solid ${colors.tertiary};\n border-radius: 5px;\n`;\n\nconst Form = styled.form`\n display: flex;\n flex-direction: column;\n`;\n\nconst Fields = styled.div`\n display: grid;\n grid-gap: 3rem 5rem;\n margin-bottom: 2.5rem;\n\n @media all and (min-width: 576px) {\n grid-template-columns: repeat(2, 1fr);\n }\n`;\n\nconst Field = styled.div`\n display: flex;\n flex-direction: column;\n`;\n\nconst Label = styled.label`\n text-transform: uppercase;\n font-size: 0.825rem;\n letter-spacing: 1px;\n`;\n\nconst Input = styled.input`\n border: none;\n border-bottom: 1px solid ${colors.input};\n padding: 0.5rem 0 0.25rem 0;\n font-family: \"Source Sans Pro\", sans-serif;\n\n &::placeholder {\n color: ${colors.input};\n }\n\n &:focus {\n border-bottom: 1px solid ${colors.black};\n }\n`;\n\nconst Buttons = styled.div`\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n grid-gap: 1rem;\n`;\n\nconst Button = styled.button`\n margin-top: 1.5rem;\n text-transform: uppercase;\n font-size: 0.9rem;\n color: ${colors.text};\n background: ${colors.secondary};\n align-self: center;\n padding: 0.5rem 1rem;\n cursor: pointer;\n\n &:hover {\n color: ${colors.label};\n }\n`;\n\nconst ButtonEmpty = styled(Button)`\n background: transparent;\n color: ${colors.secondary};\n border: 1px solid ${colors.secondary};\n\n &:hover {\n color: ${colors.dark};\n }\n`;\n\nconst EditModal = styled(Modal)`\n position: absolute;\n max-width: 600px;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n background: ${colors.label};\n padding: 4rem;\n border: 1px solid ${colors.secondary};\n\n &:focus {\n outline: none;\n }\n`;\n\nconst EditHeading = styled.h2`\n text-align: center;\n font-family: \"Playfair Display\", sans-serif;\n font-size: 1.25rem;\n margin-bottom: 1rem;\n`;\n\nconst Message = styled.div`\n text-align: center;\n font-size: 0.825rem;\n color: ${colors.primary};\n margin-top: 0.25rem;\n`;\n\nconst Icon = styled.button`\n position: absolute;\n cursor: pointer;\n top: 1rem;\n right: 1rem;\n color: ${colors.primary};\n\n &:hover {\n color: ${colors.secondary};\n }\n`;\n","/home/aureen/the_odin_project/room/src/routes/account/settings/Payment.jsx",["1110","1111","1112","1113","1114","1115","1116","1117","1118","1119","1120","1121"],"import React, { useState, useEffect } from \"react\";\nimport styled from \"styled-components\";\nimport Modal from \"react-modal\";\nimport { useAuth } from \"../../../contexts/AuthContext\";\nimport usePayment from \"../../../hooks/usePayment\";\n\n// Icons\nimport { ReactComponent as Plus } from \"../../../assets/icons/icon-plus.svg\";\nimport { ReactComponent as Minus } from \"../../../assets/icons/icon-minus.svg\";\nimport { ReactComponent as Close } from \"../../../assets/icons/icon-close.svg\";\n\nfunction Payment() {\n const { currentUser } = useAuth();\n const [cards, setCards] = useState([]);\n const [isDropdownOpen, setIsDropdownOpen] = useState(false);\n const {\n handleAddCard,\n handleStartEditing,\n handleEditCard,\n deleteCard,\n getCards,\n cardListener,\n name,\n setName,\n number,\n setNumber,\n date,\n setDate,\n cvc,\n setCvc,\n message,\n nameEdit,\n setNameEdit,\n numberEdit,\n setNumberEdit,\n dateEdit,\n setDateEdit,\n cvcEdit,\n setCvcEdit,\n messageEdit,\n isEditing,\n setIsEditing,\n } = usePayment();\n\n useEffect(() => {\n (async () => {\n const cards = await getCards(currentUser.uid);\n setCards(cards);\n if (cards.length === 0) setIsDropdownOpen(true);\n })();\n }, []);\n\n useEffect(() => {\n const unsubscribe = cardListener(currentUser.uid, async () => {\n const cards = await getCards(currentUser.uid);\n setCards(cards);\n });\n return unsubscribe;\n }, []);\n\n return (\n <div>\n <Heading>Payment</Heading>\n <div>\n <Subheading>Current Cards</Subheading>\n {cards.length === 0 ? (\n <Instructions>\n <div>You do not currently have any saved cards.</div>\n <div>Add one by completing the form below.</div>\n </Instructions>\n ) : (\n <CardsList>\n {cards.map((card) => {\n return (\n <React.Fragment key={card.id}>\n <Card>\n <strong>{card.name}</strong>\n <div>{card.number.slice(-4)}\n{' '}\n(Last 4 digits)\n</div>\n\n <Buttons>\n <ButtonEmpty onClick={() => handleStartEditing(card)}>\n Edit\n </ButtonEmpty>\n <Button\n onClick={() => deleteCard(currentUser.uid, card.id)}\n >\n Delete\n </Button>\n </Buttons>\n </Card>\n\n <EditModal\n isOpen={isEditing}\n onRequestClose={() => setIsEditing(false)}\n style={{\n overlay: {\n backgroundColor: \"rgba(255, 255, 255, .55)\",\n },\n }}\n >\n <EditHeading>Edit your card</EditHeading>\n <Icon onClick={() => setIsEditing(false)}>\n <Close />\n </Icon>\n <Form\n onSubmit={(e) => {\n e.preventDefault();\n handleEditCard(currentUser.uid, card.id);\n }}\n >\n <Fields>\n <FieldLarge>\n <Label htmlFor=\"name_edit\">Name on card</Label>\n <Input\n type=\"text\"\n value={nameEdit}\n id=\"name_edit\"\n onChange={(e) => setNameEdit(e.target.value)}\n placeholder=\"Enter your full name\"\n />\n </FieldLarge>\n\n <FieldLarge>\n <Label htmlFor=\"card_number_edit\">Card number</Label>\n <Input\n type=\"text\"\n value={numberEdit}\n id=\"card_number_edit\"\n onChange={(e) => {\n const number = e.target.value.replace(\n /[^0-9]/g,\n \"\"\n );\n setNumberEdit(number);\n }}\n placeholder=\"Enter your card number\"\n />\n </FieldLarge>\n\n <Field>\n <Label htmlFor=\"date_edit\">Valid Through</Label>\n <Input\n type=\"text\"\n id=\"date_edit\"\n value={dateEdit}\n onChange={(e) => setDateEdit(e.target.value)}\n placeholder=\"MM / YY\"\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"cvc_edit\">CVC Code</Label>\n <Input\n type=\"text\"\n id=\"cvc_edit\"\n value={cvcEdit}\n onChange={(e) => {\n const cvc = e.target.value.replace(/[^0-9]/g, \"\");\n setCvcEdit(cvc);\n }}\n placeholder=\"Enter your CVC code\"\n />\n </Field>\n </Fields>\n <Buttons>\n <ButtonEmpty onClick={() => setIsEditing(false)}>\n Cancel\n </ButtonEmpty>\n <Button type=\"submit\">Edit your card</Button>\n </Buttons>\n <Message>{messageEdit}</Message>\n </Form>\n </EditModal>\n </React.Fragment>\n );\n })}\n </CardsList>\n )}\n </div>\n\n <FormHeading onClick={() => setIsDropdownOpen(!isDropdownOpen)}>\n Add a new card\n {isDropdownOpen ? <Minus /> : <Plus />}\n </FormHeading>\n\n {isDropdownOpen && (\n <Form\n onSubmit={(e) => {\n e.preventDefault();\n handleAddCard(currentUser.uid);\n }}\n >\n <Fields>\n <FieldLarge>\n <Label htmlFor=\"name\">Name on card</Label>\n <Input\n type=\"text\"\n value={name}\n id=\"name\"\n onChange={(e) => setName(e.target.value)}\n placeholder=\"Enter your full name\"\n />\n </FieldLarge>\n\n <FieldLarge>\n <Label htmlFor=\"card_number\">Card number</Label>\n <Input\n type=\"text\"\n value={number}\n id=\"card_number\"\n onChange={(e) => {\n const number = e.target.value.replace(/[^0-9]/g, \"\");\n setNumber(number);\n }}\n placeholder=\"Enter your card number\"\n />\n </FieldLarge>\n\n <Field>\n <Label htmlFor=\"date\">Valid Through</Label>\n <Input\n type=\"text\"\n id=\"date\"\n value={date}\n onChange={(e) => setDate(e.target.value)}\n placeholder=\"MM / YY\"\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"cvc\">CVC Code</Label>\n <Input\n type=\"text\"\n id=\"cvc\"\n value={cvc}\n onChange={(e) => {\n // Makes sure the user can only write 3 numbers.\n let cvc = e.target.value.replace(/[^0-9]/g, \"\");\n if (cvc.length > 3) cvc = cvc.slice(0, 3);\n setCvc(cvc);\n }}\n placeholder=\"Enter your CVC code\"\n />\n </Field>\n </Fields>\n\n <Button type=\"submit\">Add a new card</Button>\n <Message>{message}</Message>\n </Form>\n )}\n </div>\n );\n}\n\nexport default Payment;\n\n// Styled Components\nconst colors = {\n primary: \"hsl(0, 0%, 45%)\", // Grey\n secondary: \"hsl(0, 0%, 27%)\", // Dark Grey\n tertiary: \"hsl(0, 0%, 70%)\", // Bright Grey\n text: \"hsl(0, 0%, 85%)\",\n label: \"hsl(0, 0%, 100%)\",\n quaternary: \"hsl(0, 0%, 0%)\",\n};\n\nconst Heading = styled.h1`\n margin-bottom: 2rem;\n font-size: 2rem;\n line-height: 2.75rem;\n font-family: \"Playfair Display\", sans-serif;\n`;\n\nconst Subheading = styled.div`\n border-bottom: 1px solid ${colors.black};\n text-transform: uppercase;\n color: ${colors.black};\n padding-bottom: 0.25rem;\n margin-bottom: 1.5rem;\n`;\n\nconst FormHeading = styled(Subheading)`\n cursor: pointer;\n display: flex;\n justify-content: space-between;\n`;\n\nconst Instructions = styled.div`\n text-align: center;\n margin: 1rem 0;\n color: ${colors.secondary};\n`;\n\nconst CardsList = styled.div`\n display: grid;\n margin: 2rem;\n grid-gap: 2rem;\n\n @media all and (min-width: 576px) {\n grid-template-columns: repeat(2, 1fr);\n }\n\n @media all and (min-width: 992px) {\n grid-template-columns: repeat(3, 1fr);\n }\n`;\n\nconst Card = styled.div`\n padding: 1rem;\n border: 1px solid ${colors.tertiary};\n border-radius: 5px;\n`;\n\nconst Form = styled.form`\n display: flex;\n flex-direction: column;\n`;\n\nconst Fields = styled.div`\n display: grid;\n grid-gap: 3rem 5rem;\n margin-bottom: 2.5rem;\n\n @media all and (min-width: 576px) {\n grid-template-columns: repeat(2, 1fr);\n }\n`;\n\nconst Field = styled.div`\n display: flex;\n flex-direction: column;\n`;\n\nconst FieldLarge = styled(Field)`\n grid-column: 1 / -1;\n`;\n\nconst Label = styled.label`\n text-transform: uppercase;\n font-size: 0.825rem;\n letter-spacing: 1px;\n`;\n\nconst Input = styled.input`\n border: none;\n border-bottom: 1px solid ${colors.input};\n padding: 0.5rem 0 0.25rem 0;\n font-family: \"Source Sans Pro\", sans-serif;\n\n &::placeholder {\n color: ${colors.input};\n }\n\n &:focus {\n border-bottom: 1px solid ${colors.black};\n }\n`;\n\nconst Buttons = styled.div`\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n grid-gap: 1rem;\n`;\n\nconst Button = styled.button`\n margin-top: 1.5rem;\n text-transform: uppercase;\n font-size: 0.9rem;\n color: ${colors.text};\n background: ${colors.secondary};\n align-self: center;\n padding: 0.5rem 1rem;\n cursor: pointer;\n\n &:hover {\n color: ${colors.label};\n }\n`;\n\nconst ButtonEmpty = styled(Button)`\n background: transparent;\n color: ${colors.secondary};\n border: 1px solid ${colors.secondary};\n\n &:hover {\n color: ${colors.quaternary};\n }\n`;\n\nconst EditModal = styled(Modal)`\n position: absolute;\n max-width: 600px;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n background: ${colors.label};\n padding: 4rem;\n border: 1px solid ${colors.secondary};\n\n &:focus {\n outline: none;\n }\n`;\n\nconst EditHeading = styled.h2`\n text-align: center;\n font-family: \"Playfair Display\", sans-serif;\n font-size: 1.25rem;\n margin-bottom: 1rem;\n`;\n\nconst Message = styled.div`\n text-align: center;\n font-size: 0.825rem;\n color: ${colors.primary};\n margin-top: 0.25rem;\n`;\n\nconst Icon = styled.button`\n position: absolute;\n cursor: pointer;\n top: 1rem;\n right: 1rem;\n color: ${colors.primary};\n\n &:hover {\n color: ${colors.secondary};\n }\n`;\n","/home/aureen/the_odin_project/room/src/routes/account/settings/Settings.jsx",[],"/home/aureen/the_odin_project/room/src/components/shop/nav/Nav.jsx",["1122","1123","1124","1125"],"// Nav specifics to the Shop Page.\n// Looks different from the normal nav, and displays links for shopping categories, a shopping cart, the user's saved items, a search bar...\n\nimport React, { useState, useEffect, useRef } from \"react\";\nimport styled from \"styled-components\";\nimport { Link } from \"react-router-dom\";\nimport { useAuth } from \"../../../contexts/AuthContext\";\nimport { useFavorite } from \"../../../contexts/FavoriteContext\";\nimport useCart from \"../../../hooks/useCart\";\nimport SideNav from \"./SideNav\";\nimport AccessSettings from \"../../account/AccessSettings\";\n\n// Icons\nimport { ReactComponent as Logo } from \"../../../assets/icons/logo.svg\";\nimport { ReactComponent as Cart } from \"../../../assets/icons/icon-shopping-cart.svg\";\nimport { ReactComponent as Heart } from \"../../../assets/icons/icon-heart.svg\";\nimport { ReactComponent as HeartFilled } from \"../../../assets/icons/icon-heart-filled.svg\";\nimport { ReactComponent as Home } from \"../../../assets/icons/icon-home.svg\";\nimport { ReactComponent as Search } from \"../../../assets/icons/icon-search.svg\";\nimport { ReactComponent as User } from \"../../../assets/icons/icon-user.svg\";\n\nfunction Nav() {\n const { currentUser } = useAuth();\n const { getCart, cartListener } = useCart();\n const { favorites } = useFavorite();\n const navRef = useRef();\n const [cart, setCart] = useState(0);\n\n useEffect(() => {\n (async () => {\n if (!currentUser) return;\n const cart = await getCart(currentUser.uid);\n setCart(cart.length);\n })();\n }, [currentUser]);\n\n useEffect(() => {\n if (!currentUser) return;\n const unsubscribe = cartListener(currentUser.uid, async () => {\n const cart = await getCart(currentUser.uid);\n setCart(cart.length);\n });\n return unsubscribe;\n }, [currentUser]);\n\n return (\n <Container ref={navRef}>\n <Navigation>\n <NavLeft>\n <NavIconLink>\n <SideNav nav={navRef} />\n </NavIconLink>\n <NavIconLink>\n <Link to=\"/\">\n <Home />\n </Link>\n </NavIconLink>\n </NavLeft>\n\n <Link to=\"/shop\">\n <Brand>\n <Logo />\n </Brand>\n </Link>\n\n <NavRight>\n <NavIcon title=\"Work in progress\">\n <Search />\n </NavIcon>\n\n {currentUser && !currentUser.isAnonymous ? (\n <AccessSettings />\n ) : (\n <NavIcon>\n <Link to=\"/shop/entry\">\n <User />\n </Link>\n </NavIcon>\n )}\n\n <NavIconLink>\n <Position>\n <Link to=\"/shop/favorite\">\n {favorites.length !== 0 ? (\n <>\n <HeartFilled />\n <Stamp>{favorites.length}</Stamp>\n </>\n ) : (\n <Heart />\n )}\n </Link>\n </Position>\n </NavIconLink>\n <NavIconLink>\n <Position>\n <Link to=\"/shop/cart\">\n <Cart />\n {cart !== 0 && <Stamp>{cart}</Stamp>}\n </Link>\n </Position>\n </NavIconLink>\n </NavRight>\n </Navigation>\n </Container>\n );\n}\n\nexport default Nav;\n\n\nconst colors = {\n primary: \"hsl(0, 0%, 0%)\", // Black\n secondary: \"hsl(0, 0%, 27%)\", // Grey\n stamp: \"hsl(0, 0%, 100%)\",\n};\n\n// Styled components\nconst icon = `\n color: ${colors.secondary};\n cursor: pointer;\n margin: 0 .5rem;\n\n &:hover {\n color: ${colors.primary};\n }\n`;\n\nconst Container = styled.div`\n z-index: 10;\n display: grid;\n align-items: baseline;\n font-family: \"Spartan\", sans-serif;\n width: 100vw;\n max-width: 100%;\n padding: 0.5rem;\n border-bottom: 1px solid ${colors.secondary};\n\n @media all and (min-width: 576px) {\n padding: 1rem;\n }\n`;\n\nconst Navigation = styled.nav`\n color: ${colors.primary};\n z-index: 20;\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n align-items: center;\n`;\n\nconst Brand = styled.span`\n font-size: 1.5rem;\n color: ${colors.primary};\n`;\n\nconst NavIconLink = styled.span`\n ${icon}\n`;\n\nconst NavIcon = styled.span`\n ${icon}\n`;\n\nconst Position = styled.span`\n position: relative;\n`;\n\nconst NavLeft = styled.div`\n display: flex;\n align-items: center;\n`;\n\nconst NavRight = styled.div`\n justify-self: right;\n display: grid;\n grid-template: repeat(2, auto) / repeat(2, auto);\n align-items: center;\n justify-items: center;\n\n @media all and (min-width: 440px) {\n display: block;\n }\n`;\n\nconst Stamp = styled.span`\n position: absolute;\n display: inline-block;\n top: -1rem;\n right: -0.75rem;\n width: 1.25rem;\n height: 1.25rem;\n background: ${colors.stamp};\n border-radius: 50%;\n color: ${colors.secondary};\n border: 1px solid ${colors.secondary};\n font-size: 0.75rem;\n display: flex;\n align-items: center;\n justify-content: center;\n padding-top: 3px;\n`;\n","/home/aureen/the_odin_project/room/src/components/shop/nav/ShopNav.jsx",["1126"],"import React, { useEffect, useState, useRef } from \"react\";\nimport styled from \"styled-components\";\nimport { Link } from \"react-router-dom\";\nimport useShop from \"../../../hooks/useShop\";\nimport { formatNavLink } from \"../../../utils/utils\";\n\n// Displays shopping categories (types of furnitures...)\nfunction ShopNav() {\n const { getShopCategories } = useShop();\n const [categories, setCategories] = useState([]);\n const [dropdown, setDropdown] = useState(false);\n const [hovered, setHovered] = useState(\"\");\n const navRef = useRef();\n\n useEffect(() => {\n (async () => {\n const categories = await getShopCategories();\n setCategories(categories);\n })();\n }, []);\n\n return (\n <Container\n onMouseLeave={() => {\n setDropdown(false);\n }}\n >\n <Nav ref={navRef}>\n {/* Sort the categories by order before displaying them */}\n {Object.keys(categories)\n .sort((a, b) => categories[a].order - categories[b].order)\n .map((category) => {\n return (\n <Category\n to={`/shop/${encodeURIComponent(category)}`}\n key={category}\n onMouseOver={() => {\n setDropdown(true);\n setHovered(category);\n }}\n >\n {formatNavLink(category)}\n </Category>\n );\n })}\n </Nav>\n\n {dropdown && Object.keys(categories[hovered].categories).length !== 0 && (\n <DropdownContainer margin={navRef.current.offsetHeight}>\n <Dropdown>\n {/* Sort the subcategories by order before displaying them */}\n {Object.keys(categories[hovered].categories)\n .sort(\n (a, b) =>\n categories[hovered].categories[a].order -\n categories[hovered].categories[b].order\n )\n .map((subcategory) => {\n return (\n <div key={subcategory}>\n <Subcategory\n to={`/shop/${encodeURIComponent(subcategory)}`}\n >\n {formatNavLink(subcategory)}\n </Subcategory>\n <div>\n {categories[hovered].categories[\n subcategory\n ].categories.map((item) => {\n return (\n <Item\n key={item}\n to={`/shop/${encodeURIComponent(item)}`}\n >\n {formatNavLink(item)}\n </Item>\n );\n })}\n </div>\n </div>\n );\n })}\n </Dropdown>\n </DropdownContainer>\n )}\n </Container>\n );\n}\n\nexport default ShopNav;\n\n// Styled components\nconst colors = {\n primary: \"hsl(0, 0%, 0%)\", // Black\n secondary: \"hsl(0, 0%, 27%)\", // Grey\n tertiary: \"hsl(0, 0%, 100%)\", // White\n};\n\nconst Container = styled.nav`\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n background: ${colors.secondary};\n`;\n\nconst Nav = styled.ul`\n display: flex;\n justify-content: space-between;\n width: 100%;\n max-width: 900px;\n`;\n\nconst DropdownContainer = styled.div`\n position: absolute;\n z-index: 3;\n background: ${colors.tertiary};\n top: ${(props) => props.margin}px;\n width: 100%;\n box-shadow: 0 0px 4px -3px ${colors.secondary};\n`;\n\nconst Dropdown = styled.div`\n display: grid;\n grid-auto-flow: column;\n grid-template-rows: repeat(2, auto);\n grid-gap: 2rem;\n justify-content: center;\n padding: 1.5rem;\n background: ${colors.tertiary};\n font-size: 0.825rem;\n\n @media all and (min-width: 576px) {\n grid-template-rows: auto;\n }\n`;\n\nconst Category = styled(Link)`\n cursor: pointer;\n flex: 1;\n text-align: center;\n text-transform: uppercase;\n font-weight: 600;\n color: ${colors.tertiary};\n padding: 0.75rem 0 calc(0.75rem - 2px) 0;\n border-bottom: 2px solid transparent;\n\n &:hover {\n border-bottom: 2px solid ${colors.tertiary};\n }\n`;\n\nconst Subcategory = styled(Link)`\n position: relative;\n display: inline-block;\n width: 100%;\n color: ${colors.primary};\n text-transform: uppercase;\n cursor: pointer;\n margin-bottom: 0.5rem;\n font-weight: 600;\n\n &:hover {\n text-decoration: underline;\n }\n`;\n\nconst Item = styled(Link)`\n padding: 0.25rem 0;\n cursor: pointer;\n display: block;\n color: ${colors.secondary};\n width: 100%;\n border-bottom: 1px solid transparent;\n\n &:hover {\n color: ${colors.primary};\n text-decoration: underline;\n }\n`;\n","/home/aureen/the_odin_project/room/src/components/shop/nav/Footer.jsx",["1127","1128"],"import React from \"react\";\nimport styled from \"styled-components\";\nimport { Link } from \"react-router-dom\";\n\n// Icons\nimport { ReactComponent as Logo } from \"../../../assets/icons/logo.svg\";\nimport { ReactComponent as Facebook } from \"../../../assets/icons/icon-facebook.svg\";\nimport { ReactComponent as Pinterest } from \"../../../assets/icons/icon-pinterest.svg\";\nimport { ReactComponent as Twitter } from \"../../../assets/icons/icon-twitter.svg\";\nimport { ReactComponent as Instagram } from \"../../../assets/icons/icon-instagram.svg\";\n\nfunction Footer() {\n return (\n <Container>\n <Content>\n <Room />\n <div>\n <Category>Discover Room</Category>\n <ul>\n <Li>About us</Li>\n <Li>Contact</Li>\n <Li>Terms & Conditions</Li>\n </ul>\n </div>\n\n <div>\n <Category>Room's Shop</Category>\n <ul>\n <Li>\n <Link to=\"/account/user\">My account</Link>\n </Li>\n <Li>\n <Link to=\"/shop/tracking\">Track an order</Link>\n </Li>\n <Li>Delivery</Li>\n <Li>Returns</Li>\n <Li>Payment</Li>\n </ul>\n </div>\n\n <Contact>\n <strong>+1 23 456 789</strong>\n <div>enquiries@room.com</div>\n <div>\n <Icon>\n <Facebook />\n </Icon>\n <Icon>\n <Instagram />\n </Icon>\n <Icon>\n <Pinterest />\n </Icon>\n <Icon>\n <Twitter />\n </Icon>\n </div>\n </Contact>\n </Content>\n </Container>\n );\n}\n\nexport default Footer;\n\n\n// Styled components\nconst colors = {\n heading: \"hsl(0, 0%, 95%)\",\n primary: \"hsl(0, 0%, 90%)\",\n social: \"hsl(0, 0%, 80%)\",\n secondary: \"hsl(0, 0%, 20%)\", // Grey\n};\n\nconst Container = styled.footer`\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n padding: 3rem;\n background: ${colors.secondary};\n color: ${colors.primary};\n line-height: 1.5rem;\n`;\n\nconst Content = styled.div`\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n flex: 1;\n width: 100%;\n max-width: 1200px;\n\n & > * {\n margin-bottom: 2rem;\n }\n\n @media all and (min-width: 576px) {\n flex-direction: row;\n\n & > * {\n margin-bottom: 0;\n }\n }\n`;\n\nconst Category = styled.div`\n font-weight: 600;\n margin-bottom: 0.5rem;\n color: ${colors.heading};\n`;\n\nconst Room = styled(Logo)`\n align-self: center;\n`;\n\nconst Li = styled.li`\n cursor: pointer;\n\n &:hover {\n text-decoration: underline;\n }\n`;\n\nconst Contact = styled.div`\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n\n & > *:last-child {\n margin-top: 0.5rem;\n }\n`;\n\nconst Icon = styled.span`\n display: inline-block;\n margin-left: 0.75rem;\n color: ${colors.social};\n cursor: pointer;\n\n &:hover {\n color: ${colors.primary};\n }\n`;\n","/home/aureen/the_odin_project/room/src/hooks/useShop.js",["1129","1130"],"/home/aureen/the_odin_project/room/src/hooks/useOrder.js",[],"/home/aureen/the_odin_project/room/src/hooks/useUser.js",[],"/home/aureen/the_odin_project/room/src/hooks/useUserSettings.js",[],"/home/aureen/the_odin_project/room/src/hooks/usePayment.js",["1131","1132","1133","1134","1135","1136","1137","1138","1139"],"/home/aureen/the_odin_project/room/src/hooks/useCart.js",["1140","1141"],"/home/aureen/the_odin_project/room/src/hooks/useAddress.js",["1142","1143","1144","1145","1146","1147","1148","1149","1150","1151","1152","1153","1154","1155","1156","1157","1158","1159","1160"],"/home/aureen/the_odin_project/room/src/utils/utils.js",["1161","1162","1163","1164","1165","1166"],"/home/aureen/the_odin_project/room/src/hooks/useSignIn.js",["1167"],"/home/aureen/the_odin_project/room/src/hooks/useDesign.js",[],"/home/aureen/the_odin_project/room/src/components/account/SignIn.jsx",["1168","1169","1170"],"import React, { useState } from \"react\";\nimport styled from \"styled-components\";\nimport PropTypes from \"prop-types\";\nimport { Link } from \"react-router-dom\";\nimport useSignIn from \"../../hooks/useSignIn\";\n\n// Icons\nimport check from \"../../assets/icons/icon-check.svg\";\n\nfunction SignIn({ flip }) {\n const [remember, setRemember] = useState(false);\n\n const {\n email,\n setEmail,\n password,\n setPassword,\n emailError,\n passwordError,\n handleSignIn,\n handleForgotPassword,\n loading,\n } = useSignIn();\n\n return (\n <>\n <Welcome>\n <Heading>Welcome back!</Heading>\n <p>We are happy to see you again.</p>\n </Welcome>\n\n <form\n onSubmit={(e) => {\n e.preventDefault();\n handleSignIn(false);\n }}\n >\n <Field>\n <Label htmlFor=\"email\">Email</Label>\n <Input\n id=\"email\"\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n />\n {emailError && <Message>{emailError}</Message>}\n </Field>\n\n <Field>\n <Label htmlFor=\"password\">Password</Label>\n <Input\n id=\"password\"\n type=\"password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n />\n {passwordError && <Message>{passwordError}</Message>}\n <MessageLink onClick={handleForgotPassword}>\n Forgot your password?\n </MessageLink>\n </Field>\n\n <div>\n <CheckboxLabel htmlFor=\"remember\" isChecked={remember}>\n Remember me\n </CheckboxLabel>\n <Checkbox\n type=\"checkbox\"\n id=\"remember\"\n name=\"remember\"\n checked={remember}\n onChange={() => setRemember(!remember)}\n />\n </div>\n\n <Button type=\"submit\" disabled={loading}>\n Sign In\n </Button>\n </form>\n <Message>\n Not a member yet?{\" \"}\n {flip ? (\n <>\n <MessageLink onClick={flip}>Sign up now</MessageLink>.\n </>\n ) : (\n <Link to=\"/signup\">\n <MessageLink>Sign up now</MessageLink>.\n </Link>\n )}\n </Message>\n </>\n );\n}\n\nSignIn.propTypes = {\n flip: PropTypes.func,\n};\n\nSignIn.defaultProps = {\n flip: () => {},\n};\n\nexport default SignIn;\n\n// Styled Components\nconst colors = {\n primary: \"hsl(0, 0%, 45%)\", // Grey\n secondary: \"hsl(0, 0%, 27%)\", // Button and checkbox\n tertiary: \"hsl(0, 0%, 90%)\",\n input: \"hsl(0, 0%, 70%)\", // Input lines\n black: \"hsl(0, 0%, 0%)\",\n background: \"hsl(0, 0%, 100%)\",\n};\n\nconst Welcome = styled.div`\n text-align: center;\n`;\n\nconst Heading = styled.h1`\n font-size: 2rem;\n line-height: 2.5rem;\n font-family: \"Playfair Display\", sans-serif;\n`;\n\nconst Field = styled.div`\n display: flex;\n flex-direction: column;\n margin: 2.5rem 0;\n`;\n\nconst Label = styled.label`\n text-transform: uppercase;\n font-size: 0.825rem;\n letter-spacing: 1px;\n`;\n\nconst Input = styled.input`\n border: none;\n border-bottom: 1px solid ${colors.input};\n padding: 0.5rem 0 0.25rem 0;\n font-family: \"Source Sans Pro\", sans-serif;\n\n &::placeholder {\n color: ${colors.input};\n }\n\n &:focus {\n border-bottom: 1px solid ${colors.black};\n }\n`;\n\nconst Button = styled.button`\n margin-top: 1.5rem;\n font-family: \"Source Sans Pro\", sans-serif;\n text-transform: uppercase;\n font-size: 0.9rem;\n color: ${colors.tertiary};\n background: ${colors.secondary};\n padding: 0.5rem 1rem;\n width: 100%;\n cursor: pointer;\n`;\n\nconst Message = styled.span`\n font-size: 0.825rem;\n color: ${colors.primary};\n line-height: 1rem;\n`;\n\nconst MessageLink = styled(Message)`\n cursor: pointer;\n color: ${colors.secondary};\n\n &:hover {\n color: ${colors.black};\n }\n`;\n\nconst Checkbox = styled.input`\n visibility: hidden;\n`;\n\nconst CheckboxLabel = styled.label`\n display: flex;\n align-items: center;\n\n &:before {\n display: inline-block;\n content: \"\";\n width: 1rem;\n height: 1rem;\n margin-right: 0.5rem;\n border-radius: 2px;\n border: 1px solid ${colors.secondary};\n background-color: ${(props) => (props.isChecked ? colors.secondary : \"\")};\n background-image: ${(props) => (props.isChecked ? `url(${check})` : \"\")};\n background-position: ${(props) => (props.isChecked ? \"center\" : \"\")};\n }\n`;\n","/home/aureen/the_odin_project/room/src/components/account/SignUp.jsx",["1171","1172","1173","1174","1175"],"import React from \"react\";\nimport styled from \"styled-components\";\nimport { Link, useHistory } from \"react-router-dom\";\nimport useSignUp from \"../../hooks/useSignUp\";\n\n// Icons\nimport check from \"../../assets/icons/icon-check.svg\";\n\nfunction SignUp({ flip, isPaying }) {\n const {\n email,\n setEmail,\n firstName,\n setFirstName,\n lastName,\n setLastName,\n password,\n setPassword,\n terms,\n setTerms,\n emailError,\n passwordError,\n loading,\n isFormCompleted,\n handleSignUp,\n } = useSignUp();\n\n const history = useHistory();\n\n return (\n <>\n <Welcome>\n <Heading>Create an account</Heading>\n <p>Join us for a smoother shopping experience.</p>\n </Welcome>\n\n <form\n onSubmit={async (e) => {\n e.preventDefault();\n await handleSignUp();\n isPaying ? history.push(\"/shop/personal\") : history.push(\"/shop\");\n }}\n >\n <Field>\n <Label htmlFor=\"first_name\">First Name</Label>\n <Input\n id=\"first_name\"\n type=\"text\"\n value={firstName}\n onChange={(e) => setFirstName(e.target.value)}\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"last_name\">Last Name</Label>\n <Input\n id=\"last_name\"\n type=\"text\"\n value={lastName}\n onChange={(e) => setLastName(e.target.value)}\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"email\">Email</Label>\n <Input\n id=\"email\"\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n />\n {emailError && <Message>{emailError}</Message>}\n </Field>\n\n <Field>\n <Label htmlFor=\"password\">Password</Label>\n <Input\n id=\"password\"\n type=\"password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n />\n {passwordError && <Message>{passwordError}</Message>}\n </Field>\n\n <div>\n <CheckboxLabel htmlFor=\"terms\" isChecked={terms}>\n I have read and agree to Room's Terms of Service and Privacy Policy.\n </CheckboxLabel>\n <Checkbox\n type=\"checkbox\"\n id=\"terms\"\n name=\"terms\"\n checked={terms}\n onChange={(e) => setTerms(e.target.checked)}\n />\n </div>\n\n <Button type=\"submit\" disabled={loading || isFormCompleted}>\n Sign Up\n </Button>\n </form>\n <Message>\n Already have an account?{\" \"}\n {flip ? (\n <>\n <MessageLink onClick={flip}>Sign in now.</MessageLink>\n </>\n ) : (\n <Link to=\"/signup\">\n <MessageLink>Sign in now.</MessageLink>\n </Link>\n )}\n </Message>\n </>\n );\n}\n\nexport default SignUp;\n\n// Styled Components\nconst colors = {\n primary: \"hsl(0, 0%, 45%)\", // Grey\n secondary: \"hsl(0, 0%, 27%)\", // Button and checkbox\n tertiary: \"hsl(0, 0%, 90%)\",\n input: \"hsl(0, 0%, 70%)\", // Input lines\n black: \"hsl(0, 0%, 0%)\",\n background: \"hsl(0, 0%, 100%)\",\n};\n\nconst Welcome = styled.div`\n text-align: center;\n`;\n\nconst Heading = styled.h1`\n font-size: 2rem;\n line-height: 2.5rem;\n font-family: \"Playfair Display\", sans-serif;\n`;\n\nconst Field = styled.div`\n display: flex;\n flex-direction: column;\n margin: 2.5rem 0;\n`;\n\nconst Label = styled.label`\n text-transform: uppercase;\n font-size: 0.825rem;\n letter-spacing: 1px;\n`;\n\nconst Input = styled.input`\n border: none;\n border-bottom: 1px solid ${colors.input};\n padding: 0.5rem 0 0.25rem 0;\n font-family: \"Source Sans Pro\", sans-serif;\n\n &::placeholder {\n color: ${colors.input};\n }\n\n &:focus {\n border-bottom: 1px solid ${colors.black};\n }\n`;\n\nconst Button = styled.button`\n margin-top: 1.5rem;\n font-family: \"Source Sans Pro\", sans-serif;\n text-transform: uppercase;\n font-size: 0.9rem;\n color: ${colors.tertiary};\n background: ${colors.secondary};\n padding: 0.5rem 1rem;\n width: 100%;\n cursor: pointer;\n\n &:disabled {\n background: ${colors.primary};\n cursor: not-allowed;\n }\n`;\n\nconst Message = styled.span`\n font-size: 0.825rem;\n color: ${colors.primary};\n line-height: 1rem;\n`;\n\nconst MessageLink = styled(Message)`\n cursor: pointer;\n color: ${colors.secondary};\n\n &:hover {\n color: ${colors.black};\n }\n`;\n\nconst Checkbox = styled.input`\n visibility: hidden;\n`;\n\nconst CheckboxLabel = styled.label`\n display: flex;\n align-items: center;\n\n &:before {\n display: inline-block;\n content: \"\";\n width: 1rem;\n height: 1rem;\n margin-right: 0.5rem;\n border-radius: 2px;\n border: 1px solid ${colors.secondary};\n background-color: ${(props) => (props.isChecked ? colors.secondary : \"\")};\n background-image: ${(props) => (props.isChecked ? `url(${check})` : \"\")};\n background-position: ${(props) => (props.isChecked ? \"center\" : \"\")};\n }\n`;\n","/home/aureen/the_odin_project/room/src/components/shop/display/ShopItemPreview.jsx",["1176","1177","1178","1179","1180"],"import React, { useState } from \"react\";\nimport PropTypes from \"prop-types\";\nimport styled from \"styled-components\";\nimport { Link } from \"react-router-dom\";\nimport { useFavorite } from \"../../../contexts/FavoriteContext\";\nimport { useAuth } from \"../../../contexts/AuthContext\";\n\n// Icons\nimport { ReactComponent as Heart } from \"../../../assets/icons/icon-heart.svg\";\nimport { ReactComponent as HeartFilled } from \"../../../assets/icons/icon-heart-filled.svg\";\n\nfunction ShopItemPreview({ name, images, price, id, isFavorite, isNew }) {\n const [image, setImage] = useState(images[0]);\n const { addFavorite, deleteFavorite } = useFavorite();\n const { currentUser, signInAnonymously } = useAuth();\n\n const changeImage = () => {\n if (images.length === 1) return;\n image === images[0] ? setImage(images[1]) : setImage(images[0]);\n };\n\n const handleFavorite = async () => {\n let userId = currentUser && currentUser.uid;\n\n if (!currentUser) {\n const user = await signInAnonymously();\n userId = user.user.uid;\n }\n isFavorite ? deleteFavorite(userId, id) : addFavorite(userId, id);\n };\n\n return (\n <Container>\n <Link to={`/shop/item/${id}`}>\n {isNew && <New>New</New>}\n <ImageContainer>\n <Image\n src={image}\n onMouseOver={changeImage}\n onMouseLeave={changeImage}\n />\n </ImageContainer>\n </Link>\n <Description>\n <div>\n <Link to={`/shop/item/${id}`}>\n <Name>{name}</Name>\n </Link>\n <Price>£{price}</Price>\n </div>\n <Icon onClick={handleFavorite}>\n {isFavorite ? <HeartFilled /> : <Heart />}\n </Icon>\n </Description>\n </Container>\n );\n}\n\nShopItemPreview.propTypes = {\n name: PropTypes.string.isRequired,\n images: PropTypes.arrayOf(PropTypes.string).isRequired,\n price: PropTypes.number.isRequired,\n id: PropTypes.string.isRequired,\n isFavorite: PropTypes.bool,\n isNew: PropTypes.bool,\n};\n\nShopItemPreview.defaultProps = {\n isFavorite: false,\n isNew: false,\n};\n\nexport default ShopItemPreview;\n\n\n// Styled Components\nconst colors = {\n primary: \"hsl(0, 0%, 0%)\", // Black\n secondary: \"hsl(0, 0%, 45%)\", // Grey\n tertiary: \"hsl(0, 0%, 70%)\", // Bright grey\n quaternary: \"hsl(0, 0%, 27%)\",\n new: \"hsl(0, 0%, 85%)\",\n};\n\nconst Container = styled.div`\n position: relative;\n padding: 2.5rem;\n border: 1px solid transparent;\n max-width: 17.5rem;\n\n &:hover {\n border: 1px solid ${colors.tertiary};\n }\n`;\n\nconst New = styled.span`\n position: absolute;\n font-size: 0.825rem;\n text-transform: uppercase;\n color: ${colors.new};\n background: ${colors.quaternary};\n padding: 0.2rem 0.35rem;\n border-radius: 2px;\n top: 0.5rem;\n left: 0.5rem;\n`;\n\nconst ImageContainer = styled.div`\n margin-bottom: 0.5rem;\n width: 8.5rem;\n height: 8.5rem;\n\n @media all and (min-width: 600px) {\n width: 10rem;\n height: 10rem;\n }\n\n @media all and (min-width: 730px) {\n width: 12.5rem;\n height: 12.5rem;\n }\n`;\n\nconst Image = styled.img`\n max-width: 100%;\n max-height: 100%;\n object-fit: cover;\n`;\n\nconst Name = styled.div`\n text-transform: uppercase;\n font-size: 0.825rem;\n`;\n\nconst Price = styled.div`\n color: ${colors.secondary};\n font-size: 0.825rem;\n`;\n\nconst Description = styled.div`\n display: flex;\n justify-content: space-between;\n`;\n\nconst Icon = styled.span`\n color: ${colors.secondary};\n cursor: pointer;\n`;\n","/home/aureen/the_odin_project/room/src/components/shop_handling/AddShopItem.jsx",["1181","1182","1183","1184","1185","1186","1187","1188","1189","1190","1191","1192","1193","1194","1195","1196","1197","1198","1199","1200","1201","1202","1203","1204","1205","1206","1207","1208","1209","1210","1211","1212","1213","1214","1215","1216","1217","1218","1219","1220","1221","1222","1223","1224","1225","1226","1227","1228","1229","1230","1231","1232","1233","1234","1235","1236","1237","1238","1239","1240","1241","1242","1243","1244","1245","1246","1247","1248","1249","1250","1251","1252","1253","1254"],"import React, { useState } from \"react\";\nimport styled from \"styled-components\";\nimport useShop from \"../../hooks/useShop\";\nimport useStorage from \"../../hooks/useStorage\";\n\n// Icons\nimport { ReactComponent as Plus } from \"../../assets/icons/icon-plus.svg\";\nimport { ReactComponent as Close } from \"../../assets/icons/icon-x-med.svg\";\n\nfunction AddShopItem() {\n const [name, setName] = useState(\"\");\n const [price, setPrice] = useState(0);\n const [dimensions, setDimensions] = useState({\n depth: 0,\n height: 0,\n width: 0,\n });\n const [materials, setMaterials] = useState([\"\", \"\", \"\"]);\n const [images, setImages] = useState([]);\n const [description, setDescription] = useState([\"\"]);\n const [categories, setCategories] = useState([\"\", \"\", \"\"]);\n const [colors, setColors] = useState([\n {\n description: \"\",\n type: \"\",\n value: \"#000000\",\n image: \"\",\n },\n ]);\n const [additional, setAdditional] = useState([\n {\n type: \"\",\n information: \"\",\n },\n ]);\n const [options, setOptions] = useState([\n {\n type: \"\",\n options: [\n {\n option: \"\",\n price: 0,\n dimensions: {\n width: 0,\n height: 0,\n depth: 0,\n },\n },\n ],\n },\n ]);\n const [imagesPreview, setImagesPreview] = useState([]);\n const [seats, setSeats] = useState([]);\n const [type, setType] = useState(\"\");\n const [message, setMessage] = useState(\"\");\n const [loading, setLoading] = useState(false);\n\n const { createItem, addItem } = useShop();\n const { uploadItemImage } = useStorage();\n\n const handleSubmit = async (e) => {\n e.preventDefault();\n setMessage(\"\");\n setLoading(true);\n\n const item = await createItem();\n const itemId = item.id;\n\n // Upload images in the storage and get their urls.\n const imagesUrls = [];\n for (const image of images) {\n const imageUrl = await uploadItemImage(itemId, image);\n imagesUrls.push(imageUrl);\n }\n\n const formattedColors = [...colors];\n for (const color of formattedColors) {\n const colorImageUrl = await uploadItemImage(itemId, color.image);\n color.image = colorImageUrl;\n }\n\n // Format additional informations and options\n // If the fields are empty, they are ignored.\n const formattedAdditional = {};\n for (const information of additional) {\n if (information.type !== \"\" && information.information !== \"\") {\n formattedAdditional[information.type] = information.information;\n }\n }\n\n // Remove empty fields\n const formattedMaterials = [...materials]\n .filter((material) => material !== \"\")\n .map((material) => material.toLowerCase());\n const formattedCategories = [...categories]\n .filter((category) => category !== \"\")\n .map((category) => category.toLowerCase());\n\n const formattedOptions = {};\n for (const option of options) {\n if (\n option.type !== \"\" &&\n option.options.option !== \"\" &&\n option.options.price !== \"\"\n ) {\n formattedOptions[option.type] = [...option.options];\n }\n }\n\n // Create queries (used to search / filter the item)\n const queries = {};\n\n // Colors filters\n queries.colors = [];\n for (const color of colors) {\n queries.colors.push(color.type);\n }\n\n // Search terms\n queries.search = [];\n for (const color of colors) {\n queries.search.push(color.type);\n }\n for (const category of formattedCategories) {\n queries.search.push(category);\n }\n for (const material of formattedMaterials) {\n queries.search.concat(...material.split(\"_\"));\n }\n queries.search = queries.search.concat(...name.toLowerCase().split(\" \"));\n\n // Material filters\n queries.materials = formattedMaterials;\n\n // Price filters\n queries.price = {\n min: price,\n max: price,\n };\n\n for (const option of options) {\n for (const choice of Object.keys(option)) {\n if (choice.price > queries.price.max) {\n queries.price.max = choice.price;\n }\n if (choice.price < queries.price.min) {\n queries.price.min = choice.price;\n }\n }\n }\n\n // Dimensions filters\n queries.dimensions = {\n width: {\n min: dimensions.width,\n max: dimensions.width,\n },\n height: {\n min: dimensions.height,\n max: dimensions.height,\n },\n depth: {\n min: dimensions.depth,\n max: dimensions.depth,\n },\n };\n\n for (const option of options) {\n for (const choice of option.options) {\n if (choice.dimensions.width > queries.dimensions.width.max) {\n queries.dimensions.width.max = choice.dimensions.width;\n }\n if (choice.dimensions.width < queries.dimensions.width.min) {\n queries.dimensions.width.min = choice.dimensions.width;\n }\n if (choice.dimensions.height > queries.dimensions.height.max) {\n queries.dimensions.height.max = choice.dimensions.height;\n }\n if (choice.dimensions.height < queries.dimensions.height.min) {\n queries.dimensions.height.min = choice.dimensions.height;\n }\n if (choice.dimensions.depth > queries.dimensions.depth.max) {\n queries.dimensions.depth.max = choice.dimensions.depth;\n }\n if (choice.dimensions.depth < queries.dimensions.depth.min) {\n queries.dimensions.depth.min = choice.dimensions.depth;\n }\n }\n }\n\n if (seats.length !== 0) {\n queries.seats = seats;\n }\n\n // Adds the shop item information in the firestore.\n try {\n const id = await addItem(\n itemId,\n name,\n price,\n type,\n dimensions,\n imagesUrls,\n description,\n formattedColors,\n formattedAdditional,\n formattedOptions,\n formattedCategories,\n queries\n );\n setMessage(`The item has been successfully added. Item Id: ${id}.`);\n } catch (e) {\n setMessage(\"Sorry, we could not add the item.\");\n }\n setLoading(false);\n };\n\n const addImages = (e) => {\n e.preventDefault();\n if (e.target.files.length === 0) return;\n setImages(e.target.files);\n\n const preview = [];\n for (const file of e.target.files) {\n preview.push(URL.createObjectURL(file));\n }\n setImagesPreview(preview);\n };\n\n return (\n <Container>\n <Heading>Add an item to the shop</Heading>\n <Form onSubmit={handleSubmit}>\n <Category>General</Category>\n <Fields fields={3}>\n <Field>\n <Label htmlFor=\"name\">Name</Label>\n <Input\n id=\"name\"\n name=\"name\"\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"Enter the item's name\"\n required\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"price\">Price</Label>\n <Input\n id=\"price\"\n name=\"price\"\n type=\"number\"\n value={price}\n onChange={(e) => setPrice(+e.target.value)}\n required\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"type\">Type</Label>\n <Input\n id=\"type\"\n name=\"type\"\n type=\"text\"\n value={type}\n onChange={(e) => setType(e.target.value)}\n required\n />\n </Field>\n </Fields>\n\n <Category>Dimensions</Category>\n <Fields fields={3}>\n <Field>\n <Label htmlFor=\"depth\">Depth</Label>\n <Input\n id=\"depth\"\n name=\"depth\"\n type=\"number\"\n value={dimensions.depth}\n onChange={(e) =>\n setDimensions({ ...dimensions, depth: +e.target.value })\n }\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"height\">Height</Label>\n <Input\n id=\"height\"\n name=\"height\"\n type=\"number\"\n value={dimensions.height}\n onChange={(e) =>\n setDimensions({ ...dimensions, height: +e.target.value })\n }\n />\n </Field>\n\n <Field>\n <Label htmlFor=\"width\">Width</Label>\n <Input\n id=\"width\"\n name=\"width\"\n type=\"text\"\n value={dimensions.width}\n onChange={(e) =>\n setDimensions({ ...dimensions, width: +e.target.value })\n }\n />\n </Field>\n </Fields>\n\n <Field>\n <Category>\n Materials\n <IconButton\n type=\"button\"\n title=\"Add Material\"\n onClick={() => setMaterials([...materials, \"\"])}\n >\n <Plus />\n </IconButton>\n </Category>\n <Fields fields={3}>\n {materials.map((material, index) => {\n return (\n <Box key={`material_${index + 1}`}>\n <Field>\n <Label htmlFor={`material_${index + 1}`}>\n Material {index + 1}\n </Label>\n <Input\n id={`material_${index + 1}`}\n name={`material_${index + 1}`}\n type=\"text\"\n value={material}\n placeholder={`Enter Material ${index + 1}`}\n onChange={(e) =>\n setMaterials((prev) => {\n const materials = [...prev];\n materials[index] = e.target.value;\n return materials;\n })\n }\n />\n </Field>\n <BoxButton\n type=\"button\"\n title=\"Remove Material\"\n onClick={() =>\n setMaterials((prev) => {\n const materials = [...prev];\n materials.splice(index, 1);\n return materials;\n })\n }\n >\n <Close />\n </BoxButton>\n </Box>\n );\n })}\n </Fields>\n </Field>\n\n <Category>\n Description\n <IconButton\n type=\"button\"\n title=\"Add Description\"\n onClick={() => setDescription([...description, \"\"])}\n >\n <Plus />\n </IconButton>\n </Category>\n\n <Fields fields={1}>\n {description.map((description, index) => {\n return (\n <Field key={`description-${index + 1}`}>\n <Label htmlFor={`paragraph_${index + 1}`}>\n Paragraph {index + 1}\n </Label>\n <Row>\n <Input\n id={`paragraph_${index + 1}`}\n name={`paragraph_${index + 1}`}\n type=\"text\"\n value={description}\n placeholder={`Enter Paragraph ${\n index + 1\n } of your description`}\n onChange={(e) =>\n setDescription((prev) => {\n const description = [...prev];\n description[index] = e.target.value;\n return description;\n })\n }\n />\n <IconButton\n type=\"button\"\n title=\"Remove Paragraph\"\n onClick={() =>\n setDescription((prev) => {\n const description = [...prev];\n description.splice(index, 1);\n return description;\n })\n }\n >\n <Close />\n </IconButton>\n </Row>\n </Field>\n );\n })}\n </Fields>\n\n <Field>\n <Category>\n Colors\n <IconButton\n title=\"Add a color\"\n type=\"button\"\n onClick={() =>\n setColors([\n ...colors,\n { description: \"\", type: \"\", value: \"#000000\" },\n ])\n }\n >\n <Plus />\n </IconButton>\n </Category>\n\n <Fields fields={3}>\n {colors.map((color, index) => {\n return (\n <Box key={`color_${index + 1}`}>\n <Field>\n <Label htmlFor={`color_description_${index + 1}`}>\n Description\n </Label>\n <Input\n id={`color_description_${index + 1}`}\n name={`color_description_${index + 1}`}\n type=\"text\"\n value={color.description}\n onChange={(e) =>\n setColors((prev) => {\n const colors = [...prev];\n colors[index].description = e.target.value;\n return colors;\n })\n }\n />\n </Field>\n\n <Field>\n <Label htmlFor={`color_type_${index + 1}`}>Type</Label>\n <Input\n id={`color_type_${index + 1}`}\n name={`color_type_${index + 1}`}\n type=\"text\"\n value={color.type}\n onChange={(e) =>\n setColors((prev) => {\n const colors = [...prev];\n colors[index].type = e.target.value;\n return colors;\n })\n }\n />\n </Field>\n\n <Row>\n <Label htmlFor={`color_type_${index + 1}`}>Value</Label>\n <input\n type=\"color\"\n value={color.value}\n onChange={(e) =>\n setColors((prev) => {\n const colors = [...prev];\n colors[index].value = e.target.value;\n return colors;\n })\n }\n />\n </Row>\n\n <input\n type=\"file\"\n id=\"avatar\"\n name=\"avatar\"\n multiple\n onChange={(e) => {\n if (!e.target.files[0]) return;\n setColors((prev) => {\n const colors = [...prev];\n colors[index].image = e.target.files[0];\n return colors;\n });\n }}\n />\n\n <IconButton\n type=\"button\"\n title=\"Remove Color\"\n onClick={() =>\n setColors((prev) => {\n const colors = [...prev];\n colors.splice(index, 1);\n return colors;\n })\n }\n >\n <Close />\n </IconButton>\n </Box>\n );\n })}\n </Fields>\n </Field>\n\n <Category>\n Categories\n <IconButton\n type=\"button\"\n onClick={() => setCategories([...categories, \"\"])}\n >\n <Plus />\n </IconButton>\n </Category>\n\n <Fields fields={3}>\n {categories.map((category, index) => {\n return (\n <Box key={`category-${index + 1}`}>\n <Field>\n <Label htmlFor={`category_${index + 1}`}>\n Category {index + 1}\n </Label>\n <Input\n id={`category_${index + 1}`}\n name={`category_${index + 1}`}\n type=\"text\"\n value={category}\n onChange={(e) =>\n setCategories((prev) => {\n const categories = [...prev];\n categories[index] = e.target.value;\n return categories;\n })\n }\n />\n </Field>\n\n <BoxButton\n type=\"button\"\n onClick={() =>\n setCategories((prev) => {\n const categories = [...prev];\n categories.splice(index, 1);\n return categories;\n })\n }\n >\n <Close />\n </BoxButton>\n </Box>\n );\n })}\n </Fields>\n\n <Field>\n <Category>\n Options\n <IconButton\n type=\"button\"\n title=\"Add an option\"\n onClick={() =>\n setOptions([\n ...options,\n {\n type: \"\",\n options: [\n {\n option: \"\",\n price: 0,\n dimensions: {\n width: 0,\n height: 0,\n depth: 0,\n },\n },\n ],\n },\n ])\n }\n >\n <Plus />\n </IconButton>\n </Category>\n\n {options.map((option, indexOption) => {\n return (\n <div key={`option_${indexOption + 1}`}>\n <Fields fields={1}>\n <Field>\n <Label htmlFor={`option_type_${indexOption + 1}`}>\n Type\n </Label>\n <Row>\n <Input\n id={`option_type_${indexOption + 1}`}\n name={`option_type_${indexOption + 1}`}\n type=\"text\"\n value={option.type}\n onChange={(e) =>\n setOptions((prev) => {\n const options = [...prev];\n options[indexOption].type = e.target.value;\n return options;\n })\n }\n />\n\n <IconButton\n type=\"button\"\n title=\"Remove Option\"\n onClick={() =>\n setOptions((prev) => {\n const options = [...prev];\n options.splice(indexOption, 1);\n return options;\n })\n }\n >\n <Close />\n </IconButton>\n </Row>\n </Field>\n </Fields>\n\n <TextLabel>Options</TextLabel>\n\n <Fields fields={3}>\n {option.options.map((choice, indexChoice) => {\n return (\n <Box\n key={`option_${indexOption + 1}_choice_${\n indexChoice + 1\n }`}\n >\n <BoxHeading>General</BoxHeading>\n <Field>\n <Label\n htmlFor={`option_${indexOption + 1}_choice_${\n indexChoice + 1\n }_option`}\n >\n Option\n </Label>\n <Input\n id={`option_${indexOption + 1}_choice_${\n indexChoice + 1\n }_option`}\n name={`option_${indexOption + 1}_choice_${\n indexChoice + 1\n }_option`}\n type=\"text\"\n value={choice.option}\n onChange={(e) =>\n setOptions((prev) => {\n const options = [...prev];\n options[indexOption].options[\n indexChoice\n ].option = e.target.value;\n return options;\n })\n }\n />\n </Field>\n\n <Field>\n <Label\n htmlFor={`option_${indexOption + 1}_choice_${\n indexChoice + 1\n }_price`}\n >\n Price\n </Label>\n <Input\n id={`option_${indexOption + 1}_choice_${\n indexChoice + 1\n }_price`}\n name={`option_${indexOption + 1}_choice_${\n indexChoice + 1\n }_price`}\n type=\"number\"\n value={choice.price}\n onChange={(e) =>\n setOptions((prev) => {\n const options = [...prev];\n options[indexOption].options[\n indexChoice\n ].price = +e.target.value;\n return options;\n })\n }\n />\n </Field>\n\n <BoxHeading>Dimensions</BoxHeading>\n <Field>\n <Label\n htmlFor={`option_${indexOption + 1}_choice_${\n indexChoice + 1\n }_depth`}\n >\n Depth\n </Label>\n <Input\n id={`option_${indexOption + 1}_choice_${\n indexChoice + 1\n }_depth`}\n name={`option_${indexOption + 1}_choice_${\n indexChoice + 1\n }_depth`}\n type=\"number\"\n value={choice.dimensions.depth}\n onChange={(e) =>\n setOptions((prev) => {\n const options = [...prev];\n options[indexOption].options[\n indexChoice\n ].dimensions.depth = +e.target.value;\n return options;\n })\n }\n />\n </Field>\n\n <Field>\n <Label\n htmlFor={`option_${indexOption + 1}_choice_${\n indexChoice + 1\n }_height`}\n >\n Height\n </Label>\n <Input\n id={`option_${indexOption + 1}_choice_${\n indexChoice + 1\n }_height`}\n name={`option_${indexOption + 1}_choice_${\n indexChoice + 1\n }_height`}\n type=\"number\"\n value={choice.dimensions.height}\n onChange={(e) =>\n setOptions((prev) => {\n const options = [...prev];\n options[indexOption].options[\n indexChoice\n ].dimensions.height = +e.target.value;\n return options;\n })\n }\n />\n </Field>\n\n <Field>\n <Label\n htmlFor={`option_${indexOption + 1}_choice_${\n indexChoice + 1\n }_width`}\n >\n Width\n </Label>\n <Input\n id={`option_${indexOption + 1}_choice_${\n indexChoice + 1\n }_width`}\n name={`option_${indexOption + 1}_choice_${\n indexChoice + 1\n }_width`}\n type=\"number\"\n value={choice.dimensions.width}\n onChange={(e) =>\n setOptions((prev) => {\n const options = [...prev];\n options[indexOption].options[\n indexChoice\n ].dimensions.width = +e.target.value;\n return options;\n })\n }\n />\n </Field>\n\n <IconButton\n title=\"Remove Choice\"\n type=\"button\"\n onClick={() => {\n const newOptions = [...options];\n newOptions[indexOption].options.splice(\n indexChoice,\n 1\n );\n setOptions(newOptions);\n }}\n >\n <Close />\n </IconButton>\n </Box>\n );\n })}\n <ChoiceBox\n onClick={() => {\n const newOptions = [...options];\n newOptions[indexOption].options = [\n ...options[indexOption].options,\n {\n option: \"\",\n price: 0,\n dimensions: {\n width: 0,\n height: 0,\n depth: 0,\n },\n },\n ];\n setOptions(newOptions);\n }}\n >\n <BoxHeading>Add Choice</BoxHeading>\n <Plus />\n </ChoiceBox>\n </Fields>\n </div>\n );\n })}\n </Field>\n\n <Category>\n Additional\n <IconButton\n type=\"button\"\n title=\"Add an additional information\"\n onClick={() =>\n setAdditional([...additional, { type: \"\", information: \"\" }])\n }\n >\n <Plus />\n </IconButton>\n </Category>\n\n <Fields fields={3}>\n {additional.map((add, index) => {\n return (\n <Box key={`additional_${index + 1}`}>\n <Field>\n <Label htmlFor={`additional_${index + 1}_type`}>Type</Label>\n <Input\n id={`additional_${index + 1}_type`}\n name={`additional_${index + 1}_type`}\n type=\"text\"\n value={add.type}\n onChange={(e) =>\n setAdditional((prev) => {\n const additional = [...prev];\n additional[index].type = e.target.value;\n return additional;\n })\n }\n />\n </Field>\n\n <Field>\n <Label htmlFor={`additional_${index + 1}_information`}>\n Information\n </Label>\n <Row>\n <Input\n id={`additional_${index + 1}_information`}\n name={`additional_${index + 1}_information`}\n type=\"text\"\n value={add.information}\n onChange={(e) =>\n setAdditional((prev) => {\n const additional = [...prev];\n additional[index].information = e.target.value;\n return additional;\n })\n }\n />\n </Row>\n </Field>\n\n <IconButton\n type=\"button\"\n onClick={() =>\n setAdditional((prev) => {\n const additional = [...prev];\n additional.splice(index, 1);\n return additional;\n })\n }\n >\n <Close />\n </IconButton>\n </Box>\n );\n })}\n </Fields>\n\n <Category>Others</Category>\n\n <Row>\n <TextLabel>Seats</TextLabel>\n <IconButton\n title=\"Add Seats Number\"\n type=\"button\"\n onClick={() => setSeats([...seats, 1])}\n >\n <Plus />\n </IconButton>\n </Row>\n\n <Fields fields={3}>\n {seats.map((seat, index) => {\n return (\n <Box key={`seats-${index + 1}`}>\n <Field>\n <Label htmlFor={`seats_${index + 1}`}>\n Seats {index + 1}\n </Label>\n <Input\n id={`seats_${index + 1}`}\n name={`seats_${index + 1}`}\n type=\"number\"\n value={seat}\n onChange={(e) =>\n setSeats((prev) => {\n const seats = [...prev];\n seats[index] = +e.target.value;\n return seats;\n })\n }\n />\n </Field>\n\n <BoxButton\n type=\"button\"\n onClick={() =>\n setSeats((prev) => {\n const seats = [...prev];\n seats.splice(index, 1);\n return seats;\n })\n }\n >\n <Close />\n </BoxButton>\n </Box>\n );\n })}\n </Fields>\n\n <Field>\n <input\n type=\"file\"\n id=\"avatar\"\n name=\"avatar\"\n multiple\n onChange={addImages}\n />\n\n <Preview>\n {imagesPreview.map((image, index) => {\n return (\n <Image key={`preview_${index}`} src={image} alt=\"preview\" />\n );\n })}\n </Preview>\n </Field>\n\n <Button type=\"submit\" disabled={loading}>\n Add an item\n </Button>\n <Message>{message}</Message>\n </Form>\n </Container>\n );\n}\n\nexport default AddShopItem;\n\n// Styled Components\nconst colors = {\n primary: \"hsl(0, 0%, 45%)\", // Grey\n secondary: \"hsl(0, 0%, 27%)\", // Button and checkbox\n tertiary: \"hsl(0, 0%, 90%)\",\n input: \"hsl(0, 0%, 70%)\", // Input lines\n black: \"hsl(0, 0%, 0%)\",\n};\n\nconst Container = styled.div`\n margin: 5rem;\n max-width: 1200px;\n`;\n\nconst Heading = styled.h1`\n margin-bottom: 2rem;\n font-size: 2rem;\n line-height: 2.75rem;\n font-family: \"Playfair Display\", sans-serif;\n`;\n\nconst Form = styled.form`\n display: flex;\n flex-direction: column;\n`;\n\nconst Fields = styled.div`\n display: grid;\n grid-template-columns: repeat(${(props) => props.fields}, 1fr);\n grid-gap: 3rem 5rem;\n margin: 1.25rem 0 3rem 0;\n`;\n\nconst Box = styled.div`\n display: flex;\n flex-direction: column;\n border: 1px solid ${colors.input};\n border-radius: 15px;\n padding: 1.5rem;\n\n & > * {\n margin-top: 1rem;\n }\n\n & > *:first-child {\n margin-top: inherit;\n }\n`;\n\nconst ChoiceBox = styled(Box)`\n align-items: center;\n justify-content: center;\n cursor: pointer;\n`;\n\nconst Category = styled.div`\n display: flex;\n justify-content: space-between;\n align-items: baseline;\n border-bottom: 1px solid ${colors.tertiary};\n text-transform: uppercase;\n color: ${colors.primary};\n padding-bottom: 0.25rem;\n margin-bottom: 1.5rem;\n`;\n\nconst BoxHeading = styled.div`\n text-transform: uppercase;\n font-weight: 600;\n align-self: center;\n padding: 1rem 0;\n`;\n\nconst label = `\ntext-transform: uppercase;\nfont-size: 0.825rem;\nletter-spacing: 1px;\n`;\n\nconst Label = styled.label`\n ${label}\n`;\n\nconst TextLabel = styled.div`\n ${label}\n`;\n\nconst Field = styled.div`\n display: flex;\n flex-direction: column;\n`;\n\nconst Input = styled.input`\n border: none;\n border-bottom: 1px solid ${colors.input};\n padding: 0.5rem 0 0.25rem 0;\n font-family: \"Source Sans Pro\", sans-serif;\n\n &::placeholder {\n color: ${colors.input};\n }\n\n &:focus {\n border-bottom: 1px solid ${colors.black};\n }\n`;\n\nconst IconButton = styled.button`\n color: ${colors.primary};\n\n &:hover {\n color: ${colors.secondary};\n }\n`;\n\nconst BoxButton = styled(IconButton)`\n align-self: center;\n`;\n\nconst Button = styled.button`\n font-family: \"Source Sans Pro\", sans-serif;\n text-transform: uppercase;\n font-size: 0.9rem;\n color: ${colors.tertiary};\n background: ${colors.secondary};\n align-self: center;\n padding: 0.5rem 1rem;\n cursor: pointer;\n\n &:disabled {\n background: ${colors.input};\n cursor: not-allowed;\n }\n`;\n\nconst Preview = styled.div`\n display: grid;\n grid-template-columns: repeat(6, 1fr);\n grid-gap: 2rem;\n`;\n\nconst Image = styled.img`\n max-width: 100%;\n`;\n\nconst Row = styled.div`\n display: grid;\n grid-template-columns: 1fr auto;\n`;\n\nconst Message = styled.div`\n text-align: center;\n font-size: 0.825rem;\n color: ${colors.primary};\n margin-top: 0.25rem;\n`;\n","/home/aureen/the_odin_project/room/src/components/account/Order.jsx",["1255","1256","1257","1258","1259","1260"],"import React, { useState } from \"react\";\nimport styled from \"styled-components\";\nimport PropTypes from \"prop-types\";\nimport CartPreview from \"../shop/cart/CartPreview\";\n\n// Icons\nimport { ReactComponent as Plus } from \"../../assets/icons/icon-plus.svg\";\nimport { ReactComponent as Minus } from \"../../assets/icons/icon-minus.svg\";\n\nfunction Order({ order }) {\n const [isDropdownOpen, setIsDropdownOpen] = useState(true);\n\n const getDate = (time) => {\n const date = new Date(time);\n return `${date.getDate()}/${date.getMonth() + 1}/${date.getFullYear()}`;\n };\n\n return (\n <Container>\n <Top>\n <div>\n <Type>Order</Type>\n <div>{order.id}</div>\n </div>\n\n <div>\n <Type>Date</Type>\n <div>{getDate(order.date.seconds * 1000)}</div>\n </div>\n\n <div>\n <Type>Total:</Type>\n <div>\n {order.products.reduce(\n (sum, item) => sum + item.price * item.quantity,\n 0\n )}\n </div>\n </div>\n\n <div>\n <Type>Deliver to:</Type>\n <div>\n {order.shipping.firstName} {order.shipping.lastName}\n </div>\n </div>\n\n <div>\n <Type>Status</Type>\n <div>{order.status}</div>\n </div>\n\n <Icon onClick={() => setIsDropdownOpen(!isDropdownOpen)}>\n {isDropdownOpen ? <Minus /> : <Plus />}\n </Icon>\n </Top>\n\n {isDropdownOpen && (\n <Dropdown>\n <div>\n <Category>Items</Category>\n <CartPreview cart={order.products} />\n </div>\n\n <div>\n <Category>Informations</Category>\n <Row>\n <div>\n <Subheading>Shipping</Subheading>\n <div>\n <div>\n {order.shipping.firstName} {order.shipping.lastName}\n </div>\n <div>{order.shipping.address}</div>\n <div>\n {order.shipping.zipCode} {order.shipping.city}\n </div>\n <div>{order.shipping.country}</div>\n </div>\n </div>\n <div>\n <Subheading>Payment</Subheading>\n <div>\n <div>Paid by card</div>\n <div>{order.card.name}</div>\n <div>{order.card.number.slice(-4)} (Last 4 digits)</div>\n </div>\n </div>\n </Row>\n </div>\n </Dropdown>\n )}\n </Container>\n );\n}\n\nOrder.propTypes = {\n order: PropTypes.shape({\n id: PropTypes.string,\n date: PropTypes.shape({\n seconds: PropTypes.number,\n }),\n products: PropTypes.arrayOf(PropTypes.object),\n status: PropTypes.string,\n shipping: PropTypes.shape({\n firstName: PropTypes.string,\n lastName: PropTypes.string,\n zipCode: PropTypes.string,\n address: PropTypes.string,\n city: PropTypes.string,\n country: PropTypes.string,\n }),\n card: PropTypes.shape({\n name: PropTypes.string,\n number: PropTypes.string,\n }),\n }).isRequired,\n};\n\nexport default Order;\n\n\n// Styled Components\nconst colors = {\n primary: \"hsl(0, 0%, 45%)\", // Grey\n secondary: \"hsl(0, 0%, 27%)\", // Dark Grey\n tertiary: \"hsl(0, 0%, 70%)\", // Bright Grey\n text: \"hsl(0, 0%, 85%)\",\n label: \"hsl(0, 0%, 100%)\",\n};\n\nconst Container = styled.div`\n min-width: 50vw;\n margin-bottom: 3rem;\n border: 1px solid ${colors.text};\n border-radius: 5px;\n`;\n\nconst Top = styled.div`\n display: grid;\n background: ${colors.secondary};\n padding: 0.75rem 1rem;\n color: ${colors.text};\n line-height: 1.125rem;\n border-radius: 5px 5px 0 0;\n grid-template-columns: repeat(3, auto);\n grid-gap: 1rem;\n\n @media all and (min-width: 576px) {\n grid-template-columns: repeat(3, auto) 1fr auto;\n grid-template-row: repeat(2, auto);\n }\n`;\n\nconst Icon = styled.div`\n grid-row: 1 / -1;\n align-self: center;\n grid-column: -1;\n cursor: pointer;\n\n &:hover {\n color: ${colors.label};\n }\n`;\n\nconst Category = styled.div`\n border-bottom: 1px solid ${colors.tertiary};\n text-transform: uppercase;\n font-size: 0.9rem;\n color: ${colors.primary};\n padding-bottom: 0.25rem;\n margin-bottom: 1.25rem;\n`;\n\nconst Subheading = styled.div`\n display: inline-block;\n text-transform: uppercase;\n color: ${colors.secondary};\n font-weight: 600;\n margin-bottom: 0.5rem;\n`;\n\nconst Type = styled.div`\n text-transform: uppercase;\n font-size: 0.9rem;\n color: ${colors.label};\n`;\n\nconst Dropdown = styled.div`\n margin: 2rem;\n`;\n\nconst Row = styled.div`\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n`;\n","/home/aureen/the_odin_project/room/src/components/shop/display/SideFilters.jsx",["1261","1262","1263","1264","1265","1266","1267","1268","1269","1270","1271","1272","1273","1274","1275","1276","1277","1278","1279","1280","1281","1282","1283","1284","1285","1286","1287","1288","1289","1290","1291","1292","1293","1294","1295","1296","1297","1298","1299","1300","1301","1302","1303","1304","1305","1306","1307","1308","1309","1310","1311","1312"],"import React, { useState, useEffect } from \"react\";\nimport styled from \"styled-components\";\nimport { CSSTransition } from \"react-transition-group\";\nimport { formatNavLink } from \"../../../utils/utils\";\n\n// Icons\nimport check from \"../../../assets/icons/icon-check.svg\";\nimport { ReactComponent as AngleDown } from \"../../../assets/icons/icon-angle-down.svg\";\nimport { ReactComponent as AngleUp } from \"../../../assets/icons/icon-angle-up.svg\";\n\nfunction SideFilters({ items, handleFilters }) {\n // Filters\n const [colors, setColors] = useState([]);\n const [dimensions, setDimensions] = useState({\n width: { min: 0, max: 0 },\n height: { min: 0, max: 0 },\n depth: { min: 0, max: 0 },\n });\n const [price, setPrice] = useState({});\n const [materials, setMaterials] = useState([]);\n const [seats, setSeats] = useState([]);\n\n // Filters values\n const [currentColors, setCurrentColors] = useState([]);\n const [currentDimensions, setCurrentDimensions] = useState({\n width: Infinity,\n height: Infinity,\n depth: Infinity,\n });\n const [currentPrice, setCurrentPrice] = useState(Infinity);\n const [currentMaterials, setCurrentMaterials] = useState([]);\n const [currentSeats, setCurrentSeats] = useState([]);\n const [areColorsOpen, setAreColorsOpen] = useState(true);\n const [areMaterialsOpen, setAreMaterialsOpen] = useState(true);\n const [arePricesOpen, setArePricesOpen] = useState(true);\n const [areDimensionsOpen, setAreDimensionsOpen] = useState(true);\n const [areSeatsOpen, setAreSeatsOpen] = useState(true);\n\n // Load filter values\n useEffect(() => {\n // Set colors filters\n const colorsList = new Set();\n for (const item of items) {\n for (const color of item.colors) {\n if (!colorsList.has(color.type)) colorsList.add(color.type);\n }\n }\n setColors(Array.from(colorsList));\n\n // Set dimensions filters\n const dimensions = {\n width: {\n min: Infinity,\n max: 0,\n },\n height: {\n min: Infinity,\n max: 0,\n },\n depth: {\n min: Infinity,\n max: 0,\n },\n };\n for (const item of items) {\n if (item.queries.dimensions.width.min < dimensions.width.min) {\n dimensions.width.min = item.queries.dimensions.width.min;\n }\n if (item.queries.dimensions.width.max > dimensions.width.max) {\n dimensions.width.max = item.queries.dimensions.width.max;\n }\n if (item.queries.dimensions.height.min < dimensions.height.min) {\n dimensions.height.min = item.queries.dimensions.height.min;\n }\n if (item.queries.dimensions.height.max > dimensions.height.max) {\n dimensions.height.max = item.queries.dimensions.height.max;\n }\n if (item.queries.dimensions.depth.min < dimensions.depth.min) {\n dimensions.depth.min = item.queries.dimensions.depth.min;\n }\n if (item.queries.dimensions.depth.max > dimensions.depth.max) {\n dimensions.depth.max = item.queries.dimensions.depth.max;\n }\n }\n setDimensions(dimensions);\n setCurrentDimensions({\n width: dimensions.width.max,\n height: dimensions.height.max,\n depth: dimensions.depth.max,\n });\n\n // Set materials filters\n const materialsList = new Set();\n for (const item of items) {\n for (const material of item.queries.materials) {\n if (!materialsList.has(material)) materialsList.add(material);\n }\n }\n setMaterials(Array.from(materialsList));\n\n // Set price filters\n const price = {\n min: Infinity,\n max: 0,\n };\n\n for (const item of items) {\n if (item.queries.price.min < price.min)\n price.min = item.queries.price.min;\n if (item.queries.price.max > price.max)\n price.max = item.queries.price.max;\n }\n setPrice(price);\n setCurrentPrice(price.max);\n\n // Set seats filters\n const seatsList = new Set();\n for (const item of items) {\n if (item.queries.seats) {\n for (const seat of item.queries.seats) {\n if (!seatsList.has(seat)) seatsList.add(seat);\n }\n }\n }\n setSeats(Array.from(seatsList));\n }, [items]);\n\n // Give filters values to parent (Category)\n useEffect(() => {\n handleFilters(\"colors\", currentColors);\n }, [currentColors]);\n\n useEffect(() => {\n handleFilters(\"dimensions\", currentDimensions);\n }, [currentDimensions]);\n\n useEffect(() => {\n handleFilters(\"price\", currentPrice);\n }, [currentPrice]);\n\n useEffect(() => {\n handleFilters(\"materials\", currentMaterials);\n }, [currentMaterials]);\n\n useEffect(() => {\n handleFilters(\"seats\", currentSeats);\n }, [currentSeats]);\n\n // Reset filters\n const reset = () => {\n setCurrentColors([]);\n setCurrentDimensions({\n width: +dimensions.width.max,\n height: +dimensions.height.max,\n depth: +dimensions.depth.max,\n });\n setCurrentPrice(+price.max);\n setCurrentMaterials([]);\n setCurrentSeats([]);\n };\n\n return (\n <Container>\n <Filter onClick={() => setAreColorsOpen(!areColorsOpen)}>\n Colors\n <Icon>{areColorsOpen ? <AngleUp /> : <AngleDown />}</Icon>\n </Filter>\n <CSSTransition\n in={areColorsOpen}\n timeout={500}\n classNames=\"dropdown\"\n mountOnEnter\n >\n <div>\n {colors\n .sort((a, b) => a.localeCompare(b))\n .map((color) => {\n return (\n <Color\n key={color}\n color={color}\n isSelected={currentColors.includes(color)}\n onClick={() =>\n setCurrentColors((prevColors) => {\n return prevColors.includes(color)\n ? [...prevColors].filter(\n (prevColor) => prevColor !== color\n )\n : [...prevColors, color];\n })}\n >\n {color}\n </Color>\n );\n })}\n </div>\n </CSSTransition>\n\n <div>\n <Filter onClick={() => setAreDimensionsOpen(!areDimensionsOpen)}>\n Dimensions\n <Icon>{areDimensionsOpen ? <AngleUp /> : <AngleDown />}</Icon>\n </Filter>\n <CSSTransition\n in={areDimensionsOpen}\n timeout={500}\n classNames=\"dropdown\"\n mountOnEnter\n >\n <div>\n <div>\n Height\n <Small>\n ({dimensions.height.min} - {dimensions.height.max}\n)\n</Small>\n </div>\n <Row>\n <Range\n min={dimensions.height.min}\n max={dimensions.height.max}\n value={currentDimensions.height}\n onChange={(e) =>\n setCurrentDimensions({\n ...currentDimensions,\n height: +e.target.value,\n })\n }\n />\n <RangeBubble>{currentDimensions.height}</RangeBubble>\n </Row>\n\n <div>\n Width\n <Small>\n ({dimensions.width.min} - {dimensions.width.max}\n)\n</Small>\n </div>\n <Row>\n <Range\n min={dimensions.width.min}\n max={dimensions.width.max}\n value={currentDimensions.width}\n onChange={(e) =>\n setCurrentDimensions({\n ...currentDimensions,\n width: +e.target.value,\n })\n }\n />\n <RangeBubble>{currentDimensions.width}</RangeBubble>\n </Row>\n\n <div>\n Depth\n <Small>\n ({dimensions.depth.min} - {dimensions.depth.max}\n)\n</Small>\n </div>\n <Row>\n <Range\n min={dimensions.depth.min}\n max={dimensions.depth.max}\n value={currentDimensions.depth}\n onChange={(e) =>\n setCurrentDimensions({\n ...currentDimensions,\n depth: +e.target.value,\n })\n }\n />\n <RangeBubble>{currentDimensions.depth}</RangeBubble>\n </Row>\n </div>\n </CSSTransition>\n </div>\n\n <div>\n <Filter onClick={() => setAreMaterialsOpen(!areMaterialsOpen)}>\n Materials\n <Icon>{areMaterialsOpen ? <AngleUp /> : <AngleDown />}</Icon>\n </Filter>\n <CSSTransition\n in={areMaterialsOpen}\n timeout={500}\n classNames=\"dropdown\"\n mountOnEnter\n >\n <div>\n {materials\n .sort((a, b) => a.localeCompare(b))\n .map((material) => {\n return (\n <Checkbox\n key={material}\n isSelected={currentMaterials.includes(material)}\n onClick={() =>\n setCurrentMaterials((prevMaterials) => {\n return prevMaterials.includes(material)\n ? [...prevMaterials].filter(\n (prevMaterial) => prevMaterial !== material\n )\n : [...prevMaterials, material];\n })\n }\n >\n {formatNavLink(material)}\n </Checkbox>\n );\n })}\n </div>\n </CSSTransition>\n </div>\n\n <div>\n <Filter onClick={() => setAreSeatsOpen(!areSeatsOpen)}>\n Seats\n <Icon>{areSeatsOpen ? <AngleUp /> : <AngleDown />}</Icon>\n </Filter>\n <CSSTransition\n in={areSeatsOpen}\n timeout={500}\n classNames=\"dropdown\"\n mountOnEnter\n >\n <div>\n {seats\n .sort((a, b) => a - b)\n .map((number) => {\n return (\n <Checkbox\n key={number}\n isSelected={currentSeats.includes(number)}\n onClick={() =>\n setCurrentSeats((prevSeats) => {\n return prevSeats.includes(number)\n ? [...prevSeats].filter(\n (prevMaterial) => prevMaterial !== number\n )\n : [...prevSeats, number];\n })\n }\n >\n {number}\n </Checkbox>\n );\n })}\n </div>\n </CSSTransition>\n </div>\n\n <div>\n <Filter onClick={() => setArePricesOpen(!arePricesOpen)}>\n <div>\n Price\n <Small>\n ({price.min} - {price.max}\n)\n</Small>\n </div>\n {arePricesOpen ? <AngleUp /> : <AngleDown />}\n </Filter>\n <CSSTransition\n in={arePricesOpen}\n timeout={500}\n classNames=\"dropdown\"\n mountOnEnter\n >\n <Row>\n <Range\n min={price.min}\n max={price.max}\n step={0.5}\n value={currentPrice}\n onChange={(e) => setCurrentPrice(+e.target.value)}\n />\n <RangeBubble>{currentPrice}</RangeBubble>\n </Row>\n </CSSTransition>\n </div>\n\n <Button type=\"button\" onClick={reset}>\n Reset\n </Button>\n </Container>\n );\n}\n\nexport default SideFilters;\n\n\n// Styled Components\nconst colors = {\n primary: \"hsl(0, 0%, 45%)\", // Grey\n secondary: \"hsl(0, 0%, 27%)\", // Dark Grey\n tertiary: \"hsl(0, 0%, 70%)\", // Bright Grey\n text: \"hsl(0, 0%, 85%)\",\n label: \"hsl(0, 0%, 100%)\",\n};\n\nconst filterColors = {\n beige: \"hsl(20, 49%, 73%)\",\n black: \"hsl(0, 0%, 0%)\",\n blue: \"hsl(213, 95%, 36%)\",\n brown: \"hsl(20, 35%, 29%)\",\n green: \"hsl(141, 28%, 29%)\",\n grey: \"hsl(0, 0%, 50%)\",\n orange: \"hsl(9, 39%, 51%)\",\n red: \"hsl(0, 50%, 38%)\",\n white: \"hsl(0, 0%, 100%)\",\n yellow: \"hsl(39, 39%, 53%)\",\n};\n\nconst Container = styled.div`\n line-height: 1.5rem;\n margin-right: 1rem;\n display: flex;\n flex-direction: column;\n\n & > * {\n margin-bottom: 1.5rem;\n }\n\n @media all and (min-width: 1200px) {\n margin-right: 5rem;\n }\n`;\n\nconst Filter = styled.h3`\n display: flex;\n align-items: center;\n justify-content: space-between;\n text-transform: uppercase;\n font-weight: 600;\n margin: 0.5rem 0;\n`;\n\nconst Row = styled.div`\n display: flex;\n`;\n\nconst filterButton = `\n text-transform: capitalize;\n display: flex;\n align-items: center;\n margin: .15rem 0;\n\n &:before {\n content: '';\n display: inline-block;\n width: 0.75rem;\n height: 0.75rem;\n margin-right: 0.75rem;\n border: 1px solid ${colors.primary};\n }\n`;\n\nconst Color = styled.button`\n ${filterButton}\n font-weight: ${(props) => props.isSelected && \"600\"};\n\n &:before {\n background-color: ${(props) => filterColors[props.color] || props.color};\n }\n`;\n\nconst Checkbox = styled.button`\n ${filterButton}\n font-weight: ${(props) => props.isSelected && \"600\"};\n\n &:before {\n background-color: ${(props) => props.isSelected && colors.secondary};\n background-image: ${(props) => props.isSelected && `url(${check})`};\n background-position: ${(props) => props.isSelected && \"center\"};\n border-radius: 2px;\n }\n`;\n\nconst Small = styled.span`\n display: inline-block;\n margin-left: 0.4rem;\n font-size: 0.825rem;\n color: ${colors.secondary};\n font-weight: 500;\n`;\n\nconst Range = styled.input.attrs((props) => ({\n type: \"range\",\n}))`\n margin: 0.5rem 0;\n -webkit-appearance: none;\n\n &:focus {\n outline: none;\n }\n\n &::-webkit-slider-thumb {\n -webkit-appearance: none;\n }\n\n &::-webkit-slider-thumb {\n width: 13px;\n height: 13px;\n margin-top: -3px;\n border-radius: 50%;\n background: ${colors.secondary};\n }\n\n &::-webkit-slider-runnable-track {\n background: ${colors.tertiary};\n height: 5px;\n border-radius: 5px;\n cursor: pointer;\n }\n`;\n\nconst RangeBubble = styled.span`\n position: relative;\n display: inline-block;\n padding: 0.15rem 0;\n min-width: 3rem;\n text-align: center;\n background: ${colors.secondary};\n border-radius: 3px;\n color: ${colors.text};\n margin-left: 1rem;\n\n &:before {\n content: \"\";\n position: absolute;\n border-top: 7px solid transparent;\n border-bottom: 7px solid transparent;\n border-right: 7px solid ${colors.secondary};\n left: -6px;\n top: 50%;\n transform: translateY(-50%);\n }\n`;\n\nconst Button = styled.button`\n margin-top: 1.5rem;\n text-transform: uppercase;\n font-size: 0.9rem;\n color: ${colors.text};\n background: ${colors.secondary};\n align-self: center;\n padding: 0.5rem 1rem;\n cursor: pointer;\n\n &:hover {\n color: ${colors.label};\n }\n`;\n\nconst Icon = styled.button`\n cursor: pointer;\n`;\n","/home/aureen/the_odin_project/room/src/components/shop/display/Filters.jsx",["1313","1314","1315","1316","1317","1318","1319","1320","1321","1322","1323","1324","1325","1326","1327","1328","1329","1330","1331","1332","1333","1334","1335","1336","1337","1338","1339","1340","1341","1342","1343","1344","1345","1346","1347","1348","1349","1350","1351","1352","1353","1354","1355","1356","1357","1358","1359","1360"],"import React, { useState, useEffect } from \"react\";\nimport styled from \"styled-components\";\nimport PropTypes from \"prop-types\";\nimport { CSSTransition } from \"react-transition-group\";\nimport { formatNavLink } from \"../../../utils/utils\";\n\n// Icons\nimport check from \"../../../assets/icons/icon-check.svg\";\nimport { ReactComponent as FilterIcon } from \"../../../assets/icons/icon-filter.svg\";\nimport { ReactComponent as AngleDown } from \"../../../assets/icons/icon-angle-down.svg\";\nimport { ReactComponent as AngleUp } from \"../../../assets/icons/icon-angle-up.svg\";\n\nfunction Filters({ items, handleFilters }) {\n // Filters\n const [colors, setColors] = useState([]);\n const [dimensions, setDimensions] = useState({\n width: { min: 0, max: 0 },\n height: { min: 0, max: 0 },\n depth: { min: 0, max: 0 },\n });\n const [price, setPrice] = useState({});\n const [materials, setMaterials] = useState([]);\n const [seats, setSeats] = useState([]);\n\n // Filters values\n const [currentColors, setCurrentColors] = useState([]);\n const [currentDimensions, setCurrentDimensions] = useState({\n width: Infinity,\n height: Infinity,\n depth: Infinity,\n });\n const [currentPrice, setCurrentPrice] = useState(Infinity);\n const [currentMaterials, setCurrentMaterials] = useState([]);\n const [currentSeats, setCurrentSeats] = useState([]);\n\n const [isDropdownOpen, setIsDropdownOpen] = useState(false);\n const [areColorsOpen, setAreColorsOpen] = useState(false);\n const [areMaterialsOpen, setAreMaterialsOpen] = useState(false);\n const [arePricesOpen, setArePricesOpen] = useState(false);\n const [areDimensionsOpen, setAreDimensionsOpen] = useState(false);\n const [areSeatsOpen, setAreSeatsOpen] = useState(false);\n\n // Load filter values\n useEffect(() => {\n // Set colors filters\n const colorsList = new Set();\n for (const item of items) {\n for (const color of item.colors) {\n if (!colorsList.has(color.type)) colorsList.add(color.type);\n }\n }\n setColors(Array.from(colorsList));\n\n // Set dimensions filters\n const dimensions = {\n width: {\n min: Infinity,\n max: 0,\n },\n height: {\n min: Infinity,\n max: 0,\n },\n depth: {\n min: Infinity,\n max: 0,\n },\n };\n for (const item of items) {\n if (item.queries.dimensions.width.min < dimensions.width.min) {\n dimensions.width.min = item.queries.dimensions.width.min;\n }\n if (item.queries.dimensions.width.max > dimensions.width.max) {\n dimensions.width.max = item.queries.dimensions.width.max;\n }\n if (item.queries.dimensions.height.min < dimensions.height.min) {\n dimensions.height.min = item.queries.dimensions.height.min;\n }\n if (item.queries.dimensions.height.max > dimensions.height.max) {\n dimensions.height.max = item.queries.dimensions.height.max;\n }\n if (item.queries.dimensions.depth.min < dimensions.depth.min) {\n dimensions.depth.min = item.queries.dimensions.depth.min;\n }\n if (item.queries.dimensions.depth.max > dimensions.depth.max) {\n dimensions.depth.max = item.queries.dimensions.depth.max;\n }\n }\n setDimensions(dimensions);\n setCurrentDimensions({\n width: dimensions.width.max,\n height: dimensions.height.max,\n depth: dimensions.depth.max,\n });\n\n // Set materials filters\n const materialsList = new Set();\n for (const item of items) {\n for (const material of item.queries.materials) {\n if (!materialsList.has(material)) materialsList.add(material);\n }\n }\n setMaterials(Array.from(materialsList));\n\n // Set price filters\n const price = {\n min: Infinity,\n max: 0,\n };\n\n for (const item of items) {\n if (item.queries.price.min < price.min)\n price.min = item.queries.price.min;\n if (item.queries.price.max > price.max)\n price.max = item.queries.price.max;\n }\n setPrice(price);\n setCurrentPrice(price.max);\n\n // Set seats filters\n const seatsList = new Set();\n for (const item of items) {\n if (item.queries.seats) {\n for (const seat of item.queries.seats) {\n if (!seatsList.has(seat)) seatsList.add(seat);\n }\n }\n }\n setSeats(Array.from(seatsList));\n }, [items]);\n\n // Give filters values to parent (Category)\n useEffect(() => {\n handleFilters(\"colors\", currentColors);\n }, [currentColors]);\n\n useEffect(() => {\n handleFilters(\"dimensions\", currentDimensions);\n }, [currentDimensions]);\n\n useEffect(() => {\n handleFilters(\"price\", currentPrice);\n }, [currentPrice]);\n\n useEffect(() => {\n handleFilters(\"materials\", currentMaterials);\n }, [currentMaterials]);\n\n useEffect(() => {\n handleFilters(\"seats\", currentSeats);\n }, [currentSeats]);\n\n // Reset filters\n const reset = () => {\n setCurrentColors([]);\n setCurrentDimensions({\n width: +dimensions.width.max,\n height: +dimensions.height.max,\n depth: +dimensions.depth.max,\n });\n setCurrentPrice(+price.max);\n setCurrentMaterials([]);\n setCurrentSeats([]);\n };\n\n const closeAll = () => {\n setAreColorsOpen(false);\n setAreMaterialsOpen(false);\n setArePricesOpen(false);\n setAreDimensionsOpen(false);\n setAreSeatsOpen(false);\n };\n\n return (\n <>\n <OpenButton\n type=\"button\"\n onClick={() => {\n if (isDropdownOpen) closeAll();\n setIsDropdownOpen(!isDropdownOpen);\n }}\n >\n Filters <FilterIcon />\n </OpenButton>\n {isDropdownOpen && (\n <Dropdown>\n <Filter onClick={() => setAreColorsOpen(!areColorsOpen)}>\n Colors {areColorsOpen ? <AngleUp /> : <AngleDown />}\n </Filter>\n <CSSTransition\n in={areColorsOpen}\n timeout={500}\n classNames=\"dropdown\"\n mountOnEnter\n >\n <div>\n {colors\n .sort((a, b) => a.localeCompare(b))\n .map((color) => {\n return (\n <Color\n key={color}\n color={color}\n isSelected={currentColors.includes(color)}\n onClick={() =>\n setCurrentColors((prevColors) => {\n return prevColors.includes(color)\n ? [...prevColors].filter(\n (prevColor) => prevColor !== color\n )\n : [...prevColors, color];\n })\n }\n >\n {color}\n </Color>\n );\n })}\n </div>\n </CSSTransition>\n\n <div>\n <Filter onClick={() => setAreDimensionsOpen(!areDimensionsOpen)}>\n Dimensions\n {areDimensionsOpen ? <AngleUp /> : <AngleDown />}\n </Filter>\n <CSSTransition\n in={areDimensionsOpen}\n timeout={500}\n classNames=\"dropdown\"\n mountOnEnter\n >\n <div>\n <div>\n Height\n <Small>\n ({dimensions.height.min} - {dimensions.height.max}\n)\n</Small>\n </div>\n <Row>\n <Range\n min={dimensions.height.min}\n max={dimensions.height.max}\n value={currentDimensions.height}\n onChange={(e) =>\n setCurrentDimensions({\n ...currentDimensions,\n height: +e.target.value,\n })\n }\n />\n <RangeBubble>{currentDimensions.height}</RangeBubble>\n </Row>\n\n <div>\n Width\n <Small>\n ({dimensions.width.min} - {dimensions.width.max}\n)\n</Small>\n </div>\n <Row>\n <Range\n min={dimensions.width.min}\n max={dimensions.width.max}\n value={currentDimensions.width}\n onChange={(e) =>\n setCurrentDimensions({\n ...currentDimensions,\n width: +e.target.value,\n })\n }\n />\n <RangeBubble>{currentDimensions.width}</RangeBubble>\n </Row>\n\n <div>\n Depth\n <Small>\n ({dimensions.depth.min} - {dimensions.depth.max}\n)\n</Small>\n </div>\n <Row>\n <Range\n min={dimensions.depth.min}\n max={dimensions.depth.max}\n value={currentDimensions.depth}\n onChange={(e) =>\n setCurrentDimensions({\n ...currentDimensions,\n depth: +e.target.value,\n })\n }\n />\n <RangeBubble>{currentDimensions.depth}</RangeBubble>\n </Row>\n </div>\n </CSSTransition>\n </div>\n\n <div>\n <Filter onClick={() => setAreMaterialsOpen(!areMaterialsOpen)}>\n Materials\n {areMaterialsOpen ? <AngleUp /> : <AngleDown />}\n </Filter>\n <CSSTransition\n in={areMaterialsOpen}\n timeout={500}\n classNames=\"dropdown\"\n mountOnEnter\n >\n <div>\n {materials\n .sort((a, b) => a.localeCompare(b))\n .map((material) => {\n return (\n <Checkbox\n key={material}\n isSelected={currentMaterials.includes(material)}\n onClick={() =>\n setCurrentMaterials((prevMaterials) => {\n return prevMaterials.includes(material)\n ? [...prevMaterials].filter(\n (prevMaterial) => prevMaterial !== material\n )\n : [...prevMaterials, material];\n })\n }\n >\n {formatNavLink(material)}\n </Checkbox>\n );\n })}\n </div>\n </CSSTransition>\n </div>\n\n <div>\n <Filter onClick={() => setAreSeatsOpen(!areSeatsOpen)}>\n Seats\n {areSeatsOpen ? <AngleUp /> : <AngleDown />}\n </Filter>\n <CSSTransition\n in={areSeatsOpen}\n timeout={500}\n classNames=\"dropdown\"\n mountOnEnter\n >\n <div>\n {seats\n .sort((a, b) => a - b)\n .map((number) => {\n return (\n <Checkbox\n key={number}\n isSelected={currentSeats.includes(number)}\n onClick={() =>\n setCurrentSeats((prevSeats) => {\n return prevSeats.includes(number)\n ? [...prevSeats].filter(\n (prevMaterial) => prevMaterial !== number\n )\n : [...prevSeats, number];\n })\n }\n >\n {number}\n </Checkbox>\n );\n })}\n </div>\n </CSSTransition>\n </div>\n\n <div>\n <Filter onClick={() => setArePricesOpen(!arePricesOpen)}>\n <div>\n Price\n <Small>\n ({price.min} - {price.max})\n </Small>\n </div>\n {arePricesOpen ? <AngleUp /> : <AngleDown />}\n </Filter>\n <CSSTransition\n in={arePricesOpen}\n timeout={500}\n classNames=\"dropdown\"\n mountOnEnter\n >\n <Row>\n <Range\n min={price.min}\n max={price.max}\n step={0.5}\n value={currentPrice}\n onChange={(e) => setCurrentPrice(+e.target.value)}\n />\n <RangeBubble>{currentPrice}</RangeBubble>\n </Row>\n </CSSTransition>\n </div>\n\n <Buttons>\n <Button type=\"button\" onClick={() => setIsDropdownOpen(false)}>\n Apply\n </Button>\n <ButtonEmpty type=\"button\" onClick={reset}>\n Reset\n </ButtonEmpty>\n </Buttons>\n </Dropdown>\n )}\n </>\n );\n}\n\nexport default Filters;\n\nFilters.propTypes = {\n items: PropTypes.array,\n handleFilters: PropTypes.func.isRequired,\n};\n\nFilters.defaultProps = {\n items: [],\n};\n\n// Styled Components\nconst colors = {\n primary: \"hsl(0, 0%, 45%)\", // Grey\n secondary: \"hsl(0, 0%, 27%)\", // Dark Grey\n tertiary: \"hsl(0, 0%, 70%)\", // Bright Grey\n text: \"hsl(0, 0%, 85%)\",\n label: \"hsl(0, 0%, 100%)\",\n};\n\nconst filterColors = {\n beige: \"hsl(20, 49%, 73%)\",\n black: \"hsl(0, 0%, 0%)\",\n blue: \"hsl(213, 95%, 36%)\",\n brown: \"hsl(20, 35%, 29%)\",\n green: \"hsl(141, 28%, 29%)\",\n grey: \"hsl(0, 0%, 50%)\",\n orange: \"hsl(9, 39%, 51%)\",\n red: \"hsl(0, 50%, 38%)\",\n white: \"hsl(0, 0%, 100%)\",\n yellow: \"hsl(39, 39%, 53%)\",\n};\n\nconst Dropdown = styled.div`\n line-height: 1.5rem;\n display: flex;\n flex-direction: column;\n grid-column: 1 / -1;\n`;\n\nconst Filter = styled.h3`\n text-transform: uppercase;\n font-weight: 600;\n margin: 0.5rem 0;\n cursor: pointer;\n display: flex;\n justify-content: space-between;\n`;\n\nconst Row = styled.div`\n display: flex;\n`;\n\nconst Buttons = styled.div`\n display: flex;\n justify-content: center;\n\n & > *:first-child {\n margin-right: 2rem;\n }\n`;\n\nconst filterButton = `\n text-transform: capitalize;\n display: flex;\n align-items: center;\n margin: .15rem 0;\n\n &:before {\n content: '';\n display: inline-block;\n width: 0.75rem;\n height: 0.75rem;\n margin-right: 0.75rem;\n border: 1px solid ${colors.primary};\n }\n`;\n\nconst Color = styled.button`\n ${filterButton}\n font-weight: ${(props) => props.isSelected && \"600\"};\n\n &:before {\n background-color: ${(props) => filterColors[props.color] || props.color};\n }\n`;\n\nconst Checkbox = styled.button`\n ${filterButton}\n font-weight: ${(props) => props.isSelected && \"600\"};\n\n &:before {\n background-color: ${(props) => props.isSelected && colors.secondary};\n background-image: ${(props) => props.isSelected && `url(${check})`};\n background-position: ${(props) => props.isSelected && \"center\"};\n border-radius: 2px;\n }\n`;\n\nconst Small = styled.span`\n display: inline-block;\n margin-left: 0.4rem;\n font-size: 0.825rem;\n color: ${colors.secondary};\n font-weight: 500;\n`;\n\nconst Range = styled.input.attrs((props) => ({\n type: \"range\",\n}))`\n margin: 0.5rem 0;\n -webkit-appearance: none;\n\n &:focus {\n outline: none;\n }\n\n &::-webkit-slider-thumb {\n -webkit-appearance: none;\n }\n\n &::-webkit-slider-thumb {\n width: 13px;\n height: 13px;\n margin-top: -3px;\n border-radius: 50%;\n background: ${colors.secondary};\n }\n\n &::-webkit-slider-runnable-track {\n background: ${colors.tertiary};\n height: 5px;\n border-radius: 5px;\n cursor: pointer;\n }\n`;\n\nconst RangeBubble = styled.span`\n position: relative;\n display: inline-block;\n padding: 0.15rem 0;\n min-width: 3rem;\n text-align: center;\n background: ${colors.secondary};\n border-radius: 3px;\n color: ${colors.text};\n margin-left: 1rem;\n\n &:before {\n content: \"\";\n position: absolute;\n border-top: 7px solid transparent;\n border-bottom: 7px solid transparent;\n border-right: 7px solid ${colors.secondary};\n left: -6px;\n top: 50%;\n transform: translateY(-50%);\n }\n`;\n\nconst Button = styled.button`\n margin-top: 1.5rem;\n text-transform: uppercase;\n font-size: 0.9rem;\n color: ${colors.text};\n background: ${colors.secondary};\n align-self: center;\n padding: 0.5rem 1rem;\n cursor: pointer;\n\n &:hover {\n color: ${colors.label};\n }\n`;\n\nconst ButtonEmpty = styled(Button)`\n background: transparent;\n color: ${colors.secondary};\n border: 1px solid ${colors.secondary};\n\n &:hover {\n color: initial;\n }\n`;\n\nconst OpenButton = styled(Button)`\n display: flex;\n justify-content: space-between;\n text-transform: initial;\n margin-top: 0;\n`;\n","/home/aureen/the_odin_project/room/src/components/shop/display/Sort.jsx",["1361"],"import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport styled from \"styled-components\";\nimport angleDown from \"../../../assets/icons/icon-angle-down.svg\";\n\nfunction Sort({ handleSort }) {\n return (\n <Select name=\"sort\" id=\"sort\" onChange={(e) => handleSort(e.target.value)}>\n <option value=\"featured\">Featured</option>\n <option value=\"new\">New In</option>\n <option value=\"alphabetical_increasing\">Alphabetical (A-Z)</option>\n <option value=\"alphabetical_decreasing\">Alphabetical (Z-A)</option>\n <option value=\"price_increasing\">Price (Low to High)</option>\n <option value=\"price_decreasing\">Price (High to Low)</option>\n </Select>\n );\n}\n\nSort.propTypes = {\n handleSort: PropTypes.func,\n};\n\nSort.defaultProps = {\n handleSort: () => {},\n};\n\nexport default Sort;\n\nconst Select = styled.select`\n -webkit-appearance: none;\n -moz-appearance: none;\n\n font-family: \"Source Sans Pro\", sans-serif;\n padding: 0.25rem 2rem 0.25rem 1rem;\n line-height: 1.5rem;\n background-color: transparent;\n background: url(${angleDown});\n background-repeat: no-repeat;\n background-position: 95% center;\n\n &:focus {\n outline: none;\n }\n\n &:after {\n content: \"aaa\";\n }\n`;","/home/aureen/the_odin_project/room/src/components/shop/display/Designs.jsx",["1362","1363","1364","1365","1366","1367","1368"],"/home/aureen/the_odin_project/room/src/components/shop/cart/CartPreview.jsx",["1369","1370","1371","1372","1373","1374","1375","1376"],"import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport styled from \"styled-components\";\n\nfunction CartPreview({ cart }) {\n return (\n <Container>\n <ul>\n {cart.map((product) => {\n return (\n <Product key={product.id}>\n <Image src={product.image} alt=\"Product preview\" />\n <div>\n <Name>{product.name}</Name>\n <Type>\n {product.type}\n {' '}\n in\n {product.color.description}\n </Type>\n {product.options.map((option) => {\n return (\n <Option option={option} key={Object.keys(option)[0]}>\n <Capitalize>{Object.keys(option)[0]}</Capitalize>\n {' '}\n -{\" \"}\n {option[Object.keys(option)[0]].option}\n </Option>\n );\n })}\n </div>\n <div>{product.quantity}</div>\n <Price>£{product.price}</Price>\n </Product>\n );\n })}\n </ul>\n\n <Review>\n <div>Items</div>\n <div>\n £\n {cart.reduce((sum, item) => sum + item.price * item.quantity, 0)}\n </div>\n <div>Shipping</div>\n <div>0</div>\n <Total>Total</Total>\n <Total>\n £\n {cart.reduce((sum, item) => sum + item.price * item.quantity, 0)}\n </Total>\n </Review>\n </Container>\n );\n}\n\nCartPreview.propTypes = {\n cart: PropTypes.arrayOf({\n product: PropTypes.shape({\n id: PropTypes.string,\n name: PropTypes.string,\n type: PropTypes.string,\n image: PropTypes.string,\n color: PropTypes.shape({\n description: PropTypes.string,\n }),\n quantity: PropTypes.number,\n price: PropTypes.number,\n }),\n }).isRequired,\n};\n\nexport default CartPreview;\n\n\nconst colors = {\n primary: \"hsl(0, 0%, 45%)\", // Grey\n secondary: \"hsl(0, 0%, 27%)\", // Darker grey - background\n tertiary: \"hsl(0, 0%, 0%)\", // Black\n quaternary: \"hsl(0, 0%, 55%)\",\n};\n\nconst Container = styled.div`\n display: flex;\n flex-direction: column;\n`;\n\nconst Product = styled.li`\n display: grid;\n grid-gap: 1rem;\n grid-template-columns: auto 3fr 1fr 1fr;\n align-items: center;\n\n @media all and (min-width: 500px) {\n grid-gap: 2rem;\n }\n`;\n\nconst Image = styled.img`\n width: 7.5rem;\n height: 7.5rem;\n`;\n\nconst Name = styled.div`\n text-transform: uppercase;\n`;\n\nconst Price = styled.div`\n text-transform: uppercase;\n letter-spacing: 1px;\n color: ${colors.secondary};\n justify-self: end;\n`;\n\nconst Type = styled.div`\n font-size: 0.9rem;\n color: ${colors.primary};\n`;\n\nconst Option = styled(Type)`\n color: ${colors.quaternary};\n`;\n\nconst Capitalize = styled.span`\n text-transform: capitalize;\n`;\n\nconst Review = styled.div`\n display: grid;\n align-self: flex-end;\n grid-template-columns: repeat(2, auto);\n grid-gap: 0.5rem 1.5rem;\n color: ${colors.primary};\n margin-bottom: 1rem;\n`;\n\nconst Total = styled.div`\n color: ${colors.tertiary};\n font-weight: 600;\n`;\n","/home/aureen/the_odin_project/room/src/components/account/AccessSettings.jsx",[],"/home/aureen/the_odin_project/room/src/components/shop/nav/SideNav.jsx",["1377","1378","1379","1380","1381","1382"],"import React, { useEffect, useState, useRef } from \"react\";\nimport PropTypes from \"prop-types\";\nimport styled from \"styled-components\";\nimport { Link } from \"react-router-dom\";\nimport useShop from \"../../../hooks/useShop\";\nimport { formatNavLink } from \"../../../utils/utils\";\n\n// Icons\nimport { ReactComponent as Hamburger } from \"../../../assets/icons/icon-hamburger.svg\";\n\nfunction SideNav({ nav }) {\n const { getShopCategories } = useShop();\n const [categories, setCategories] = useState({});\n const [isNavOpen, setIsNavOpen] = useState(false);\n const [isDropdownOpen, setIsDropdownOpen] = useState(false);\n const [activeCategory, setActiveCategory] = useState(\"\");\n const [height, setHeight] = useState(0);\n const ref = useRef();\n\n useEffect(() => {\n (async () => {\n const categories = await getShopCategories();\n setCategories(categories);\n })();\n }, []);\n\n useEffect(() => {\n setHeight(nav.current.offsetHeight);\n }, []);\n\n useEffect(() => {\n if (!isNavOpen) return;\n const closeNavListener = (e) => {\n if (ref.current && !ref.current.contains(e.target)) {\n setIsNavOpen(false);\n }\n };\n document.addEventListener(\"click\", closeNavListener);\n return () => {\n document.removeEventListener(\"click\", closeNavListener);\n };\n }, [isNavOpen, ref]);\n\n return (\n <>\n <Icon\n onClick={() => {\n setIsNavOpen(!isNavOpen);\n isNavOpen && setIsDropdownOpen(false);\n }}\n >\n <Hamburger />\n </Icon>\n\n <Container\n ref={ref}\n top={height}\n isNavOpen={isNavOpen}\n isDropdownOpen={isDropdownOpen}\n >\n <Nav>\n {/* Sort the categories by order before displaying them */}\n {Object.keys(categories).length !== 0 &&\n Object.keys(categories)\n .sort((a, b) => categories[a].order - categories[b].order)\n .map((category) => {\n if (Object.keys(categories[category].categories).length === 0) {\n return (\n <CategoryLink\n key={category}\n selected={activeCategory === category}\n to={`/shop/${encodeURIComponent(category)}`}\n onClick={() => {\n setIsDropdownOpen(false);\n setIsNavOpen(false);\n setActiveCategory(category);\n }}\n >\n {formatNavLink(category)}\n </CategoryLink>\n );\n }\n return (\n <Category\n key={category}\n selected={activeCategory === category}\n onClick={() => {\n setIsDropdownOpen(true);\n setActiveCategory(category);\n }}\n >\n {formatNavLink(category)}\n </Category>\n );\n })}\n </Nav>\n\n {isDropdownOpen &&\n Object.keys(categories[activeCategory].categories).length !== 0 &&\n isNavOpen && (\n <DropdownContainer>\n <Dropdown>\n {/* Sort the subcategories by order before displaying them */}\n {Object.keys(categories[activeCategory].categories)\n .sort(\n (a, b) =>\n categories[activeCategory].categories[a].order -\n categories[activeCategory].categories[b].order\n )\n .map((subcategory) => {\n return (\n <Column key={subcategory}>\n <Subcategory\n to={`/shop/${encodeURIComponent(subcategory)}`}\n onClick={() => {\n setIsDropdownOpen(false);\n setIsNavOpen(false);\n }}\n >\n {formatNavLink(subcategory)}\n </Subcategory>\n <div>\n {categories[activeCategory].categories[\n subcategory\n ].categories.map((item) => {\n return (\n <Item\n key={item}\n to={`/shop/${encodeURIComponent(item)}`}\n onClick={() => {\n setIsDropdownOpen(false);\n setIsNavOpen(false);\n }}\n >\n {formatNavLink(item)}\n </Item>\n );\n })}\n </div>\n </Column>\n );\n })}\n <SeeAll>\n <Item\n to={`/shop/${encodeURIComponent(activeCategory)}`}\n onClick={() => {\n setIsDropdownOpen(false);\n setIsNavOpen(false);\n }}\n >\n See all {formatNavLink(activeCategory)}\n </Item>\n </SeeAll>\n </Dropdown>\n </DropdownContainer>\n )}\n </Container>\n </>\n );\n}\n\nSideNav.propTypes = {\n nav: PropTypes.oneOfType([\n PropTypes.func,\n PropTypes.shape({ current: PropTypes.instanceOf(Element)}),\n ]).isRequired,\n};\n\nexport default SideNav;\n\n\n// Styled Components\nconst colors = {\n primary: \"hsl(0, 0%, 0%)\", // Black\n secondary: \"hsl(0, 0%, 27%)\", // Grey,\n tertiary: \"hsl(0, 0%, 100%)\", // White\n background: \"hsl(0, 0%, 100%)\",\n};\n\nconst Icon = styled.button`\n color: ${colors.secondary};\n margin: 0.5rem;\n cursor: pointer;\n\n &:hover {\n color: ${colors.primary};\n }\n`;\n\nconst Container = styled.nav`\n display: flex;\n position: absolute;\n left: 0;\n top: ${(props) => props.top}px;\n height: calc(100% - ${(props) => props.top}px);\n border-top: 1px solid ${colors.secondary};\n background: ${colors.secondary};\n font-size: 0.825rem;\n font-family: \"Source Sans Pro\", sans-serif;\n transition: all 0.15s linear;\n transform: translateX(${(props) => (props.isNavOpen ? \"0\" : \"-100\")}%);\n\n @media all and (max-width: 600px) {\n width: ${(props) => (props.isDropdownOpen ? \"100vw\" : \"initial\")};\n max-width: ${(props) => (props.isDropdownOpen ? \"100%\" : \"initial\")};\n }\n\n @media all and (max-width: 500px) {\n height: 100%;\n }\n`;\n\nconst Nav = styled.ul`\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n padding: 1rem 0;\n`;\n\nconst category = `\n position: relative;\n cursor: pointer;\n text-align: center;\n text-transform: uppercase;\n font-weight: 600;\n color: ${colors.tertiary};\n padding: 0.75rem 2rem calc(0.75rem - 2px) 2rem;\n transition: all 0.3s ease;\n width: 100%;\n text-align: start;\n\n &:after {\n background: none repeat scroll 0 0 transparent;\n bottom: 0;\n content: '';\n display: block;\n width: 2px;\n left: 1rem;\n position: absolute;\n background: #fff;\n transition: height 0.3s ease 0s, top 0.3s ease 0s;\n }\n`;\n\nconst Category = styled.div`\n ${category}\n\n &:hover {\n transform: translateX(${(props) => (props.selected ? \"0\" : \"3\")}%);\n }\n\n &:after {\n height: ${(props) => (props.selected ? \"90%\" : \"0\")};\n top: ${(props) => (props.selected ? \"5%\" : \"50%\")};\n }\n`;\n\nconst CategoryLink = styled(Link)`\n ${category}\n\n &:hover {\n transform: translateX(${(props) => (props.selected ? \"0\" : \"3\")}%);\n }\n\n &:after {\n height: ${(props) => (props.selected ? \"90%\" : \"0\")};\n top: ${(props) => (props.selected ? \"5%\" : \"50%\")};\n }\n`;\n\nconst DropdownContainer = styled.div`\n background: ${colors.tertiary};\n width: 100%;\n box-shadow: 0 5px 5px ${colors.secondary};\n`;\n\nconst Dropdown = styled.div`\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n grid-auto-flow: row;\n grid-gap: 3rem 1rem;\n justify-content: center;\n padding: 1.5rem;\n background: ${colors.tertiary};\n font-size: 0.825rem;\n\n @media all and (max-width: 500px) {\n grid-template-columns: 1fr;\n }\n`;\n\nconst Column = styled.div`\n margin: 0 1rem;\n`;\n\nconst Subcategory = styled(Link)`\n position: relative;\n display: block;\n color: ${colors.primary};\n text-transform: uppercase;\n cursor: pointer;\n margin-bottom: 0.5rem;\n font-weight: 600;\n transition: all 0.15s ease;\n\n &:hover {\n text-decoration: underline;\n }\n`;\n\nconst Item = styled(Link)`\n padding: 0.25rem 0;\n cursor: pointer;\n display: block;\n color: ${colors.secondary};\n border-bottom: 1px solid transparent;\n transition: all 0.15s ease;\n\n &:hover {\n color: ${colors.primary};\n text-decoration: underline;\n }\n`;\n\nconst SeeAll = styled.div`\n grid-column: 1 / -1;\n justify-self: center;\n`;\n","/home/aureen/the_odin_project/room/src/components/shop/cart/CartItem.jsx",["1383","1384","1385","1386","1387","1388","1389","1390","1391","1392","1393"],"import React, { useState, useEffect } from \"react\";\nimport PropTypes from \"prop-types\";\nimport styled from \"styled-components\";\nimport { Link } from \"react-router-dom\";\nimport { useAuth } from \"../../../contexts/AuthContext\";\nimport useCart from \"../../../hooks/useCart\";\n\n// Icon\nimport { ReactComponent as Delete } from \"../../../assets/icons/icon-x-med.svg\";\n\nfunction CartItem({ item }) {\n const [quantity, setQuantity] = useState(item.quantity);\n const { currentUser } = useAuth();\n const { deleteFromCart, updateCartQuantity } = useCart();\n\n useEffect(() => {\n updateCartQuantity(currentUser.uid, item.id, quantity);\n }, [quantity]);\n\n return (\n <Item>\n <Information>\n <Image src={item.image} alt=\"Item preview\" />\n <div>\n <Name>\n <Link to={`/shop/item/${item.id}`}>{item.name}</Link>\n </Name>\n <Type>\n {item.type} - {item.color.description}\n </Type>\n <div>\n {item.options.map((option) => {\n return (\n <Option option={option} key={Object.keys(option)[0]}>\n <Capitalize>{Object.keys(option)[0]}</Capitalize> -{\" \"}\n {option[Object.keys(option)[0]].option}\n </Option>\n );\n })}\n </div>\n <Price>£{item.price}</Price>\n </div>\n </Information>\n\n <Quantity>\n <Button\n onClick={() => setQuantity((prev) => (+prev < 2 ? \"1\" : prev - 1))}\n >\n -\n </Button>\n <QuantityInput\n value={quantity}\n onChange={(e) => {\n let quantity = e.target.value.replace(/[^0-9]/g, \"\");\n if (+quantity < 1 || !quantity) quantity = \"1\";\n setQuantity(quantity);\n }}\n />\n <Button onClick={() => setQuantity((prev) => +prev + 1)}>+</Button>\n </Quantity>\n <Price>£{item.price * quantity}</Price>\n <Button onClick={() => deleteFromCart(currentUser.uid, item.id)}>\n <Delete />\n </Button>\n </Item>\n );\n}\n\nCartItem.propTypes = {\n item: PropTypes.shape({\n price: PropTypes.number,\n id: PropTypes.string,\n type: PropTypes.string,\n name: PropTypes.string,\n quantity: PropTypes.number,\n image: PropTypes.string,\n color: PropTypes.shape({\n description: PropTypes.string,\n }),\n options: PropTypes.object,\n }).isRequired,\n};\n\nexport default CartItem;\n\n// Styled Components\nconst colors = {\n primary: \"hsl(0, 0%, 45%)\", // Grey\n secondary: \"hsl(0, 0%, 15%)\", // Dark Grey\n tertiary: \"hsl(0, 0%, 55%)\", // Bright Grey\n border: \"hsl(0, 0%, 90%)\",\n};\n\nconst Item = styled.div`\n display: grid;\n grid-template-columns: repeat(4, 1fr) auto;\n align-items: center;\n justify-items: center;\n border-bottom: 1px solid ${colors.border};\n`;\n\nconst Information = styled.div`\n display: flex;\n align-items: center;\n line-height: 1.125rem;\n padding: 1rem 0;\n width: 15rem;\n\n @media all and (min-width: 576px) {\n width: 20rem;\n }\n`;\n\nconst Image = styled.img`\n width: 7rem;\n height: 7rem;\n margin-right: 1rem;\n object-fit: cover;\n\n @media all and (min-width: 576px) {\n width: 10rem;\n height: 10rem;\n }\n`;\n\nconst Name = styled.div`\n text-transform: uppercase;\n`;\n\nconst Price = styled.div`\n text-transform: uppercase;\n letter-spacing: 1px;\n color: ${colors.secondary};\n`;\n\nconst Type = styled.span`\n font-size: 0.9rem;\n color: ${colors.primary};\n`;\n\nconst Option = styled.span`\n font-size: 0.9rem;\n color: ${colors.tertiary};\n`;\n\nconst Capitalize = styled.span`\n text-transform: capitalize;\n`;\n\nconst Quantity = styled.div`\n display: flex;\n flex-direction: column;\n align-items: center;\n\n @media all and (min-width: 600px) {\n flex-direction: row;\n }\n`;\n\nconst QuantityInput = styled.input`\n font-family: \"Source Sans Pro\", sans-serif;\n width: 2rem;\n height: 2rem;\n text-align: center;\n`;\n\nconst Button = styled.button`\n font-size: 1.25rem;\n color: ${colors.primary};\n cursor: pointer;\n\n &:hover {\n color: initial;\n }\n`;","/home/aureen/the_odin_project/room/src/components/FullCarousel.jsx",["1394","1395","1396","1397","1398"],"import React, { useState } from \"react\";\nimport styled from \"styled-components\";\nimport { Link } from \"react-router-dom\";\nimport { CSSTransition } from \"react-transition-group\";\nimport { HashLink } from \"react-router-hash-link\";\n\n// Images\nimport { ReactComponent as AngleLeft } from \"../assets/icons/icon-angle-left.svg\";\nimport { ReactComponent as AngleRight } from \"../assets/icons/icon-angle-right.svg\";\nimport { ReactComponent as Arrow } from \"../assets/icons/icon-small-arrow.svg\";\n\nfunction FullCarousel() {\n const images = [\n \"https://firebasestorage.googleapis.com/v0/b/room-f191c.appspot.com/o/images%2Fshop%2Fshop_main_1.jpg?alt=media&token=6955b061-b35e-445a-9c2f-7ea1b7389612\",\n \"https://firebasestorage.googleapis.com/v0/b/room-f191c.appspot.com/o/images%2Fshop%2Fshop_main_2.jpg?alt=media&token=6c2dfbbc-116b-4488-bd9b-c8001a4bc1a3\",\n ];\n const text = [\n {\n title: \"New Arrivals\",\n text: \"Discover our new furnitures and decorations.\",\n link: \"/shop/new_in\",\n },\n {\n title: \"Featured Designs\",\n text: \"Discover our designers' seasonal creations.\",\n link: \"/shop#featured\",\n },\n ];\n const [currentSlide, setCurrentSlide] = useState(0);\n const [isChanging, setIsChanging] = useState(false);\n\n // Functions\n const next = () => {\n currentSlide === images.length - 1\n ? setCurrentSlide(0)\n : setCurrentSlide((prev) => prev + 1);\n setIsChanging(true);\n };\n\n const previous = () => {\n currentSlide === 0\n ? setCurrentSlide(images.length + 1)\n : setCurrentSlide((prev) => prev - 1);\n setIsChanging(true);\n };\n\n return (\n <Container>\n <CarouselComponent>\n <CSSTransition\n in={isChanging}\n timeout={500}\n classNames=\"fade\"\n onEntered={() => setIsChanging(false)}\n >\n <>\n <Image src={images[currentSlide]} alt=\"Hero\" />\n <Text>\n <Title>{text[currentSlide].title}</Title>\n <div>{text[currentSlide].text}</div>\n {text[currentSlide].link.includes(\"#\") ? (\n <HashLink to={text[currentSlide].link}>\n <ShopButton>\n Shop now <Arrow />\n </ShopButton>\n </HashLink>\n ) : (\n <Link to={text[currentSlide].link}>\n <ShopButton>\n Shop now <Arrow />\n </ShopButton>\n </Link>\n )}\n </Text>\n </>\n </CSSTransition>\n\n <ButtonLeft type=\"button\" onClick={previous}>\n <AngleLeft />\n </ButtonLeft>\n <ButtonRight type=\"button\" onClick={next}>\n <AngleRight />\n </ButtonRight>\n\n <ImageButtons>\n {images.map((image, index) => (\n <ImageButton\n key={image}\n onClick={() => {\n setCurrentSlide(index);\n setIsChanging(true);\n }}\n isSelected={currentSlide === index}\n disabled={currentSlide === index}\n >\n {index + 1}\n </ImageButton>\n ))}\n </ImageButtons>\n </CarouselComponent>\n </Container>\n );\n}\n\nexport default FullCarousel;\n\n\nconst colors = {\n arrow: \"hsl(0, 0%, 100%)\",\n button: \"hsl(0, 0%, 27%)\",\n buttonHover: \"hsl(0, 0%, 5%)\",\n text: \"hsl(0, 0%, 0%)\",\n};\n\nconst Container = styled.div`\n display: flex;\n width: 100%;\n height: 100%;\n height: 80vh;\n`;\n\nconst CarouselComponent = styled.div`\n position: relative;\n width: 100%;\n height: 100%;\n`;\n\nconst Text = styled.div`\n position: absolute;\n top: 3rem;\n color: ${colors.arrow};\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n font-size: 1.25rem;\n line-height: 2.5rem;\n text-align: center;\n padding: 0 1rem;\n left: 50%;\n top: 15%;\n transform: translateX(-50%);\n\n @media all and (min-width: 768px) {\n left: 15%;\n top: 50%;\n transform: translateY(-50%);\n font-size: 1.75rem;\n line-height: 3.25rem;\n align-items: flex-start;\n }\n`;\n\nconst Title = styled.div`\n text-transform: uppercase;\n font-size: 2.5rem;\n letter-spacing: 3px;\n\n @media all and (min-width: 768px) {\n font-size: 3.75rem;\n letter-spacing: 6px;\n }\n`;\n\nconst ShopButton = styled.span`\n background: ${colors.arrow};\n padding: 0 1rem;\n margin-top: 0.5rem;\n color: ${colors.button};\n text-transform: uppercase;\n font-size: 1.125rem;\n display: flex;\n align-items: center;\n`;\n\nconst ImageButtons = styled.div`\n position: absolute;\n bottom: 1rem;\n right: 1rem;\n display: flex;\n\n & > * {\n margin-left: 0.5rem;\n }\n\n & > *:first-child {\n margin-left: 0;\n }\n`;\n\nconst ImageButton = styled.button`\n color: ${colors.arrow};\n font-family: \"Playfair Display\", sans-serif;\n font-size: ${(props) => (props.isSelected ? \"1.25rem\" : \"1.125rem\")};\n opacity: ${(props) => (props.isSelected ? \"1\" : \".75\")};\n cursor: pointer;\n\n &:hover {\n font-size: ${(props) => !props.isSelected && \"1.25rem\"};\n }\n`;\n\nconst Button = styled.button`\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n background: ${colors.button};\n padding: 1.5rem 1rem;\n cursor: pointer;\n color: ${colors.arrow};\n\n &:hover {\n background: ${colors.buttonHover};\n }\n`;\n\nconst ButtonLeft = styled(Button)`\n left: 0;\n`;\n\nconst ButtonRight = styled(Button)`\n right: 0;\n`;\n\nconst Image = styled.img`\n width: 100vw;\n object-fit: cover;\n height: 100%;\n filter: brightness(70%);\n`;\n","/home/aureen/the_odin_project/room/src/components/shop/display/ImagesPreview.jsx",["1399","1400","1401"],"/home/aureen/the_odin_project/room/src/components/shop/display/Recommendations.jsx",["1402","1403","1404","1405","1406"],"import React from \"react\";\nimport styled from \"styled-components\";\nimport PropTypes from \"prop-types\";\nimport { useFavorite } from \"../../../contexts/FavoriteContext\";\nimport useCarousel from \"../../../hooks/useCarousel\";\nimport ShopItemPreview from \"./ShopItemPreview\";\n\n// Icons\nimport { ReactComponent as AngleLeft } from \"../../../assets/icons/icon-angle-left.svg\";\nimport { ReactComponent as AngleRight } from \"../../../assets/icons/icon-angle-right.svg\";\n\nfunction Recommendations({ recommendations, number }) {\n const { favorites } = useFavorite();\n const {\n slidesNumber,\n transition,\n transitionDuration,\n slidesGroups,\n previous,\n next,\n handleTransitionEnd,\n } = useCarousel(recommendations, number);\n useCarousel(recommendations, number);\n\n return (\n <>\n <Heading>Similar Items</Heading>\n <Container>\n <Button onClick={previous} disabled={slidesGroups.length < 3}>\n <AngleLeft />\n </Button>\n\n <Gallery>\n <Slides\n onTransitionEnd={handleTransitionEnd}\n transition={transition}\n transitionDuration={transitionDuration}\n slidesGroups={slidesGroups.length}\n >\n {slidesGroups.map((slide, index) => {\n return (\n <Slide key={index} slidesNumber={slidesNumber}>\n {slide.map((slide, index) => {\n if (slide) {\n return (\n <Preview key={`${slide.id}-${index}`}>\n <ShopItemPreview\n name={slide.name}\n images={slide.images}\n price={slide.price}\n id={slide.id}\n isFavorite={favorites.includes(slide.id)}\n isNew={slide.isNew}\n />\n </Preview>\n );\n }\n return <Preview key={`empty-${index}`} />;\n })}\n </Slide>\n );\n })}\n </Slides>\n </Gallery>\n\n <Button onClick={next} disabled={slidesGroups.length < 3}>\n <AngleRight />\n </Button>\n </Container>\n </>\n );\n}\n\nexport default Recommendations;\n\nRecommendations.propTypes = {\n recommendations: PropTypes.arrayOf(\n PropTypes.shape({\n additional: PropTypes.objectOf(PropTypes.string),\n categories: PropTypes.arrayOf(PropTypes.string),\n colors: PropTypes.arrayOf(\n PropTypes.shape({\n description: PropTypes.string,\n image: PropTypes.string,\n type: PropTypes.string,\n value: PropTypes.string,\n })\n ),\n description: PropTypes.arrayOf(PropTypes.string),\n dimensions: PropTypes.shape({\n width: PropTypes.number,\n height: PropTypes.number,\n depth: PropTypes.number,\n }),\n id: PropTypes.string,\n images: PropTypes.arrayOf(PropTypes.string),\n name: PropTypes.string,\n new: PropTypes.bool,\n price: PropTypes.number,\n type: PropTypes.string,\n })\n ).isRequired,\n number: PropTypes.number.isRequired,\n};\n\n// Styled components\nconst colors = {\n heading: \"hsl(0, 0%, 27%)\",\n border: \"hsl(0, 0%, 80%)\",\n button: \"hsl(0, 0%, 50%)\",\n disabled: \"hsl(0, 0%, 90%)\",\n};\n\nconst Container = styled.div`\n display: flex;\n justify-content: space-between;\n width: 100%;\n height: 100%;\n max-width: 1300px;\n margin: 3rem 0;\n`;\n\nconst Gallery = styled.div`\n height: 100%;\n width: 100%;\n overflow: hidden;\n`;\n\nconst Slides = styled.div`\n display: grid;\n grid-auto-flow: column;\n transition: transform ${(props) => props.transitionDuration}s linear;\n transform: translateX(${(props) => props.transition}%);\n width: ${(props) => props.slidesGroups * 100}%;\n`;\n\nconst Slide = styled.div`\n display: grid;\n grid-template-columns: repeat(${(props) => props.slidesNumber}, 1fr);\n min-width: 0;\n`;\n\nconst Button = styled.button`\n width: 2rem;\n padding: 0;\n cursor: pointer;\n color: ${colors.button};\n\n &:disabled {\n color: ${colors.disabled};\n }\n`;\n\nconst Preview = styled.div`\n width: 100%;\n height: 100%;\n cursor: pointer;\n display: flex;\n justify-content: center;\n`;\n\nconst Heading = styled.h2`\n text-transform: uppercase;\n display: flex;\n align-items: center;\n align-self: stretch;\n justify-content: center;\n font-size: 1.25rem;\n margin-top: 3rem;\n\n &:before,\n &:after {\n content: \"\";\n display: inline-block;\n margin: 0 1rem;\n height: 1px;\n width: 20%;\n background: ${colors.heading};\n background: linear-gradient(270deg, transparent, ${colors.heading});\n }\n\n &:before {\n background: linear-gradient(270deg, ${colors.heading}, transparent);\n }\n`;\n","/home/aureen/the_odin_project/room/src/components/shop/checkout/Order.jsx",["1407","1408","1409","1410","1411","1412","1413","1414","1415","1416","1417"],"import React, { useState, useEffect } from \"react\";\nimport styled from \"styled-components\";\nimport { Link } from \"react-router-dom\";\nimport { useAuth } from \"../../../contexts/AuthContext\";\nimport useCart from \"../../../hooks/useCart\";\n\nfunction Order() {\n const [cart, setCart] = useState([]);\n const { getCart } = useCart();\n const { currentUser } = useAuth();\n\n useEffect(() => {\n (async () => {\n if (!currentUser) return;\n const cart = await getCart(currentUser.uid);\n setCart(cart);\n })();\n }, []);\n\n return (\n <Container>\n <Heading>Order Summary</Heading>\n <Cart>\n <ul>\n {cart.map((item) => {\n return (\n <Item key={item.id}>\n <div>\n <Name>{item.name}</Name>\n <Type>\n {item.type} in {item.color.description}\n </Type>\n {item.options.map((option) => {\n return (\n <div option={option} key={Object.keys(option)[0]}>\n <Capitalize>{Object.keys(option)[0]}</Capitalize> -\n{\" \"}\n {option[Object.keys(option)[0]].option}\n </div>\n );\n })}\n </div>\n <Quantity>{item.quantity}</Quantity>\n <Price>£{item.price}</Price>\n </Item>\n );\n })}\n </ul>\n <Row>\n <div>Items</div>\n <Price>£{cart.reduce((sum, item) => sum + +item.price, 0)}</Price>\n </Row>\n <Row>\n <div>Shipping</div>\n <Price>£0</Price>\n </Row>\n <Total>\n <Row>\n <TotalLabel>Total</TotalLabel>\n <TotalPrice>\n £{cart.reduce((sum, item) => sum + +item.price, 0)}\n </TotalPrice>\n </Row>\n </Total>\n </Cart>\n\n <GoBack>\n <Link to=\"/shop/cart\">← Edit your cart</Link>\n </GoBack>\n </Container>\n );\n}\n\nexport default Order;\n\nconst colors = {\n primary: \"hsl(0, 0%, 45%)\", // Grey\n secondary: \"hsl(0, 0%, 27%)\", // Darker grey - for background\n text: \"hsl(0, 0%, 95%)\",\n white: \"hsl(0, 0%, 100%)\",\n small: \"hsl(0, 0%, 85%)\",\n accent: \"hsl(46, 65%, 52%)\", // Gold\n};\n\nconst Container = styled.div`\n margin-left: 5rem;\n background: ${colors.secondary};\n color: ${colors.text};\n padding: 3rem 4rem;\n display: flex;\n flex-direction: column;\n align-items: center;\n flex: 1;\n`;\n\nconst Cart = styled.div`\n line-height: 1.25rem;\n width: 100%;\n`;\n\nconst Heading = styled.h3`\n font-size: 1.25rem;\n margin-bottom: 1.5rem;\n`;\n\nconst Item = styled.li`\n display: grid;\n grid-template-columns: 1fr auto;\n grid-row-gap: 1rem;\n\n &:after {\n content: \"\";\n grid-column: 1 / -1;\n width: 100%;\n height: 1px;\n margin-bottom: 1rem;\n background: ${colors.primary};\n background: linear-gradient(\n 90deg,\n ${colors.secondary} 0%,\n ${colors.accent} 40%,\n ${colors.accent} 60%,\n ${colors.secondary} 100%\n );\n }\n`;\n\nconst Name = styled.div`\n text-transform: uppercase;\n font-size: 0.9rem;\n`;\n\nconst Type = styled.div`\n font-style: italic;\n color: ${colors.small};\n`;\n\nconst Capitalize = styled.span`\n text-transform: capitalize;\n`;\n\nconst Quantity = styled.div`\n font-size: 0.9rem;\n justify-self: end;\n`;\n\nconst Price = styled.div`\n grid-column: -2;\n font-weight: 600;\n`;\n\nconst Row = styled.div`\n display: grid;\n grid-template-columns: 1fr auto;\n margin: 0.5rem 0;\n`;\n\nconst Total = styled.div`\n margin: 1.5rem 0;\n`;\n\nconst TotalLabel = styled.div`\n text-transform: uppercase;\n font-weight: 600;\n color: ${colors.accent};\n`;\n\nconst TotalPrice = styled.div`\n font-weight: 600;\n font-size: 1.125rem;\n`;\n\nconst GoBack = styled.div`\n &:hover {\n color: ${colors.white};\n }\n`;\n","/home/aureen/the_odin_project/room/src/hooks/useSignUp.js",["1418"],"/home/aureen/the_odin_project/room/src/hooks/useStorage.js",[],"/home/aureen/the_odin_project/room/src/hooks/useCarousel.js",["1419","1420","1421","1422"],"import { useState, useEffect } from \"react\";\n\nfunction useCarousel(slides, number) {\n const [currentSlide, setCurrentSlide] = useState(0);\n const [slidesNumber, setSlidesNumber] = useState(number);\n const [slidesGroups, setSlidesGroups] = useState([]);\n const [transition, setTransition] = useState(0);\n const [transitionDuration, setTransitionDuration] = useState(0.3);\n const [isInitialized, setIsInitialized] = useState(false);\n const [isNext, setIsNext] = useState(false); // Indicates the carousel direction (previous/next)\n\n const previous = () => {\n setIsNext(false);\n setTransition((prev) => prev + 100 / slidesGroups.length);\n setCurrentSlide((prev) => {\n return prev === 0 ? slidesGroups.length - 1 : prev - 1;\n });\n };\n\n const next = () => {\n setIsNext(true);\n setTransition((prev) => prev - 100 / slidesGroups.length);\n setCurrentSlide((prev) => {\n return prev === slidesGroups.length - 1 ? 0 : prev + 1;\n });\n };\n\n /* At the end of each transition:\n - The transition duration is set to 0. It allows us to silently reset transform: translateX to 0.\n - The slides order is changed so that there is always a \"previous slide\" and a \"next slide\" to go to without jumping too far.\n - Thanks to useEffect, the transition duration is put back to 0.3s to have a smooth animation.\n */\n const handleTransitionEnd = () => {\n if (!isInitialized) return;\n setTransitionDuration(0);\n setTransition(-100 / slidesGroups.length);\n\n if (isNext) {\n setSlidesGroups((prev) => {\n const slides = [...prev];\n slides.pop();\n const prevSlide = slides.shift();\n slides.push(prevSlide);\n slides.push(slides[0]);\n return slides;\n });\n } else {\n setSlidesGroups((prev) => {\n const slides = [...prev];\n slides.shift();\n const lastSlide = slides.pop();\n slides.unshift(lastSlide);\n slides.unshift(slides[slides.length - 1]);\n return slides;\n });\n }\n };\n\n // Organize slides.\n // 1 \"slide\" = 1 group of slidesNumber mini preview pictures.\n useEffect(() => {\n const slidesGroups = [];\n slides.forEach((slide, index) => {\n index % slidesNumber === 0\n ? slidesGroups.push([slide])\n : slidesGroups[slidesGroups.length - 1].push(slide);\n });\n\n // If there aren't enough preview images to fill the last slide, empty space is added to compensate.\n while (slidesGroups[slidesGroups.length - 1].length < slidesNumber) {\n slidesGroups[slidesGroups.length - 1].push(null);\n }\n setSlidesGroups([slidesGroups[slidesGroups.length - 1], ...slidesGroups]);\n setTransition(-100 / (slidesGroups.length + 1));\n }, []);\n\n useEffect(() => {\n if (transitionDuration === 0) {\n setTransitionDuration(0.3);\n }\n }, [transitionDuration]);\n\n // Avoid handleTransitionEnd when initializing the carousel\n useEffect(() => {\n setIsInitialized(true);\n }, [transition]);\n\n return {\n currentSlide,\n slidesNumber,\n slidesGroups,\n setSlidesNumber,\n transition,\n transitionDuration,\n previous,\n next,\n handleTransitionEnd,\n };\n}\n\nexport default useCarousel;\n","/home/aureen/the_odin_project/room/src/components/shop/display/ImageMagnifier.jsx",[],{"ruleId":"1423","replacedBy":"1424"},{"ruleId":"1425","replacedBy":"1426"},{"ruleId":"1427","replacedBy":"1428"},{"ruleId":"1429","replacedBy":"1430"},{"ruleId":"1431","replacedBy":"1432"},{"ruleId":"1433","severity":2,"message":"1434","line":1,"column":1,"nodeType":"1435","endLine":11,"endColumn":3},{"ruleId":"1436","severity":2,"message":"1437","line":5,"column":23,"nodeType":null,"endLine":5,"endColumn":26,"fix":"1438"},{"ruleId":"1439","severity":2,"message":"1440","line":8,"column":16,"nodeType":"1441","messageId":"1442","endLine":8,"endColumn":26},{"ruleId":"1436","severity":2,"message":"1443","line":14,"column":9,"nodeType":null,"endLine":14,"endColumn":20,"fix":"1444"},{"ruleId":"1445","severity":2,"message":"1446","line":16,"column":10,"nodeType":"1447","messageId":"1448","endLine":18,"endColumn":4,"fix":"1449"},{"ruleId":"1436","severity":2,"message":"1450","line":17,"column":16,"nodeType":null,"endLine":17,"endColumn":16,"fix":"1451"},{"ruleId":"1452","severity":2,"message":"1453","line":39,"column":7,"nodeType":"1454","messageId":"1455","endLine":39,"endColumn":69},{"ruleId":"1452","severity":2,"message":"1453","line":20,"column":5,"nodeType":"1454","messageId":"1455","endLine":22,"endColumn":34},{"ruleId":"1456","severity":2,"message":"1457","line":111,"column":34,"nodeType":"1441","messageId":"1458","endLine":111,"endColumn":38},{"ruleId":"1456","severity":2,"message":"1457","line":114,"column":8,"nodeType":"1441","messageId":"1458","endLine":114,"endColumn":12},{"ruleId":"1459","severity":2,"message":"1460","line":42,"column":5,"nodeType":"1461","messageId":"1462","endLine":57,"endColumn":10},{"ruleId":"1463","severity":2,"message":"1464","line":87,"column":5,"nodeType":"1465","messageId":"1466","endLine":89,"endColumn":6},{"ruleId":"1456","severity":2,"message":"1467","line":31,"column":5,"nodeType":"1441","messageId":"1458","endLine":31,"endColumn":14},{"ruleId":"1456","severity":2,"message":"1468","line":32,"column":5,"nodeType":"1441","messageId":"1458","endLine":32,"endColumn":13},{"ruleId":"1456","severity":2,"message":"1469","line":33,"column":5,"nodeType":"1441","messageId":"1458","endLine":33,"endColumn":12},{"ruleId":"1456","severity":2,"message":"1470","line":34,"column":5,"nodeType":"1441","messageId":"1458","endLine":34,"endColumn":12},{"ruleId":"1456","severity":2,"message":"1471","line":35,"column":5,"nodeType":"1441","messageId":"1458","endLine":35,"endColumn":9},{"ruleId":"1456","severity":2,"message":"1472","line":36,"column":5,"nodeType":"1441","messageId":"1458","endLine":36,"endColumn":12},{"ruleId":"1456","severity":2,"message":"1473","line":37,"column":5,"nodeType":"1441","messageId":"1458","endLine":37,"endColumn":10},{"ruleId":"1456","severity":2,"message":"1474","line":38,"column":5,"nodeType":"1441","messageId":"1458","endLine":38,"endColumn":10},{"ruleId":"1456","severity":2,"message":"1469","line":93,"column":31,"nodeType":"1441","messageId":"1458","endLine":93,"endColumn":38},{"ruleId":"1456","severity":2,"message":"1467","line":108,"column":5,"nodeType":"1441","messageId":"1458","endLine":108,"endColumn":14},{"ruleId":"1456","severity":2,"message":"1468","line":109,"column":5,"nodeType":"1441","messageId":"1458","endLine":109,"endColumn":13},{"ruleId":"1456","severity":2,"message":"1469","line":110,"column":5,"nodeType":"1441","messageId":"1458","endLine":110,"endColumn":12},{"ruleId":"1456","severity":2,"message":"1470","line":111,"column":5,"nodeType":"1441","messageId":"1458","endLine":111,"endColumn":12},{"ruleId":"1456","severity":2,"message":"1471","line":112,"column":5,"nodeType":"1441","messageId":"1458","endLine":112,"endColumn":9},{"ruleId":"1456","severity":2,"message":"1472","line":113,"column":5,"nodeType":"1441","messageId":"1458","endLine":113,"endColumn":12},{"ruleId":"1456","severity":2,"message":"1473","line":114,"column":5,"nodeType":"1441","messageId":"1458","endLine":114,"endColumn":10},{"ruleId":"1456","severity":2,"message":"1474","line":115,"column":5,"nodeType":"1441","messageId":"1458","endLine":115,"endColumn":10},{"ruleId":"1436","severity":2,"message":"1475","line":155,"column":1,"nodeType":null,"endLine":156,"endColumn":1,"fix":"1476"},{"ruleId":"1456","severity":2,"message":"1469","line":174,"column":24,"nodeType":"1441","messageId":"1458","endLine":174,"endColumn":31},{"ruleId":"1456","severity":2,"message":"1477","line":21,"column":34,"nodeType":"1441","messageId":"1458","endLine":21,"endColumn":38},{"ruleId":"1456","severity":2,"message":"1478","line":21,"column":40,"nodeType":"1441","messageId":"1458","endLine":21,"endColumn":46},{"ruleId":"1456","severity":2,"message":"1479","line":21,"column":48,"nodeType":"1441","messageId":"1458","endLine":21,"endColumn":52},{"ruleId":"1456","severity":2,"message":"1480","line":21,"column":54,"nodeType":"1441","messageId":"1458","endLine":21,"endColumn":57},{"ruleId":"1439","severity":2,"message":"1481","line":89,"column":13,"nodeType":"1441","messageId":"1442","endLine":89,"endColumn":21},{"ruleId":"1456","severity":2,"message":"1477","line":96,"column":33,"nodeType":"1441","messageId":"1458","endLine":96,"endColumn":37},{"ruleId":"1456","severity":2,"message":"1478","line":96,"column":39,"nodeType":"1441","messageId":"1458","endLine":96,"endColumn":45},{"ruleId":"1456","severity":2,"message":"1479","line":96,"column":47,"nodeType":"1441","messageId":"1458","endLine":96,"endColumn":51},{"ruleId":"1456","severity":2,"message":"1480","line":96,"column":53,"nodeType":"1441","messageId":"1458","endLine":96,"endColumn":56},{"ruleId":"1456","severity":2,"message":"1482","line":38,"column":15,"nodeType":"1441","messageId":"1458","endLine":38,"endColumn":21},{"ruleId":"1456","severity":2,"message":"1482","line":47,"column":15,"nodeType":"1441","messageId":"1458","endLine":47,"endColumn":21},{"ruleId":"1456","severity":2,"message":"1483","line":60,"column":11,"nodeType":"1441","messageId":"1458","endLine":60,"endColumn":23},{"ruleId":"1452","severity":2,"message":"1453","line":62,"column":7,"nodeType":"1454","messageId":"1455","endLine":64,"endColumn":61},{"ruleId":"1436","severity":2,"message":"1484","line":74,"column":3,"nodeType":null,"endLine":74,"endColumn":3,"fix":"1485"},{"ruleId":"1456","severity":2,"message":"1486","line":49,"column":11,"nodeType":"1441","messageId":"1458","endLine":49,"endColumn":20},{"ruleId":"1456","severity":2,"message":"1486","line":62,"column":15,"nodeType":"1441","messageId":"1458","endLine":62,"endColumn":24},{"ruleId":"1463","severity":2,"message":"1464","line":64,"column":9,"nodeType":"1465","messageId":"1466","endLine":66,"endColumn":10},{"ruleId":"1459","severity":2,"message":"1487","line":69,"column":5,"nodeType":"1461","messageId":"1462","endLine":69,"endColumn":24},{"ruleId":"1436","severity":2,"message":"1475","line":128,"column":1,"nodeType":null,"endLine":129,"endColumn":1,"fix":"1488"},{"ruleId":"1489","severity":2,"message":"1490","line":27,"column":22,"nodeType":"1491"},{"ruleId":"1492","severity":2,"message":"1493","line":57,"column":60,"nodeType":"1494","endLine":57,"endColumn":70},{"ruleId":"1456","severity":2,"message":"1495","line":35,"column":13,"nodeType":"1441","messageId":"1458","endLine":35,"endColumn":17},{"ruleId":"1456","severity":2,"message":"1495","line":43,"column":13,"nodeType":"1441","messageId":"1458","endLine":43,"endColumn":17},{"ruleId":"1459","severity":2,"message":"1487","line":46,"column":5,"nodeType":"1461","messageId":"1462","endLine":46,"endColumn":24},{"ruleId":"1456","severity":2,"message":"1495","line":50,"column":23,"nodeType":"1441","messageId":"1458","endLine":50,"endColumn":27},{"ruleId":"1456","severity":2,"message":"1495","line":102,"column":22,"nodeType":"1441","messageId":"1458","endLine":102,"endColumn":26},{"ruleId":"1456","severity":2,"message":"1496","line":102,"column":28,"nodeType":"1441","messageId":"1458","endLine":102,"endColumn":39},{"ruleId":"1489","severity":2,"message":"1490","line":158,"column":29,"nodeType":"1491"},{"ruleId":"1463","severity":2,"message":"1464","line":19,"column":7,"nodeType":"1465","messageId":"1466","endLine":22,"endColumn":8},{"ruleId":"1497","severity":2,"message":"1498","line":20,"column":22,"nodeType":"1499","messageId":"1500","endLine":20,"endColumn":45},{"ruleId":"1489","severity":2,"message":"1490","line":35,"column":38,"nodeType":"1491"},{"ruleId":"1452","severity":2,"message":"1453","line":14,"column":5,"nodeType":"1454","messageId":"1455","endLine":16,"endColumn":28},{"ruleId":"1439","severity":2,"message":"1501","line":24,"column":22,"nodeType":"1441","messageId":"1442","endLine":24,"endColumn":28},{"ruleId":"1456","severity":2,"message":"1502","line":48,"column":15,"nodeType":"1441","messageId":"1458","endLine":48,"endColumn":21},{"ruleId":"1456","severity":2,"message":"1502","line":57,"column":15,"nodeType":"1441","messageId":"1458","endLine":57,"endColumn":21},{"ruleId":"1503","severity":2,"message":"1504","line":84,"column":34,"nodeType":"1441","endLine":84,"endColumn":39},{"ruleId":"1436","severity":2,"message":"1475","line":137,"column":1,"nodeType":null,"endLine":138,"endColumn":1,"fix":"1505"},{"ruleId":"1506","severity":2,"message":"1507","line":6,"column":24,"nodeType":"1508","endLine":6,"endColumn":44},{"ruleId":"1492","severity":2,"message":"1493","line":11,"column":7,"nodeType":"1494","endLine":11,"endColumn":16},{"ruleId":"1492","severity":2,"message":"1493","line":16,"column":22,"nodeType":"1494","endLine":16,"endColumn":32},{"ruleId":"1506","severity":2,"message":"1507","line":6,"column":25,"nodeType":"1508","endLine":6,"endColumn":45},{"ruleId":"1492","severity":2,"message":"1493","line":11,"column":7,"nodeType":"1494","endLine":11,"endColumn":16},{"ruleId":"1492","severity":2,"message":"1493","line":14,"column":22,"nodeType":"1494","endLine":14,"endColumn":32},{"ruleId":"1456","severity":2,"message":"1509","line":16,"column":11,"nodeType":"1441","messageId":"1458","endLine":16,"endColumn":16},{"ruleId":"1452","severity":2,"message":"1453","line":17,"column":5,"nodeType":"1454","messageId":"1455","endLine":19,"endColumn":60},{"ruleId":"1456","severity":2,"message":"1510","line":45,"column":17,"nodeType":"1441","messageId":"1458","endLine":45,"endColumn":24},{"ruleId":"1456","severity":2,"message":"1511","line":51,"column":23,"nodeType":"1441","messageId":"1458","endLine":51,"endColumn":27},{"ruleId":"1456","severity":2,"message":"1512","line":57,"column":9,"nodeType":"1441","messageId":"1458","endLine":57,"endColumn":23},{"ruleId":"1456","severity":2,"message":"1513","line":13,"column":13,"nodeType":"1441","messageId":"1458","endLine":13,"endColumn":20},{"ruleId":"1489","severity":2,"message":"1490","line":25,"column":58,"nodeType":"1491"},{"ruleId":"1489","severity":2,"message":"1490","line":27,"column":72,"nodeType":"1491"},{"ruleId":"1489","severity":2,"message":"1490","line":42,"column":19,"nodeType":"1491"},{"ruleId":"1452","severity":2,"message":"1453","line":51,"column":5,"nodeType":"1454","messageId":"1455","endLine":53,"endColumn":33},{"ruleId":"1456","severity":2,"message":"1514","line":60,"column":13,"nodeType":"1441","messageId":"1458","endLine":60,"endColumn":17},{"ruleId":"1463","severity":2,"message":"1464","line":75,"column":7,"nodeType":"1465","messageId":"1466","endLine":77,"endColumn":8},{"ruleId":"1456","severity":2,"message":"1515","line":118,"column":14,"nodeType":"1441","messageId":"1458","endLine":118,"endColumn":15},{"ruleId":"1456","severity":2,"message":"1516","line":129,"column":13,"nodeType":"1441","messageId":"1458","endLine":129,"endColumn":28},{"ruleId":"1517","severity":2,"message":"1518","line":179,"column":22,"nodeType":"1491","endLine":179,"endColumn":23,"fix":"1519"},{"ruleId":"1517","severity":2,"message":"1520","line":179,"column":23,"nodeType":"1521","endLine":179,"endColumn":37,"fix":"1522"},{"ruleId":"1503","severity":2,"message":"1504","line":182,"column":34,"nodeType":"1523","endLine":182,"endColumn":55},{"ruleId":"1517","severity":2,"message":"1524","line":189,"column":28,"nodeType":"1521","endLine":189,"endColumn":54,"fix":"1525"},{"ruleId":"1517","severity":2,"message":"1526","line":218,"column":36,"nodeType":"1521","endLine":218,"endColumn":44,"fix":"1527"},{"ruleId":"1517","severity":2,"message":"1528","line":218,"column":44,"nodeType":"1491","endLine":218,"endColumn":46,"fix":"1529"},{"ruleId":"1530","severity":2,"message":"1531","line":247,"column":35,"nodeType":"1532","messageId":"1533","endLine":247,"endColumn":36,"fix":"1534"},{"ruleId":"1456","severity":2,"message":"1535","line":268,"column":31,"nodeType":"1441","messageId":"1458","endLine":268,"endColumn":39},{"ruleId":"1517","severity":2,"message":"1536","line":310,"column":48,"nodeType":"1521","endLine":310,"endColumn":59,"fix":"1537"},{"ruleId":"1517","severity":2,"message":"1528","line":310,"column":59,"nodeType":"1491","endLine":310,"endColumn":61,"fix":"1538"},{"ruleId":"1517","severity":2,"message":"1539","line":328,"column":50,"nodeType":"1521","endLine":328,"endColumn":56,"fix":"1540"},{"ruleId":"1517","severity":2,"message":"1528","line":328,"column":56,"nodeType":"1491","endLine":328,"endColumn":58,"fix":"1541"},{"ruleId":"1456","severity":2,"message":"1542","line":18,"column":13,"nodeType":"1441","messageId":"1458","endLine":18,"endColumn":19},{"ruleId":"1456","severity":2,"message":"1543","line":21,"column":13,"nodeType":"1441","messageId":"1458","endLine":21,"endColumn":18},{"ruleId":"1463","severity":2,"message":"1464","line":22,"column":7,"nodeType":"1465","messageId":"1466","endLine":25,"endColumn":8},{"ruleId":"1497","severity":2,"message":"1498","line":23,"column":22,"nodeType":"1499","messageId":"1500","endLine":23,"endColumn":43},{"ruleId":"1456","severity":2,"message":"1544","line":41,"column":17,"nodeType":"1441","messageId":"1458","endLine":41,"endColumn":24},{"ruleId":"1456","severity":2,"message":"1545","line":47,"column":23,"nodeType":"1441","messageId":"1458","endLine":47,"endColumn":27},{"ruleId":"1456","severity":2,"message":"1546","line":53,"column":9,"nodeType":"1441","messageId":"1458","endLine":53,"endColumn":23},{"ruleId":"1456","severity":2,"message":"1547","line":40,"column":13,"nodeType":"1441","messageId":"1458","endLine":40,"endColumn":18},{"ruleId":"1436","severity":2,"message":"1475","line":88,"column":56,"nodeType":null,"endLine":89,"endColumn":1,"fix":"1548"},{"ruleId":"1549","severity":2,"message":"1550","line":89,"column":1,"nodeType":"1521","endLine":89,"endColumn":6,"fix":"1551"},{"ruleId":"1436","severity":2,"message":"1475","line":94,"column":54,"nodeType":null,"endLine":95,"endColumn":1,"fix":"1552"},{"ruleId":"1549","severity":2,"message":"1550","line":95,"column":1,"nodeType":"1521","endLine":95,"endColumn":6,"fix":"1553"},{"ruleId":"1436","severity":2,"message":"1554","line":113,"column":59,"nodeType":null,"endLine":115,"endColumn":1,"fix":"1555"},{"ruleId":"1549","severity":2,"message":"1556","line":114,"column":1,"nodeType":"1521","endLine":114,"endColumn":6,"fix":"1557"},{"ruleId":"1549","severity":2,"message":"1556","line":114,"column":6,"nodeType":"1491","endLine":115,"endColumn":2,"fix":"1558"},{"ruleId":"1517","severity":2,"message":"1559","line":115,"column":2,"nodeType":"1521","endLine":115,"endColumn":7,"fix":"1560"},{"ruleId":"1456","severity":2,"message":"1561","line":174,"column":33,"nodeType":"1441","messageId":"1458","endLine":174,"endColumn":39},{"ruleId":"1456","severity":2,"message":"1562","line":199,"column":33,"nodeType":"1441","messageId":"1458","endLine":199,"endColumn":36},{"ruleId":"1456","severity":2,"message":"1563","line":51,"column":13,"nodeType":"1441","messageId":"1458","endLine":51,"endColumn":22},{"ruleId":"1456","severity":2,"message":"1564","line":95,"column":37,"nodeType":"1441","messageId":"1458","endLine":95,"endColumn":44},{"ruleId":"1517","severity":2,"message":"1565","line":99,"column":49,"nodeType":"1521","endLine":99,"endColumn":67,"fix":"1566"},{"ruleId":"1517","severity":2,"message":"1567","line":103,"column":47,"nodeType":"1521","endLine":103,"endColumn":61,"fix":"1568"},{"ruleId":"1456","severity":2,"message":"1509","line":15,"column":13,"nodeType":"1441","messageId":"1458","endLine":15,"endColumn":18},{"ruleId":"1517","severity":2,"message":"1569","line":36,"column":44,"nodeType":"1521","endLine":36,"endColumn":69,"fix":"1570"},{"ruleId":"1517","severity":2,"message":"1571","line":40,"column":42,"nodeType":"1521","endLine":40,"endColumn":63,"fix":"1572"},{"ruleId":"1436","severity":2,"message":"1573","line":52,"column":49,"nodeType":null,"endLine":54,"endColumn":46,"fix":"1574"},{"ruleId":"1436","severity":2,"message":"1575","line":55,"column":1,"nodeType":null,"endLine":55,"endColumn":3,"fix":"1576"},{"ruleId":"1577","severity":2,"message":"1578","line":55,"column":15,"nodeType":"1579","endLine":55,"endColumn":19,"fix":"1580"},{"ruleId":"1549","severity":2,"message":"1581","line":55,"column":15,"nodeType":"1579","endLine":55,"endColumn":19,"fix":"1582"},{"ruleId":"1489","severity":2,"message":"1490","line":58,"column":40,"nodeType":"1491"},{"ruleId":"1517","severity":2,"message":"1559","line":58,"column":67,"nodeType":"1521","endLine":58,"endColumn":72,"fix":"1583"},{"ruleId":"1517","severity":2,"message":"1559","line":62,"column":62,"nodeType":"1521","endLine":62,"endColumn":67,"fix":"1584"},{"ruleId":"1456","severity":2,"message":"1585","line":14,"column":13,"nodeType":"1441","messageId":"1458","endLine":14,"endColumn":19},{"ruleId":"1586","severity":2,"message":"1587","line":7,"column":17,"nodeType":"1441","messageId":"1588","endLine":7,"endColumn":25},{"ruleId":"1456","severity":2,"message":"1589","line":63,"column":13,"nodeType":"1441","messageId":"1458","endLine":63,"endColumn":22},{"ruleId":"1452","severity":2,"message":"1453","line":67,"column":7,"nodeType":"1454","messageId":"1455","endLine":67,"endColumn":57},{"ruleId":"1456","severity":2,"message":"1589","line":73,"column":13,"nodeType":"1441","messageId":"1458","endLine":73,"endColumn":22},{"ruleId":"1456","severity":2,"message":"1590","line":91,"column":29,"nodeType":"1441","messageId":"1458","endLine":91,"endColumn":36},{"ruleId":"1517","severity":2,"message":"1565","line":96,"column":43,"nodeType":"1521","endLine":96,"endColumn":61,"fix":"1591"},{"ruleId":"1517","severity":2,"message":"1567","line":100,"column":41,"nodeType":"1521","endLine":100,"endColumn":55,"fix":"1592"},{"ruleId":"1530","severity":2,"message":"1531","line":111,"column":25,"nodeType":"1532","messageId":"1533","endLine":111,"endColumn":26,"fix":"1593"},{"ruleId":"1456","severity":2,"message":"1594","line":47,"column":13,"nodeType":"1441","messageId":"1458","endLine":47,"endColumn":18},{"ruleId":"1456","severity":2,"message":"1594","line":55,"column":13,"nodeType":"1441","messageId":"1458","endLine":55,"endColumn":18},{"ruleId":"1517","severity":2,"message":"1595","line":78,"column":26,"nodeType":"1521","endLine":78,"endColumn":49,"fix":"1596"},{"ruleId":"1436","severity":2,"message":"1597","line":78,"column":49,"nodeType":null,"endLine":81,"endColumn":1,"fix":"1598"},{"ruleId":"1549","severity":2,"message":"1599","line":79,"column":1,"nodeType":"1521","endLine":79,"endColumn":6,"fix":"1600"},{"ruleId":"1549","severity":2,"message":"1599","line":79,"column":6,"nodeType":"1491","endLine":81,"endColumn":1,"fix":"1601"},{"ruleId":"1577","severity":2,"message":"1578","line":81,"column":1,"nodeType":"1579","endLine":81,"endColumn":7,"fix":"1602"},{"ruleId":"1549","severity":2,"message":"1550","line":81,"column":1,"nodeType":"1579","endLine":81,"endColumn":7,"fix":"1603"},{"ruleId":"1456","severity":2,"message":"1604","line":133,"column":37,"nodeType":"1441","messageId":"1458","endLine":133,"endColumn":43},{"ruleId":"1456","severity":2,"message":"1605","line":161,"column":37,"nodeType":"1441","messageId":"1458","endLine":161,"endColumn":40},{"ruleId":"1456","severity":2,"message":"1604","line":215,"column":25,"nodeType":"1441","messageId":"1458","endLine":215,"endColumn":31},{"ruleId":"1456","severity":2,"message":"1605","line":241,"column":23,"nodeType":"1441","messageId":"1458","endLine":241,"endColumn":26},{"ruleId":"1456","severity":2,"message":"1606","line":17,"column":13,"nodeType":"1441","messageId":"1458","endLine":17,"endColumn":23},{"ruleId":"1456","severity":2,"message":"1607","line":32,"column":13,"nodeType":"1441","messageId":"1458","endLine":32,"endColumn":17},{"ruleId":"1456","severity":2,"message":"1607","line":40,"column":13,"nodeType":"1441","messageId":"1458","endLine":40,"endColumn":17},{"ruleId":"1459","severity":2,"message":"1487","line":43,"column":5,"nodeType":"1461","messageId":"1462","endLine":43,"endColumn":24},{"ruleId":"1436","severity":2,"message":"1475","line":111,"column":1,"nodeType":null,"endLine":112,"endColumn":1,"fix":"1608"},{"ruleId":"1489","severity":2,"message":"1490","line":27,"column":25,"nodeType":"1491"},{"ruleId":"1436","severity":2,"message":"1475","line":66,"column":1,"nodeType":null,"endLine":67,"endColumn":1,"fix":"1609"},{"ruleId":"1517","severity":2,"message":"1559","line":81,"column":26,"nodeType":"1521","endLine":81,"endColumn":31,"fix":"1610"},{"ruleId":"1517","severity":2,"message":"1611","line":84,"column":66,"nodeType":"1491","endLine":85,"endColumn":11,"fix":"1612"},{"ruleId":"1517","severity":2,"message":"1611","line":88,"column":51,"nodeType":"1491","endLine":89,"endColumn":11,"fix":"1613"},{"ruleId":"1506","severity":2,"message":"1614","line":9,"column":19,"nodeType":"1508","endLine":9,"endColumn":23},{"ruleId":"1506","severity":2,"message":"1615","line":9,"column":25,"nodeType":"1508","endLine":9,"endColumn":33},{"ruleId":"1452","severity":2,"message":"1453","line":41,"column":11,"nodeType":"1454","messageId":"1455","endLine":41,"endColumn":77},{"ruleId":"1489","severity":2,"message":"1490","line":88,"column":42,"nodeType":"1491"},{"ruleId":"1517","severity":2,"message":"1559","line":104,"column":33,"nodeType":"1521","endLine":104,"endColumn":38,"fix":"1616"},{"ruleId":"1452","severity":2,"message":"1453","line":19,"column":5,"nodeType":"1454","messageId":"1455","endLine":19,"endColumn":69},{"ruleId":"1452","severity":2,"message":"1453","line":29,"column":5,"nodeType":"1454","messageId":"1455","endLine":29,"endColumn":71},{"ruleId":"1517","severity":2,"message":"1518","line":49,"column":18,"nodeType":"1491","endLine":49,"endColumn":19,"fix":"1617"},{"ruleId":"1517","severity":2,"message":"1618","line":49,"column":19,"nodeType":"1521","endLine":49,"endColumn":26,"fix":"1619"},{"ruleId":"1436","severity":2,"message":"1475","line":75,"column":1,"nodeType":null,"endLine":76,"endColumn":1,"fix":"1620"},{"ruleId":"1463","severity":2,"message":"1464","line":71,"column":5,"nodeType":"1465","messageId":"1466","endLine":74,"endColumn":6},{"ruleId":"1497","severity":2,"message":"1498","line":72,"column":24,"nodeType":"1499","messageId":"1500","endLine":72,"endColumn":60},{"ruleId":"1463","severity":2,"message":"1464","line":77,"column":5,"nodeType":"1465","messageId":"1466","endLine":80,"endColumn":6},{"ruleId":"1497","severity":2,"message":"1498","line":78,"column":29,"nodeType":"1499","messageId":"1500","endLine":78,"endColumn":71},{"ruleId":"1463","severity":2,"message":"1464","line":85,"column":5,"nodeType":"1465","messageId":"1466","endLine":89,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":100,"column":5,"nodeType":"1465","messageId":"1466","endLine":108,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":115,"column":5,"nodeType":"1465","messageId":"1466","endLine":117,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":121,"column":5,"nodeType":"1465","messageId":"1466","endLine":123,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":124,"column":5,"nodeType":"1465","messageId":"1466","endLine":126,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":127,"column":5,"nodeType":"1465","messageId":"1466","endLine":129,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":141,"column":5,"nodeType":"1465","messageId":"1466","endLine":150,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":142,"column":7,"nodeType":"1465","messageId":"1466","endLine":149,"endColumn":8},{"ruleId":"1463","severity":2,"message":"1464","line":168,"column":5,"nodeType":"1465","messageId":"1466","endLine":189,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":169,"column":7,"nodeType":"1465","messageId":"1466","endLine":188,"endColumn":8},{"ruleId":"1456","severity":2,"message":"1621","line":212,"column":14,"nodeType":"1441","messageId":"1458","endLine":212,"endColumn":15},{"ruleId":"1463","severity":2,"message":"1464","line":224,"column":5,"nodeType":"1465","messageId":"1466","endLine":226,"endColumn":6},{"ruleId":"1530","severity":2,"message":"1531","line":285,"column":15,"nodeType":"1532","messageId":"1533","endLine":285,"endColumn":16,"fix":"1622"},{"ruleId":"1530","severity":2,"message":"1531","line":298,"column":15,"nodeType":"1532","messageId":"1533","endLine":298,"endColumn":16,"fix":"1623"},{"ruleId":"1530","severity":2,"message":"1531","line":311,"column":15,"nodeType":"1532","messageId":"1533","endLine":311,"endColumn":16,"fix":"1624"},{"ruleId":"1517","severity":2,"message":"1625","line":333,"column":32,"nodeType":"1521","endLine":333,"endColumn":43,"fix":"1626"},{"ruleId":"1456","severity":2,"message":"1627","line":343,"column":33,"nodeType":"1441","messageId":"1458","endLine":343,"endColumn":42},{"ruleId":"1530","severity":2,"message":"1531","line":347,"column":23,"nodeType":"1532","messageId":"1533","endLine":347,"endColumn":24,"fix":"1628"},{"ruleId":"1456","severity":2,"message":"1627","line":355,"column":31,"nodeType":"1441","messageId":"1458","endLine":355,"endColumn":40},{"ruleId":"1530","severity":2,"message":"1531","line":359,"column":21,"nodeType":"1532","messageId":"1533","endLine":359,"endColumn":22,"fix":"1629"},{"ruleId":"1456","severity":2,"message":"1630","line":381,"column":29,"nodeType":"1441","messageId":"1458","endLine":381,"endColumn":40},{"ruleId":"1517","severity":2,"message":"1625","line":385,"column":29,"nodeType":"1521","endLine":385,"endColumn":40,"fix":"1631"},{"ruleId":"1456","severity":2,"message":"1632","line":398,"column":31,"nodeType":"1441","messageId":"1458","endLine":398,"endColumn":42},{"ruleId":"1530","severity":2,"message":"1531","line":402,"column":21,"nodeType":"1532","messageId":"1533","endLine":402,"endColumn":22,"fix":"1633"},{"ruleId":"1456","severity":2,"message":"1632","line":409,"column":31,"nodeType":"1441","messageId":"1458","endLine":409,"endColumn":42},{"ruleId":"1530","severity":2,"message":"1531","line":413,"column":21,"nodeType":"1532","messageId":"1533","endLine":413,"endColumn":22,"fix":"1634"},{"ruleId":"1530","severity":2,"message":"1531","line":434,"column":15,"nodeType":"1532","messageId":"1533","endLine":434,"endColumn":16,"fix":"1635"},{"ruleId":"1456","severity":2,"message":"1636","line":455,"column":33,"nodeType":"1441","messageId":"1458","endLine":455,"endColumn":39},{"ruleId":"1530","severity":2,"message":"1531","line":459,"column":23,"nodeType":"1532","messageId":"1533","endLine":459,"endColumn":24,"fix":"1637"},{"ruleId":"1456","severity":2,"message":"1636","line":472,"column":33,"nodeType":"1441","messageId":"1458","endLine":472,"endColumn":39},{"ruleId":"1530","severity":2,"message":"1531","line":476,"column":23,"nodeType":"1532","messageId":"1533","endLine":476,"endColumn":24,"fix":"1638"},{"ruleId":"1456","severity":2,"message":"1636","line":487,"column":33,"nodeType":"1441","messageId":"1458","endLine":487,"endColumn":39},{"ruleId":"1530","severity":2,"message":"1531","line":491,"column":23,"nodeType":"1532","messageId":"1533","endLine":491,"endColumn":24,"fix":"1639"},{"ruleId":"1456","severity":2,"message":"1636","line":503,"column":31,"nodeType":"1441","messageId":"1458","endLine":503,"endColumn":37},{"ruleId":"1640","severity":2,"message":"1641","line":504,"column":25,"nodeType":"1642","messageId":"1643","endLine":504,"endColumn":64},{"ruleId":"1456","severity":2,"message":"1636","line":515,"column":31,"nodeType":"1441","messageId":"1458","endLine":515,"endColumn":37},{"ruleId":"1530","severity":2,"message":"1531","line":519,"column":21,"nodeType":"1532","messageId":"1533","endLine":519,"endColumn":22,"fix":"1644"},{"ruleId":"1517","severity":2,"message":"1625","line":545,"column":30,"nodeType":"1521","endLine":545,"endColumn":41,"fix":"1645"},{"ruleId":"1456","severity":2,"message":"1646","line":554,"column":31,"nodeType":"1441","messageId":"1458","endLine":554,"endColumn":41},{"ruleId":"1530","severity":2,"message":"1531","line":558,"column":21,"nodeType":"1532","messageId":"1533","endLine":558,"endColumn":22,"fix":"1647"},{"ruleId":"1456","severity":2,"message":"1646","line":566,"column":29,"nodeType":"1441","messageId":"1458","endLine":566,"endColumn":39},{"ruleId":"1530","severity":2,"message":"1531","line":570,"column":19,"nodeType":"1532","messageId":"1533","endLine":570,"endColumn":20,"fix":"1648"},{"ruleId":"1530","severity":2,"message":"1531","line":603,"column":15,"nodeType":"1532","messageId":"1533","endLine":603,"endColumn":16,"fix":"1649"},{"ruleId":"1456","severity":2,"message":"1650","line":625,"column":35,"nodeType":"1441","messageId":"1458","endLine":625,"endColumn":42},{"ruleId":"1530","severity":2,"message":"1531","line":629,"column":25,"nodeType":"1532","messageId":"1533","endLine":629,"endColumn":26,"fix":"1651"},{"ruleId":"1456","severity":2,"message":"1650","line":637,"column":35,"nodeType":"1441","messageId":"1458","endLine":637,"endColumn":42},{"ruleId":"1530","severity":2,"message":"1531","line":641,"column":25,"nodeType":"1532","messageId":"1533","endLine":641,"endColumn":26,"fix":"1652"},{"ruleId":"1456","severity":2,"message":"1650","line":679,"column":39,"nodeType":"1441","messageId":"1458","endLine":679,"endColumn":46},{"ruleId":"1530","severity":2,"message":"1531","line":685,"column":29,"nodeType":"1532","messageId":"1533","endLine":685,"endColumn":30,"fix":"1653"},{"ruleId":"1456","severity":2,"message":"1650","line":708,"column":39,"nodeType":"1441","messageId":"1458","endLine":708,"endColumn":46},{"ruleId":"1530","severity":2,"message":"1531","line":714,"column":29,"nodeType":"1532","messageId":"1533","endLine":714,"endColumn":30,"fix":"1654"},{"ruleId":"1456","severity":2,"message":"1650","line":738,"column":39,"nodeType":"1441","messageId":"1458","endLine":738,"endColumn":46},{"ruleId":"1530","severity":2,"message":"1531","line":744,"column":29,"nodeType":"1532","messageId":"1533","endLine":744,"endColumn":30,"fix":"1655"},{"ruleId":"1456","severity":2,"message":"1650","line":767,"column":39,"nodeType":"1441","messageId":"1458","endLine":767,"endColumn":46},{"ruleId":"1530","severity":2,"message":"1531","line":773,"column":29,"nodeType":"1532","messageId":"1533","endLine":773,"endColumn":30,"fix":"1656"},{"ruleId":"1456","severity":2,"message":"1650","line":796,"column":39,"nodeType":"1441","messageId":"1458","endLine":796,"endColumn":46},{"ruleId":"1530","severity":2,"message":"1531","line":802,"column":29,"nodeType":"1532","messageId":"1533","endLine":802,"endColumn":30,"fix":"1657"},{"ruleId":"1530","severity":2,"message":"1531","line":857,"column":13,"nodeType":"1532","messageId":"1533","endLine":857,"endColumn":14,"fix":"1658"},{"ruleId":"1456","severity":2,"message":"1659","line":876,"column":31,"nodeType":"1441","messageId":"1458","endLine":876,"endColumn":41},{"ruleId":"1530","severity":2,"message":"1531","line":880,"column":21,"nodeType":"1532","messageId":"1533","endLine":880,"endColumn":22,"fix":"1660"},{"ruleId":"1456","severity":2,"message":"1659","line":896,"column":33,"nodeType":"1441","messageId":"1458","endLine":896,"endColumn":43},{"ruleId":"1530","severity":2,"message":"1531","line":900,"column":23,"nodeType":"1532","messageId":"1533","endLine":900,"endColumn":24,"fix":"1661"},{"ruleId":"1456","severity":2,"message":"1659","line":909,"column":29,"nodeType":"1441","messageId":"1458","endLine":909,"endColumn":39},{"ruleId":"1530","severity":2,"message":"1531","line":913,"column":19,"nodeType":"1532","messageId":"1533","endLine":913,"endColumn":20,"fix":"1662"},{"ruleId":"1517","severity":2,"message":"1625","line":941,"column":27,"nodeType":"1521","endLine":941,"endColumn":38,"fix":"1663"},{"ruleId":"1456","severity":2,"message":"1664","line":950,"column":31,"nodeType":"1441","messageId":"1458","endLine":950,"endColumn":36},{"ruleId":"1530","severity":2,"message":"1531","line":954,"column":21,"nodeType":"1532","messageId":"1533","endLine":954,"endColumn":22,"fix":"1665"},{"ruleId":"1456","severity":2,"message":"1664","line":962,"column":29,"nodeType":"1441","messageId":"1458","endLine":962,"endColumn":34},{"ruleId":"1530","severity":2,"message":"1531","line":966,"column":19,"nodeType":"1532","messageId":"1533","endLine":966,"endColumn":20,"fix":"1666"},{"ruleId":"1503","severity":2,"message":"1504","line":987,"column":29,"nodeType":"1523","endLine":987,"endColumn":47},{"ruleId":"1517","severity":2,"message":"1569","line":44,"column":40,"nodeType":"1521","endLine":44,"endColumn":65,"fix":"1667"},{"ruleId":"1517","severity":2,"message":"1569","line":72,"column":48,"nodeType":"1521","endLine":72,"endColumn":73,"fix":"1668"},{"ruleId":"1517","severity":2,"message":"1571","line":76,"column":46,"nodeType":"1521","endLine":76,"endColumn":67,"fix":"1669"},{"ruleId":"1517","severity":2,"message":"1670","line":86,"column":24,"nodeType":"1521","endLine":86,"endColumn":53,"fix":"1671"},{"ruleId":"1517","severity":2,"message":"1672","line":86,"column":53,"nodeType":"1491","endLine":86,"endColumn":69,"fix":"1673"},{"ruleId":"1436","severity":2,"message":"1475","line":122,"column":1,"nodeType":null,"endLine":123,"endColumn":1,"fix":"1674"},{"ruleId":"1463","severity":2,"message":"1464","line":47,"column":5,"nodeType":"1465","messageId":"1466","endLine":51,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":48,"column":7,"nodeType":"1465","messageId":"1466","endLine":50,"endColumn":8},{"ruleId":"1456","severity":2,"message":"1675","line":55,"column":11,"nodeType":"1441","messageId":"1458","endLine":55,"endColumn":21},{"ruleId":"1463","severity":2,"message":"1464","line":69,"column":5,"nodeType":"1465","messageId":"1466","endLine":88,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":98,"column":5,"nodeType":"1465","messageId":"1466","endLine":102,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":99,"column":7,"nodeType":"1465","messageId":"1466","endLine":101,"endColumn":8},{"ruleId":"1456","severity":2,"message":"1676","line":106,"column":11,"nodeType":"1441","messageId":"1458","endLine":106,"endColumn":16},{"ruleId":"1463","severity":2,"message":"1464","line":111,"column":5,"nodeType":"1465","messageId":"1466","endLine":116,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":122,"column":5,"nodeType":"1465","messageId":"1466","endLine":128,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":124,"column":9,"nodeType":"1465","messageId":"1466","endLine":126,"endColumn":10},{"ruleId":"1517","severity":2,"message":"1677","line":183,"column":17,"nodeType":"1678","endLine":183,"endColumn":31,"fix":"1679"},{"ruleId":"1517","severity":2,"message":"1680","line":188,"column":20,"nodeType":"1521","endLine":188,"endColumn":65,"fix":"1681"},{"ruleId":"1530","severity":2,"message":"1531","line":213,"column":23,"nodeType":"1532","messageId":"1533","endLine":213,"endColumn":24,"fix":"1682"},{"ruleId":"1517","severity":2,"message":"1683","line":237,"column":22,"nodeType":"1521","endLine":237,"endColumn":45,"fix":"1684"},{"ruleId":"1517","severity":2,"message":"1685","line":237,"column":45,"nodeType":"1491","endLine":237,"endColumn":48,"fix":"1686"},{"ruleId":"1517","severity":2,"message":"1687","line":237,"column":48,"nodeType":"1521","endLine":237,"endColumn":71,"fix":"1688"},{"ruleId":"1436","severity":2,"message":"1475","line":237,"column":71,"nodeType":null,"endLine":238,"endColumn":1,"fix":"1689"},{"ruleId":"1549","severity":2,"message":"1550","line":237,"column":71,"nodeType":"1491","endLine":239,"endColumn":1,"fix":"1690"},{"ruleId":"1436","severity":2,"message":"1691","line":239,"column":1,"nodeType":null,"endLine":239,"endColumn":1,"fix":"1692"},{"ruleId":"1577","severity":2,"message":"1578","line":239,"column":1,"nodeType":"1579","endLine":239,"endColumn":9,"fix":"1693"},{"ruleId":"1549","severity":2,"message":"1694","line":239,"column":1,"nodeType":"1579","endLine":239,"endColumn":9,"fix":"1695"},{"ruleId":"1530","severity":2,"message":"1531","line":251,"column":21,"nodeType":"1532","messageId":"1533","endLine":251,"endColumn":22,"fix":"1696"},{"ruleId":"1517","severity":2,"message":"1697","line":259,"column":22,"nodeType":"1521","endLine":259,"endColumn":44,"fix":"1698"},{"ruleId":"1517","severity":2,"message":"1685","line":259,"column":44,"nodeType":"1491","endLine":259,"endColumn":47,"fix":"1699"},{"ruleId":"1517","severity":2,"message":"1700","line":259,"column":47,"nodeType":"1521","endLine":259,"endColumn":69,"fix":"1701"},{"ruleId":"1436","severity":2,"message":"1475","line":259,"column":69,"nodeType":null,"endLine":260,"endColumn":1,"fix":"1702"},{"ruleId":"1549","severity":2,"message":"1550","line":259,"column":69,"nodeType":"1491","endLine":261,"endColumn":1,"fix":"1703"},{"ruleId":"1436","severity":2,"message":"1691","line":261,"column":1,"nodeType":null,"endLine":261,"endColumn":1,"fix":"1704"},{"ruleId":"1577","severity":2,"message":"1578","line":261,"column":1,"nodeType":"1579","endLine":261,"endColumn":9,"fix":"1705"},{"ruleId":"1549","severity":2,"message":"1694","line":261,"column":1,"nodeType":"1579","endLine":261,"endColumn":9,"fix":"1706"},{"ruleId":"1530","severity":2,"message":"1531","line":273,"column":21,"nodeType":"1532","messageId":"1533","endLine":273,"endColumn":22,"fix":"1707"},{"ruleId":"1517","severity":2,"message":"1708","line":281,"column":22,"nodeType":"1521","endLine":281,"endColumn":44,"fix":"1709"},{"ruleId":"1517","severity":2,"message":"1685","line":281,"column":44,"nodeType":"1491","endLine":281,"endColumn":47,"fix":"1710"},{"ruleId":"1517","severity":2,"message":"1711","line":281,"column":47,"nodeType":"1521","endLine":281,"endColumn":69,"fix":"1712"},{"ruleId":"1436","severity":2,"message":"1475","line":281,"column":69,"nodeType":null,"endLine":282,"endColumn":1,"fix":"1713"},{"ruleId":"1549","severity":2,"message":"1550","line":281,"column":69,"nodeType":"1491","endLine":283,"endColumn":1,"fix":"1714"},{"ruleId":"1436","severity":2,"message":"1691","line":283,"column":1,"nodeType":null,"endLine":283,"endColumn":1,"fix":"1715"},{"ruleId":"1577","severity":2,"message":"1578","line":283,"column":1,"nodeType":"1579","endLine":283,"endColumn":9,"fix":"1716"},{"ruleId":"1549","severity":2,"message":"1694","line":283,"column":1,"nodeType":"1579","endLine":283,"endColumn":9,"fix":"1717"},{"ruleId":"1530","severity":2,"message":"1531","line":295,"column":21,"nodeType":"1532","messageId":"1533","endLine":295,"endColumn":22,"fix":"1718"},{"ruleId":"1530","severity":2,"message":"1531","line":330,"column":25,"nodeType":"1532","messageId":"1533","endLine":330,"endColumn":26,"fix":"1719"},{"ruleId":"1530","severity":2,"message":"1531","line":367,"column":25,"nodeType":"1532","messageId":"1533","endLine":367,"endColumn":26,"fix":"1720"},{"ruleId":"1517","severity":2,"message":"1721","line":382,"column":20,"nodeType":"1521","endLine":382,"endColumn":31,"fix":"1722"},{"ruleId":"1517","severity":2,"message":"1685","line":382,"column":31,"nodeType":"1491","endLine":382,"endColumn":34,"fix":"1723"},{"ruleId":"1517","severity":2,"message":"1724","line":382,"column":34,"nodeType":"1521","endLine":382,"endColumn":45,"fix":"1725"},{"ruleId":"1517","severity":2,"message":"1726","line":382,"column":45,"nodeType":"1491","endLine":383,"endColumn":17,"fix":"1727"},{"ruleId":"1728","severity":2,"message":"1729","line":423,"column":3,"nodeType":"1508","endLine":423,"endColumn":25},{"ruleId":"1586","severity":2,"message":"1730","line":527,"column":35,"nodeType":"1441","messageId":"1588","endLine":527,"endColumn":40},{"ruleId":"1506","severity":2,"message":"1731","line":11,"column":24,"nodeType":"1508","endLine":11,"endColumn":29},{"ruleId":"1506","severity":2,"message":"1732","line":11,"column":31,"nodeType":"1508","endLine":11,"endColumn":44},{"ruleId":"1463","severity":2,"message":"1464","line":43,"column":5,"nodeType":"1465","messageId":"1466","endLine":47,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":44,"column":7,"nodeType":"1465","messageId":"1466","endLine":46,"endColumn":8},{"ruleId":"1456","severity":2,"message":"1733","line":51,"column":11,"nodeType":"1441","messageId":"1458","endLine":51,"endColumn":21},{"ruleId":"1463","severity":2,"message":"1464","line":65,"column":5,"nodeType":"1465","messageId":"1466","endLine":84,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":94,"column":5,"nodeType":"1465","messageId":"1466","endLine":98,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":95,"column":7,"nodeType":"1465","messageId":"1466","endLine":97,"endColumn":8},{"ruleId":"1456","severity":2,"message":"1734","line":102,"column":11,"nodeType":"1441","messageId":"1458","endLine":102,"endColumn":16},{"ruleId":"1463","severity":2,"message":"1464","line":107,"column":5,"nodeType":"1465","messageId":"1466","endLine":112,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":118,"column":5,"nodeType":"1465","messageId":"1466","endLine":124,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":120,"column":9,"nodeType":"1465","messageId":"1466","endLine":122,"endColumn":10},{"ruleId":"1436","severity":2,"message":"1735","line":190,"column":23,"nodeType":null,"endLine":190,"endColumn":23,"fix":"1736"},{"ruleId":"1517","severity":2,"message":"1683","line":214,"column":18,"nodeType":"1521","endLine":214,"endColumn":41,"fix":"1737"},{"ruleId":"1517","severity":2,"message":"1685","line":214,"column":41,"nodeType":"1491","endLine":214,"endColumn":44,"fix":"1738"},{"ruleId":"1517","severity":2,"message":"1687","line":214,"column":44,"nodeType":"1521","endLine":214,"endColumn":67,"fix":"1739"},{"ruleId":"1436","severity":2,"message":"1475","line":214,"column":67,"nodeType":null,"endLine":215,"endColumn":1,"fix":"1740"},{"ruleId":"1549","severity":2,"message":"1741","line":214,"column":67,"nodeType":"1491","endLine":216,"endColumn":1,"fix":"1742"},{"ruleId":"1436","severity":2,"message":"1743","line":216,"column":1,"nodeType":null,"endLine":216,"endColumn":1,"fix":"1744"},{"ruleId":"1577","severity":2,"message":"1578","line":216,"column":1,"nodeType":"1579","endLine":216,"endColumn":9,"fix":"1745"},{"ruleId":"1549","severity":2,"message":"1746","line":216,"column":1,"nodeType":"1579","endLine":216,"endColumn":9,"fix":"1747"},{"ruleId":"1530","severity":2,"message":"1531","line":228,"column":17,"nodeType":"1532","messageId":"1533","endLine":228,"endColumn":18,"fix":"1748"},{"ruleId":"1517","severity":2,"message":"1697","line":236,"column":18,"nodeType":"1521","endLine":236,"endColumn":40,"fix":"1749"},{"ruleId":"1517","severity":2,"message":"1685","line":236,"column":40,"nodeType":"1491","endLine":236,"endColumn":43,"fix":"1750"},{"ruleId":"1517","severity":2,"message":"1700","line":236,"column":43,"nodeType":"1521","endLine":236,"endColumn":65,"fix":"1751"},{"ruleId":"1436","severity":2,"message":"1475","line":236,"column":65,"nodeType":null,"endLine":237,"endColumn":1,"fix":"1752"},{"ruleId":"1549","severity":2,"message":"1741","line":236,"column":65,"nodeType":"1491","endLine":238,"endColumn":1,"fix":"1753"},{"ruleId":"1436","severity":2,"message":"1743","line":238,"column":1,"nodeType":null,"endLine":238,"endColumn":1,"fix":"1754"},{"ruleId":"1577","severity":2,"message":"1578","line":238,"column":1,"nodeType":"1579","endLine":238,"endColumn":9,"fix":"1755"},{"ruleId":"1549","severity":2,"message":"1746","line":238,"column":1,"nodeType":"1579","endLine":238,"endColumn":9,"fix":"1756"},{"ruleId":"1530","severity":2,"message":"1531","line":250,"column":17,"nodeType":"1532","messageId":"1533","endLine":250,"endColumn":18,"fix":"1757"},{"ruleId":"1517","severity":2,"message":"1708","line":258,"column":18,"nodeType":"1521","endLine":258,"endColumn":40,"fix":"1758"},{"ruleId":"1517","severity":2,"message":"1685","line":258,"column":40,"nodeType":"1491","endLine":258,"endColumn":43,"fix":"1759"},{"ruleId":"1517","severity":2,"message":"1711","line":258,"column":43,"nodeType":"1521","endLine":258,"endColumn":65,"fix":"1760"},{"ruleId":"1436","severity":2,"message":"1475","line":258,"column":65,"nodeType":null,"endLine":259,"endColumn":1,"fix":"1761"},{"ruleId":"1549","severity":2,"message":"1741","line":258,"column":65,"nodeType":"1491","endLine":260,"endColumn":1,"fix":"1762"},{"ruleId":"1436","severity":2,"message":"1743","line":260,"column":1,"nodeType":null,"endLine":260,"endColumn":1,"fix":"1763"},{"ruleId":"1577","severity":2,"message":"1578","line":260,"column":1,"nodeType":"1579","endLine":260,"endColumn":9,"fix":"1764"},{"ruleId":"1549","severity":2,"message":"1746","line":260,"column":1,"nodeType":"1579","endLine":260,"endColumn":9,"fix":"1765"},{"ruleId":"1530","severity":2,"message":"1531","line":272,"column":17,"nodeType":"1532","messageId":"1533","endLine":272,"endColumn":18,"fix":"1766"},{"ruleId":"1530","severity":2,"message":"1531","line":307,"column":21,"nodeType":"1532","messageId":"1533","endLine":307,"endColumn":22,"fix":"1767"},{"ruleId":"1530","severity":2,"message":"1531","line":344,"column":21,"nodeType":"1532","messageId":"1533","endLine":344,"endColumn":22,"fix":"1768"},{"ruleId":"1517","severity":2,"message":"1721","line":359,"column":16,"nodeType":"1521","endLine":359,"endColumn":27,"fix":"1769"},{"ruleId":"1517","severity":2,"message":"1685","line":359,"column":27,"nodeType":"1491","endLine":359,"endColumn":30,"fix":"1770"},{"ruleId":"1517","severity":2,"message":"1724","line":359,"column":30,"nodeType":"1521","endLine":359,"endColumn":41,"fix":"1771"},{"ruleId":"1436","severity":2,"message":"1475","line":359,"column":41,"nodeType":null,"endLine":360,"endColumn":1,"fix":"1772"},{"ruleId":"1549","severity":2,"message":"1746","line":359,"column":41,"nodeType":"1491","endLine":361,"endColumn":1,"fix":"1773"},{"ruleId":"1436","severity":2,"message":"1774","line":361,"column":1,"nodeType":null,"endLine":361,"endColumn":1,"fix":"1775"},{"ruleId":"1577","severity":2,"message":"1578","line":361,"column":1,"nodeType":"1579","endLine":361,"endColumn":9,"fix":"1776"},{"ruleId":"1549","severity":2,"message":"1777","line":361,"column":1,"nodeType":"1579","endLine":361,"endColumn":9,"fix":"1778"},{"ruleId":"1436","severity":2,"message":"1475","line":391,"column":28,"nodeType":null,"endLine":392,"endColumn":1,"fix":"1779"},{"ruleId":"1586","severity":2,"message":"1730","line":489,"column":35,"nodeType":"1441","messageId":"1588","endLine":489,"endColumn":40},{"ruleId":"1436","severity":2,"message":"1484","line":48,"column":3,"nodeType":null,"endLine":48,"endColumn":3,"fix":"1780"},{"ruleId":"1452","severity":2,"message":"1453","line":34,"column":5,"nodeType":"1454","messageId":"1455","endLine":36,"endColumn":45},{"ruleId":"1452","severity":2,"message":"1453","line":41,"column":5,"nodeType":"1454","messageId":"1455","endLine":43,"endColumn":45},{"ruleId":"1517","severity":2,"message":"1781","line":64,"column":30,"nodeType":"1678","endLine":64,"endColumn":39,"fix":"1782"},{"ruleId":"1517","severity":2,"message":"1781","line":70,"column":30,"nodeType":"1678","endLine":70,"endColumn":39,"fix":"1783"},{"ruleId":"1436","severity":2,"message":"1475","line":107,"column":1,"nodeType":null,"endLine":108,"endColumn":1,"fix":"1784"},{"ruleId":"1503","severity":2,"message":"1504","line":43,"column":31,"nodeType":"1441","endLine":43,"endColumn":41},{"ruleId":"1456","severity":2,"message":"1785","line":45,"column":34,"nodeType":"1441","messageId":"1458","endLine":45,"endColumn":39},{"ruleId":"1503","severity":2,"message":"1504","line":49,"column":36,"nodeType":"1523","endLine":49,"endColumn":63},{"ruleId":"1436","severity":2,"message":"1786","line":62,"column":46,"nodeType":null,"endLine":64,"endColumn":1,"fix":"1787"},{"ruleId":"1549","severity":2,"message":"1788","line":63,"column":1,"nodeType":"1521","endLine":63,"endColumn":6,"fix":"1789"},{"ruleId":"1549","severity":2,"message":"1788","line":64,"column":1,"nodeType":"1790","endLine":64,"endColumn":10,"fix":"1791"},{"ruleId":"1503","severity":2,"message":"1504","line":71,"column":46,"nodeType":"1523","endLine":71,"endColumn":62},{"ruleId":"1503","severity":2,"message":"1504","line":42,"column":29,"nodeType":"1441","endLine":42,"endColumn":34},{"ruleId":"1456","severity":2,"message":"1792","line":43,"column":31,"nodeType":"1441","messageId":"1458","endLine":43,"endColumn":36},{"ruleId":"1456","severity":2,"message":"1793","line":43,"column":38,"nodeType":"1441","messageId":"1458","endLine":43,"endColumn":43},{"ruleId":"1503","severity":2,"message":"1504","line":46,"column":39,"nodeType":"1523","endLine":46,"endColumn":61},{"ruleId":"1503","severity":2,"message":"1504","line":58,"column":42,"nodeType":"1523","endLine":58,"endColumn":58},{"ruleId":"1503","severity":2,"message":"1504","line":57,"column":29,"nodeType":"1441","endLine":57,"endColumn":34},{"ruleId":"1456","severity":2,"message":"1794","line":59,"column":39,"nodeType":"1441","messageId":"1458","endLine":59,"endColumn":44},{"ruleId":"1503","severity":2,"message":"1504","line":75,"column":44,"nodeType":"1523","endLine":75,"endColumn":60},{"ruleId":"1436","severity":2,"message":"1795","line":16,"column":33,"nodeType":null,"endLine":18,"endColumn":18,"fix":"1796"},{"ruleId":"1436","severity":2,"message":"1797","line":24,"column":72,"nodeType":null,"endLine":26,"endColumn":22,"fix":"1798"},{"ruleId":"1517","severity":2,"message":"1559","line":26,"column":24,"nodeType":"1521","endLine":26,"endColumn":29,"fix":"1799"},{"ruleId":"1517","severity":2,"message":"1518","line":33,"column":22,"nodeType":"1491","endLine":33,"endColumn":23,"fix":"1800"},{"ruleId":"1517","severity":2,"message":"1801","line":33,"column":23,"nodeType":"1521","endLine":33,"endColumn":38,"fix":"1802"},{"ruleId":"1436","severity":2,"message":"1803","line":42,"column":12,"nodeType":null,"endLine":43,"endColumn":11,"fix":"1804"},{"ruleId":"1436","severity":2,"message":"1803","line":49,"column":12,"nodeType":null,"endLine":50,"endColumn":11,"fix":"1805"},{"ruleId":"1436","severity":2,"message":"1475","line":73,"column":28,"nodeType":null,"endLine":74,"endColumn":1,"fix":"1806"},{"ruleId":"1456","severity":2,"message":"1807","line":15,"column":13,"nodeType":"1441","messageId":"1458","endLine":15,"endColumn":17},{"ruleId":"1517","severity":2,"message":"1808","line":31,"column":32,"nodeType":"1491","endLine":31,"endColumn":36,"fix":"1809"},{"ruleId":"1517","severity":2,"message":"1810","line":31,"column":36,"nodeType":"1521","endLine":31,"endColumn":60,"fix":"1811"},{"ruleId":"1517","severity":2,"message":"1812","line":36,"column":74,"nodeType":"1491","endLine":37,"endColumn":1,"fix":"1813"},{"ruleId":"1436","severity":2,"message":"1475","line":36,"column":76,"nodeType":null,"endLine":37,"endColumn":1,"fix":"1814"},{"ruleId":"1549","severity":2,"message":"1815","line":37,"column":1,"nodeType":"1521","endLine":37,"endColumn":6,"fix":"1816"},{"ruleId":"1517","severity":2,"message":"1518","line":44,"column":24,"nodeType":"1491","endLine":44,"endColumn":25,"fix":"1817"},{"ruleId":"1517","severity":2,"message":"1818","line":44,"column":25,"nodeType":"1521","endLine":44,"endColumn":37,"fix":"1819"},{"ruleId":"1517","severity":2,"message":"1518","line":51,"column":18,"nodeType":"1491","endLine":51,"endColumn":19,"fix":"1820"},{"ruleId":"1517","severity":2,"message":"1821","line":51,"column":19,"nodeType":"1521","endLine":51,"endColumn":69,"fix":"1822"},{"ruleId":"1517","severity":2,"message":"1821","line":61,"column":16,"nodeType":"1521","endLine":61,"endColumn":66,"fix":"1823"},{"ruleId":"1456","severity":2,"message":"1824","line":22,"column":13,"nodeType":"1441","messageId":"1458","endLine":22,"endColumn":23},{"ruleId":"1459","severity":2,"message":"1487","line":39,"column":5,"nodeType":"1461","messageId":"1462","endLine":41,"endColumn":7},{"ruleId":"1452","severity":2,"message":"1453","line":49,"column":11,"nodeType":"1454","messageId":"1455","endLine":49,"endColumn":49},{"ruleId":"1517","severity":2,"message":"1825","line":151,"column":29,"nodeType":"1521","endLine":151,"endColumn":60,"fix":"1826"},{"ruleId":"1436","severity":2,"message":"1827","line":165,"column":61,"nodeType":null,"endLine":165,"endColumn":61,"fix":"1828"},{"ruleId":"1436","severity":2,"message":"1475","line":169,"column":24,"nodeType":null,"endLine":170,"endColumn":1,"fix":"1829"},{"ruleId":"1517","severity":2,"message":"1685","line":29,"column":24,"nodeType":"1491","endLine":29,"endColumn":27,"fix":"1830"},{"ruleId":"1517","severity":2,"message":"1810","line":29,"column":27,"nodeType":"1521","endLine":29,"endColumn":51,"fix":"1831"},{"ruleId":"1517","severity":2,"message":"1812","line":35,"column":68,"nodeType":"1491","endLine":35,"endColumn":70,"fix":"1832"},{"ruleId":"1517","severity":2,"message":"1559","line":35,"column":70,"nodeType":"1521","endLine":35,"endColumn":75,"fix":"1833"},{"ruleId":"1517","severity":2,"message":"1518","line":41,"column":18,"nodeType":"1491","endLine":41,"endColumn":19,"fix":"1834"},{"ruleId":"1517","severity":2,"message":"1818","line":41,"column":19,"nodeType":"1521","endLine":41,"endColumn":31,"fix":"1835"},{"ruleId":"1456","severity":2,"message":"1836","line":54,"column":17,"nodeType":"1441","messageId":"1458","endLine":54,"endColumn":25},{"ruleId":"1517","severity":2,"message":"1518","line":61,"column":14,"nodeType":"1491","endLine":61,"endColumn":15,"fix":"1837"},{"ruleId":"1517","severity":2,"message":"1838","line":61,"column":15,"nodeType":"1521","endLine":61,"endColumn":38,"fix":"1839"},{"ruleId":"1728","severity":2,"message":"1840","line":80,"column":5,"nodeType":"1508","endLine":80,"endColumn":30},{"ruleId":"1436","severity":2,"message":"1484","line":175,"column":3,"nodeType":null,"endLine":175,"endColumn":3,"fix":"1841"},{"ruleId":"1423","replacedBy":"1842"},{"ruleId":"1425","replacedBy":"1843"},{"ruleId":"1427","replacedBy":"1844"},{"ruleId":"1429","replacedBy":"1845"},{"ruleId":"1431","replacedBy":"1846"},{"ruleId":"1436","severity":2,"message":"1484","line":74,"column":3,"nodeType":null,"endLine":74,"endColumn":3,"fix":"1847"},{"ruleId":"1456","severity":2,"message":"1486","line":49,"column":11,"nodeType":"1441","messageId":"1458","endLine":49,"endColumn":20},{"ruleId":"1456","severity":2,"message":"1486","line":62,"column":15,"nodeType":"1441","messageId":"1458","endLine":62,"endColumn":24},{"ruleId":"1463","severity":2,"message":"1464","line":64,"column":9,"nodeType":"1465","messageId":"1466","endLine":66,"endColumn":10},{"ruleId":"1459","severity":2,"message":"1487","line":69,"column":5,"nodeType":"1461","messageId":"1462","endLine":69,"endColumn":24},{"ruleId":"1436","severity":2,"message":"1475","line":128,"column":1,"nodeType":null,"endLine":129,"endColumn":1,"fix":"1848"},{"ruleId":"1489","severity":2,"message":"1490","line":29,"column":22,"nodeType":"1491"},{"ruleId":"1436","severity":2,"message":"1484","line":322,"column":3,"nodeType":null,"endLine":322,"endColumn":3,"fix":"1849"},{"ruleId":"1492","severity":2,"message":"1493","line":57,"column":60,"nodeType":"1494","endLine":57,"endColumn":70},{"ruleId":"1463","severity":2,"message":"1464","line":19,"column":7,"nodeType":"1465","messageId":"1466","endLine":22,"endColumn":8},{"ruleId":"1497","severity":2,"message":"1498","line":20,"column":22,"nodeType":"1499","messageId":"1500","endLine":20,"endColumn":45},{"ruleId":"1489","severity":2,"message":"1490","line":35,"column":38,"nodeType":"1491"},{"ruleId":"1452","severity":2,"message":"1453","line":14,"column":5,"nodeType":"1454","messageId":"1455","endLine":16,"endColumn":28},{"ruleId":"1439","severity":2,"message":"1501","line":24,"column":22,"nodeType":"1441","messageId":"1442","endLine":24,"endColumn":28},{"ruleId":"1456","severity":2,"message":"1502","line":48,"column":15,"nodeType":"1441","messageId":"1458","endLine":48,"endColumn":21},{"ruleId":"1456","severity":2,"message":"1502","line":57,"column":15,"nodeType":"1441","messageId":"1458","endLine":57,"endColumn":21},{"ruleId":"1503","severity":2,"message":"1504","line":84,"column":34,"nodeType":"1441","endLine":84,"endColumn":39},{"ruleId":"1436","severity":2,"message":"1475","line":137,"column":1,"nodeType":null,"endLine":138,"endColumn":1,"fix":"1850"},{"ruleId":"1506","severity":2,"message":"1507","line":6,"column":24,"nodeType":"1508","endLine":6,"endColumn":44},{"ruleId":"1492","severity":2,"message":"1493","line":11,"column":7,"nodeType":"1494","endLine":11,"endColumn":16},{"ruleId":"1492","severity":2,"message":"1493","line":16,"column":22,"nodeType":"1494","endLine":16,"endColumn":32},{"ruleId":"1506","severity":2,"message":"1507","line":6,"column":25,"nodeType":"1508","endLine":6,"endColumn":45},{"ruleId":"1492","severity":2,"message":"1493","line":11,"column":7,"nodeType":"1494","endLine":11,"endColumn":16},{"ruleId":"1492","severity":2,"message":"1493","line":14,"column":22,"nodeType":"1494","endLine":14,"endColumn":32},{"ruleId":"1456","severity":2,"message":"1509","line":16,"column":11,"nodeType":"1441","messageId":"1458","endLine":16,"endColumn":16},{"ruleId":"1452","severity":2,"message":"1453","line":17,"column":5,"nodeType":"1454","messageId":"1455","endLine":19,"endColumn":60},{"ruleId":"1456","severity":2,"message":"1510","line":45,"column":17,"nodeType":"1441","messageId":"1458","endLine":45,"endColumn":24},{"ruleId":"1456","severity":2,"message":"1511","line":51,"column":23,"nodeType":"1441","messageId":"1458","endLine":51,"endColumn":27},{"ruleId":"1456","severity":2,"message":"1512","line":57,"column":9,"nodeType":"1441","messageId":"1458","endLine":57,"endColumn":23},{"ruleId":"1452","severity":2,"message":"1453","line":51,"column":5,"nodeType":"1454","messageId":"1455","endLine":53,"endColumn":33},{"ruleId":"1456","severity":2,"message":"1514","line":60,"column":13,"nodeType":"1441","messageId":"1458","endLine":60,"endColumn":17},{"ruleId":"1463","severity":2,"message":"1464","line":75,"column":7,"nodeType":"1465","messageId":"1466","endLine":77,"endColumn":8},{"ruleId":"1456","severity":2,"message":"1515","line":118,"column":14,"nodeType":"1441","messageId":"1458","endLine":118,"endColumn":15},{"ruleId":"1456","severity":2,"message":"1516","line":129,"column":13,"nodeType":"1441","messageId":"1458","endLine":129,"endColumn":28},{"ruleId":"1517","severity":2,"message":"1518","line":179,"column":22,"nodeType":"1491","endLine":179,"endColumn":23,"fix":"1851"},{"ruleId":"1517","severity":2,"message":"1520","line":179,"column":23,"nodeType":"1521","endLine":179,"endColumn":37,"fix":"1852"},{"ruleId":"1503","severity":2,"message":"1504","line":182,"column":34,"nodeType":"1523","endLine":182,"endColumn":55},{"ruleId":"1517","severity":2,"message":"1524","line":189,"column":28,"nodeType":"1521","endLine":189,"endColumn":54,"fix":"1853"},{"ruleId":"1517","severity":2,"message":"1526","line":218,"column":36,"nodeType":"1521","endLine":218,"endColumn":44,"fix":"1854"},{"ruleId":"1517","severity":2,"message":"1528","line":218,"column":44,"nodeType":"1491","endLine":218,"endColumn":46,"fix":"1855"},{"ruleId":"1530","severity":2,"message":"1531","line":247,"column":35,"nodeType":"1532","messageId":"1533","endLine":247,"endColumn":36,"fix":"1856"},{"ruleId":"1456","severity":2,"message":"1535","line":268,"column":31,"nodeType":"1441","messageId":"1458","endLine":268,"endColumn":39},{"ruleId":"1517","severity":2,"message":"1536","line":310,"column":48,"nodeType":"1521","endLine":310,"endColumn":59,"fix":"1857"},{"ruleId":"1517","severity":2,"message":"1528","line":310,"column":59,"nodeType":"1491","endLine":310,"endColumn":61,"fix":"1858"},{"ruleId":"1517","severity":2,"message":"1539","line":328,"column":50,"nodeType":"1521","endLine":328,"endColumn":56,"fix":"1859"},{"ruleId":"1517","severity":2,"message":"1528","line":328,"column":56,"nodeType":"1491","endLine":328,"endColumn":58,"fix":"1860"},{"ruleId":"1456","severity":2,"message":"1513","line":13,"column":13,"nodeType":"1441","messageId":"1458","endLine":13,"endColumn":20},{"ruleId":"1489","severity":2,"message":"1490","line":25,"column":58,"nodeType":"1491"},{"ruleId":"1489","severity":2,"message":"1490","line":27,"column":72,"nodeType":"1491"},{"ruleId":"1489","severity":2,"message":"1490","line":42,"column":19,"nodeType":"1491"},{"ruleId":"1456","severity":2,"message":"1544","line":41,"column":17,"nodeType":"1441","messageId":"1458","endLine":41,"endColumn":24},{"ruleId":"1456","severity":2,"message":"1545","line":47,"column":23,"nodeType":"1441","messageId":"1458","endLine":47,"endColumn":27},{"ruleId":"1456","severity":2,"message":"1546","line":53,"column":9,"nodeType":"1441","messageId":"1458","endLine":53,"endColumn":23},{"ruleId":"1456","severity":2,"message":"1542","line":18,"column":13,"nodeType":"1441","messageId":"1458","endLine":18,"endColumn":19},{"ruleId":"1456","severity":2,"message":"1543","line":21,"column":13,"nodeType":"1441","messageId":"1458","endLine":21,"endColumn":18},{"ruleId":"1463","severity":2,"message":"1464","line":22,"column":7,"nodeType":"1465","messageId":"1466","endLine":25,"endColumn":8},{"ruleId":"1497","severity":2,"message":"1498","line":23,"column":22,"nodeType":"1499","messageId":"1500","endLine":23,"endColumn":43},{"ruleId":"1456","severity":2,"message":"1495","line":35,"column":13,"nodeType":"1441","messageId":"1458","endLine":35,"endColumn":17},{"ruleId":"1456","severity":2,"message":"1495","line":43,"column":13,"nodeType":"1441","messageId":"1458","endLine":43,"endColumn":17},{"ruleId":"1459","severity":2,"message":"1487","line":46,"column":5,"nodeType":"1461","messageId":"1462","endLine":46,"endColumn":24},{"ruleId":"1456","severity":2,"message":"1495","line":50,"column":23,"nodeType":"1441","messageId":"1458","endLine":50,"endColumn":27},{"ruleId":"1456","severity":2,"message":"1495","line":102,"column":22,"nodeType":"1441","messageId":"1458","endLine":102,"endColumn":26},{"ruleId":"1456","severity":2,"message":"1496","line":102,"column":28,"nodeType":"1441","messageId":"1458","endLine":102,"endColumn":39},{"ruleId":"1489","severity":2,"message":"1490","line":158,"column":29,"nodeType":"1491"},{"ruleId":"1456","severity":2,"message":"1547","line":40,"column":13,"nodeType":"1441","messageId":"1458","endLine":40,"endColumn":18},{"ruleId":"1436","severity":2,"message":"1475","line":88,"column":56,"nodeType":null,"endLine":89,"endColumn":1,"fix":"1861"},{"ruleId":"1549","severity":2,"message":"1550","line":89,"column":1,"nodeType":"1521","endLine":89,"endColumn":6,"fix":"1862"},{"ruleId":"1436","severity":2,"message":"1475","line":94,"column":54,"nodeType":null,"endLine":95,"endColumn":1,"fix":"1863"},{"ruleId":"1549","severity":2,"message":"1550","line":95,"column":1,"nodeType":"1521","endLine":95,"endColumn":6,"fix":"1864"},{"ruleId":"1436","severity":2,"message":"1554","line":113,"column":59,"nodeType":null,"endLine":115,"endColumn":1,"fix":"1865"},{"ruleId":"1549","severity":2,"message":"1556","line":114,"column":1,"nodeType":"1521","endLine":114,"endColumn":6,"fix":"1866"},{"ruleId":"1549","severity":2,"message":"1556","line":114,"column":6,"nodeType":"1491","endLine":115,"endColumn":2,"fix":"1867"},{"ruleId":"1517","severity":2,"message":"1559","line":115,"column":2,"nodeType":"1521","endLine":115,"endColumn":7,"fix":"1868"},{"ruleId":"1456","severity":2,"message":"1561","line":174,"column":33,"nodeType":"1441","messageId":"1458","endLine":174,"endColumn":39},{"ruleId":"1456","severity":2,"message":"1562","line":199,"column":33,"nodeType":"1441","messageId":"1458","endLine":199,"endColumn":36},{"ruleId":"1456","severity":2,"message":"1563","line":51,"column":13,"nodeType":"1441","messageId":"1458","endLine":51,"endColumn":22},{"ruleId":"1456","severity":2,"message":"1564","line":95,"column":37,"nodeType":"1441","messageId":"1458","endLine":95,"endColumn":44},{"ruleId":"1517","severity":2,"message":"1565","line":99,"column":49,"nodeType":"1521","endLine":99,"endColumn":67,"fix":"1869"},{"ruleId":"1517","severity":2,"message":"1567","line":103,"column":47,"nodeType":"1521","endLine":103,"endColumn":61,"fix":"1870"},{"ruleId":"1456","severity":2,"message":"1509","line":15,"column":13,"nodeType":"1441","messageId":"1458","endLine":15,"endColumn":18},{"ruleId":"1517","severity":2,"message":"1569","line":36,"column":44,"nodeType":"1521","endLine":36,"endColumn":69,"fix":"1871"},{"ruleId":"1517","severity":2,"message":"1571","line":40,"column":42,"nodeType":"1521","endLine":40,"endColumn":63,"fix":"1872"},{"ruleId":"1436","severity":2,"message":"1573","line":52,"column":49,"nodeType":null,"endLine":54,"endColumn":46,"fix":"1873"},{"ruleId":"1436","severity":2,"message":"1575","line":55,"column":1,"nodeType":null,"endLine":55,"endColumn":3,"fix":"1874"},{"ruleId":"1577","severity":2,"message":"1578","line":55,"column":15,"nodeType":"1579","endLine":55,"endColumn":19,"fix":"1875"},{"ruleId":"1549","severity":2,"message":"1581","line":55,"column":15,"nodeType":"1579","endLine":55,"endColumn":19,"fix":"1876"},{"ruleId":"1489","severity":2,"message":"1490","line":58,"column":40,"nodeType":"1491"},{"ruleId":"1517","severity":2,"message":"1559","line":58,"column":67,"nodeType":"1521","endLine":58,"endColumn":72,"fix":"1877"},{"ruleId":"1517","severity":2,"message":"1559","line":62,"column":62,"nodeType":"1521","endLine":62,"endColumn":67,"fix":"1878"},{"ruleId":"1586","severity":2,"message":"1587","line":7,"column":17,"nodeType":"1441","messageId":"1588","endLine":7,"endColumn":25},{"ruleId":"1456","severity":2,"message":"1585","line":14,"column":13,"nodeType":"1441","messageId":"1458","endLine":14,"endColumn":19},{"ruleId":"1456","severity":2,"message":"1589","line":63,"column":13,"nodeType":"1441","messageId":"1458","endLine":63,"endColumn":22},{"ruleId":"1452","severity":2,"message":"1453","line":67,"column":7,"nodeType":"1454","messageId":"1455","endLine":67,"endColumn":57},{"ruleId":"1456","severity":2,"message":"1589","line":73,"column":13,"nodeType":"1441","messageId":"1458","endLine":73,"endColumn":22},{"ruleId":"1456","severity":2,"message":"1590","line":91,"column":29,"nodeType":"1441","messageId":"1458","endLine":91,"endColumn":36},{"ruleId":"1517","severity":2,"message":"1565","line":96,"column":43,"nodeType":"1521","endLine":96,"endColumn":61,"fix":"1879"},{"ruleId":"1517","severity":2,"message":"1567","line":100,"column":41,"nodeType":"1521","endLine":100,"endColumn":55,"fix":"1880"},{"ruleId":"1530","severity":2,"message":"1531","line":111,"column":25,"nodeType":"1532","messageId":"1533","endLine":111,"endColumn":26,"fix":"1881"},{"ruleId":"1456","severity":2,"message":"1594","line":47,"column":13,"nodeType":"1441","messageId":"1458","endLine":47,"endColumn":18},{"ruleId":"1456","severity":2,"message":"1594","line":55,"column":13,"nodeType":"1441","messageId":"1458","endLine":55,"endColumn":18},{"ruleId":"1517","severity":2,"message":"1595","line":78,"column":26,"nodeType":"1521","endLine":78,"endColumn":49,"fix":"1882"},{"ruleId":"1436","severity":2,"message":"1597","line":78,"column":49,"nodeType":null,"endLine":81,"endColumn":1,"fix":"1883"},{"ruleId":"1549","severity":2,"message":"1599","line":79,"column":1,"nodeType":"1521","endLine":79,"endColumn":6,"fix":"1884"},{"ruleId":"1549","severity":2,"message":"1599","line":79,"column":6,"nodeType":"1491","endLine":81,"endColumn":1,"fix":"1885"},{"ruleId":"1577","severity":2,"message":"1578","line":81,"column":1,"nodeType":"1579","endLine":81,"endColumn":7,"fix":"1886"},{"ruleId":"1549","severity":2,"message":"1550","line":81,"column":1,"nodeType":"1579","endLine":81,"endColumn":7,"fix":"1887"},{"ruleId":"1456","severity":2,"message":"1604","line":133,"column":37,"nodeType":"1441","messageId":"1458","endLine":133,"endColumn":43},{"ruleId":"1456","severity":2,"message":"1605","line":161,"column":37,"nodeType":"1441","messageId":"1458","endLine":161,"endColumn":40},{"ruleId":"1456","severity":2,"message":"1604","line":215,"column":25,"nodeType":"1441","messageId":"1458","endLine":215,"endColumn":31},{"ruleId":"1456","severity":2,"message":"1605","line":241,"column":23,"nodeType":"1441","messageId":"1458","endLine":241,"endColumn":26},{"ruleId":"1456","severity":2,"message":"1607","line":32,"column":13,"nodeType":"1441","messageId":"1458","endLine":32,"endColumn":17},{"ruleId":"1456","severity":2,"message":"1607","line":40,"column":13,"nodeType":"1441","messageId":"1458","endLine":40,"endColumn":17},{"ruleId":"1459","severity":2,"message":"1487","line":43,"column":5,"nodeType":"1461","messageId":"1462","endLine":43,"endColumn":24},{"ruleId":"1436","severity":2,"message":"1475","line":111,"column":1,"nodeType":null,"endLine":112,"endColumn":1,"fix":"1888"},{"ruleId":"1456","severity":2,"message":"1606","line":17,"column":13,"nodeType":"1441","messageId":"1458","endLine":17,"endColumn":23},{"ruleId":"1489","severity":2,"message":"1490","line":27,"column":25,"nodeType":"1491"},{"ruleId":"1436","severity":2,"message":"1475","line":66,"column":1,"nodeType":null,"endLine":67,"endColumn":1,"fix":"1889"},{"ruleId":"1456","severity":2,"message":"1457","line":111,"column":34,"nodeType":"1441","messageId":"1458","endLine":111,"endColumn":38},{"ruleId":"1456","severity":2,"message":"1457","line":114,"column":8,"nodeType":"1441","messageId":"1458","endLine":114,"endColumn":12},{"ruleId":"1456","severity":2,"message":"1477","line":21,"column":34,"nodeType":"1441","messageId":"1458","endLine":21,"endColumn":38},{"ruleId":"1456","severity":2,"message":"1478","line":21,"column":40,"nodeType":"1441","messageId":"1458","endLine":21,"endColumn":46},{"ruleId":"1456","severity":2,"message":"1479","line":21,"column":48,"nodeType":"1441","messageId":"1458","endLine":21,"endColumn":52},{"ruleId":"1456","severity":2,"message":"1480","line":21,"column":54,"nodeType":"1441","messageId":"1458","endLine":21,"endColumn":57},{"ruleId":"1439","severity":2,"message":"1481","line":89,"column":13,"nodeType":"1441","messageId":"1442","endLine":89,"endColumn":21},{"ruleId":"1456","severity":2,"message":"1477","line":96,"column":33,"nodeType":"1441","messageId":"1458","endLine":96,"endColumn":37},{"ruleId":"1456","severity":2,"message":"1478","line":96,"column":39,"nodeType":"1441","messageId":"1458","endLine":96,"endColumn":45},{"ruleId":"1456","severity":2,"message":"1479","line":96,"column":47,"nodeType":"1441","messageId":"1458","endLine":96,"endColumn":51},{"ruleId":"1456","severity":2,"message":"1480","line":96,"column":53,"nodeType":"1441","messageId":"1458","endLine":96,"endColumn":56},{"ruleId":"1459","severity":2,"message":"1460","line":42,"column":5,"nodeType":"1461","messageId":"1462","endLine":57,"endColumn":10},{"ruleId":"1463","severity":2,"message":"1464","line":87,"column":5,"nodeType":"1465","messageId":"1466","endLine":89,"endColumn":6},{"ruleId":"1456","severity":2,"message":"1467","line":31,"column":5,"nodeType":"1441","messageId":"1458","endLine":31,"endColumn":14},{"ruleId":"1456","severity":2,"message":"1468","line":32,"column":5,"nodeType":"1441","messageId":"1458","endLine":32,"endColumn":13},{"ruleId":"1456","severity":2,"message":"1469","line":33,"column":5,"nodeType":"1441","messageId":"1458","endLine":33,"endColumn":12},{"ruleId":"1456","severity":2,"message":"1470","line":34,"column":5,"nodeType":"1441","messageId":"1458","endLine":34,"endColumn":12},{"ruleId":"1456","severity":2,"message":"1471","line":35,"column":5,"nodeType":"1441","messageId":"1458","endLine":35,"endColumn":9},{"ruleId":"1456","severity":2,"message":"1472","line":36,"column":5,"nodeType":"1441","messageId":"1458","endLine":36,"endColumn":12},{"ruleId":"1456","severity":2,"message":"1473","line":37,"column":5,"nodeType":"1441","messageId":"1458","endLine":37,"endColumn":10},{"ruleId":"1456","severity":2,"message":"1474","line":38,"column":5,"nodeType":"1441","messageId":"1458","endLine":38,"endColumn":10},{"ruleId":"1456","severity":2,"message":"1469","line":93,"column":31,"nodeType":"1441","messageId":"1458","endLine":93,"endColumn":38},{"ruleId":"1456","severity":2,"message":"1467","line":108,"column":5,"nodeType":"1441","messageId":"1458","endLine":108,"endColumn":14},{"ruleId":"1456","severity":2,"message":"1468","line":109,"column":5,"nodeType":"1441","messageId":"1458","endLine":109,"endColumn":13},{"ruleId":"1456","severity":2,"message":"1469","line":110,"column":5,"nodeType":"1441","messageId":"1458","endLine":110,"endColumn":12},{"ruleId":"1456","severity":2,"message":"1470","line":111,"column":5,"nodeType":"1441","messageId":"1458","endLine":111,"endColumn":12},{"ruleId":"1456","severity":2,"message":"1471","line":112,"column":5,"nodeType":"1441","messageId":"1458","endLine":112,"endColumn":9},{"ruleId":"1456","severity":2,"message":"1472","line":113,"column":5,"nodeType":"1441","messageId":"1458","endLine":113,"endColumn":12},{"ruleId":"1456","severity":2,"message":"1473","line":114,"column":5,"nodeType":"1441","messageId":"1458","endLine":114,"endColumn":10},{"ruleId":"1456","severity":2,"message":"1474","line":115,"column":5,"nodeType":"1441","messageId":"1458","endLine":115,"endColumn":10},{"ruleId":"1436","severity":2,"message":"1475","line":155,"column":1,"nodeType":null,"endLine":156,"endColumn":1,"fix":"1890"},{"ruleId":"1456","severity":2,"message":"1469","line":174,"column":24,"nodeType":"1441","messageId":"1458","endLine":174,"endColumn":31},{"ruleId":"1433","severity":2,"message":"1434","line":1,"column":1,"nodeType":"1435","endLine":11,"endColumn":3},{"ruleId":"1436","severity":2,"message":"1437","line":5,"column":23,"nodeType":null,"endLine":5,"endColumn":26,"fix":"1891"},{"ruleId":"1439","severity":2,"message":"1440","line":8,"column":16,"nodeType":"1441","messageId":"1442","endLine":8,"endColumn":26},{"ruleId":"1436","severity":2,"message":"1443","line":14,"column":9,"nodeType":null,"endLine":14,"endColumn":20,"fix":"1892"},{"ruleId":"1445","severity":2,"message":"1446","line":16,"column":10,"nodeType":"1447","messageId":"1448","endLine":18,"endColumn":4,"fix":"1893"},{"ruleId":"1436","severity":2,"message":"1450","line":17,"column":16,"nodeType":null,"endLine":17,"endColumn":16,"fix":"1894"},{"ruleId":"1452","severity":2,"message":"1453","line":39,"column":7,"nodeType":"1454","messageId":"1455","endLine":39,"endColumn":69},{"ruleId":"1517","severity":2,"message":"1559","line":81,"column":26,"nodeType":"1521","endLine":81,"endColumn":31,"fix":"1895"},{"ruleId":"1517","severity":2,"message":"1611","line":84,"column":66,"nodeType":"1491","endLine":85,"endColumn":11,"fix":"1896"},{"ruleId":"1517","severity":2,"message":"1611","line":88,"column":51,"nodeType":"1491","endLine":89,"endColumn":11,"fix":"1897"},{"ruleId":"1506","severity":2,"message":"1614","line":9,"column":19,"nodeType":"1508","endLine":9,"endColumn":23},{"ruleId":"1506","severity":2,"message":"1615","line":9,"column":25,"nodeType":"1508","endLine":9,"endColumn":33},{"ruleId":"1452","severity":2,"message":"1453","line":41,"column":11,"nodeType":"1454","messageId":"1455","endLine":41,"endColumn":77},{"ruleId":"1489","severity":2,"message":"1490","line":88,"column":42,"nodeType":"1491"},{"ruleId":"1517","severity":2,"message":"1559","line":104,"column":33,"nodeType":"1521","endLine":104,"endColumn":38,"fix":"1898"},{"ruleId":"1452","severity":2,"message":"1453","line":19,"column":5,"nodeType":"1454","messageId":"1455","endLine":19,"endColumn":69},{"ruleId":"1452","severity":2,"message":"1453","line":29,"column":5,"nodeType":"1454","messageId":"1455","endLine":29,"endColumn":71},{"ruleId":"1517","severity":2,"message":"1518","line":49,"column":18,"nodeType":"1491","endLine":49,"endColumn":19,"fix":"1899"},{"ruleId":"1517","severity":2,"message":"1618","line":49,"column":19,"nodeType":"1521","endLine":49,"endColumn":26,"fix":"1900"},{"ruleId":"1436","severity":2,"message":"1475","line":75,"column":1,"nodeType":null,"endLine":76,"endColumn":1,"fix":"1901"},{"ruleId":"1463","severity":2,"message":"1464","line":71,"column":5,"nodeType":"1465","messageId":"1466","endLine":74,"endColumn":6},{"ruleId":"1497","severity":2,"message":"1498","line":72,"column":24,"nodeType":"1499","messageId":"1500","endLine":72,"endColumn":60},{"ruleId":"1463","severity":2,"message":"1464","line":77,"column":5,"nodeType":"1465","messageId":"1466","endLine":80,"endColumn":6},{"ruleId":"1497","severity":2,"message":"1498","line":78,"column":29,"nodeType":"1499","messageId":"1500","endLine":78,"endColumn":71},{"ruleId":"1463","severity":2,"message":"1464","line":85,"column":5,"nodeType":"1465","messageId":"1466","endLine":89,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":100,"column":5,"nodeType":"1465","messageId":"1466","endLine":108,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":115,"column":5,"nodeType":"1465","messageId":"1466","endLine":117,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":121,"column":5,"nodeType":"1465","messageId":"1466","endLine":123,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":124,"column":5,"nodeType":"1465","messageId":"1466","endLine":126,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":127,"column":5,"nodeType":"1465","messageId":"1466","endLine":129,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":141,"column":5,"nodeType":"1465","messageId":"1466","endLine":150,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":142,"column":7,"nodeType":"1465","messageId":"1466","endLine":149,"endColumn":8},{"ruleId":"1463","severity":2,"message":"1464","line":168,"column":5,"nodeType":"1465","messageId":"1466","endLine":189,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":169,"column":7,"nodeType":"1465","messageId":"1466","endLine":188,"endColumn":8},{"ruleId":"1456","severity":2,"message":"1621","line":212,"column":14,"nodeType":"1441","messageId":"1458","endLine":212,"endColumn":15},{"ruleId":"1463","severity":2,"message":"1464","line":224,"column":5,"nodeType":"1465","messageId":"1466","endLine":226,"endColumn":6},{"ruleId":"1530","severity":2,"message":"1531","line":285,"column":15,"nodeType":"1532","messageId":"1533","endLine":285,"endColumn":16,"fix":"1902"},{"ruleId":"1530","severity":2,"message":"1531","line":298,"column":15,"nodeType":"1532","messageId":"1533","endLine":298,"endColumn":16,"fix":"1903"},{"ruleId":"1530","severity":2,"message":"1531","line":311,"column":15,"nodeType":"1532","messageId":"1533","endLine":311,"endColumn":16,"fix":"1904"},{"ruleId":"1517","severity":2,"message":"1625","line":333,"column":32,"nodeType":"1521","endLine":333,"endColumn":43,"fix":"1905"},{"ruleId":"1456","severity":2,"message":"1627","line":343,"column":33,"nodeType":"1441","messageId":"1458","endLine":343,"endColumn":42},{"ruleId":"1530","severity":2,"message":"1531","line":347,"column":23,"nodeType":"1532","messageId":"1533","endLine":347,"endColumn":24,"fix":"1906"},{"ruleId":"1456","severity":2,"message":"1627","line":355,"column":31,"nodeType":"1441","messageId":"1458","endLine":355,"endColumn":40},{"ruleId":"1530","severity":2,"message":"1531","line":359,"column":21,"nodeType":"1532","messageId":"1533","endLine":359,"endColumn":22,"fix":"1907"},{"ruleId":"1456","severity":2,"message":"1630","line":381,"column":29,"nodeType":"1441","messageId":"1458","endLine":381,"endColumn":40},{"ruleId":"1517","severity":2,"message":"1625","line":385,"column":29,"nodeType":"1521","endLine":385,"endColumn":40,"fix":"1908"},{"ruleId":"1456","severity":2,"message":"1632","line":398,"column":31,"nodeType":"1441","messageId":"1458","endLine":398,"endColumn":42},{"ruleId":"1530","severity":2,"message":"1531","line":402,"column":21,"nodeType":"1532","messageId":"1533","endLine":402,"endColumn":22,"fix":"1909"},{"ruleId":"1456","severity":2,"message":"1632","line":409,"column":31,"nodeType":"1441","messageId":"1458","endLine":409,"endColumn":42},{"ruleId":"1530","severity":2,"message":"1531","line":413,"column":21,"nodeType":"1532","messageId":"1533","endLine":413,"endColumn":22,"fix":"1910"},{"ruleId":"1530","severity":2,"message":"1531","line":434,"column":15,"nodeType":"1532","messageId":"1533","endLine":434,"endColumn":16,"fix":"1911"},{"ruleId":"1456","severity":2,"message":"1636","line":455,"column":33,"nodeType":"1441","messageId":"1458","endLine":455,"endColumn":39},{"ruleId":"1530","severity":2,"message":"1531","line":459,"column":23,"nodeType":"1532","messageId":"1533","endLine":459,"endColumn":24,"fix":"1912"},{"ruleId":"1456","severity":2,"message":"1636","line":472,"column":33,"nodeType":"1441","messageId":"1458","endLine":472,"endColumn":39},{"ruleId":"1530","severity":2,"message":"1531","line":476,"column":23,"nodeType":"1532","messageId":"1533","endLine":476,"endColumn":24,"fix":"1913"},{"ruleId":"1456","severity":2,"message":"1636","line":487,"column":33,"nodeType":"1441","messageId":"1458","endLine":487,"endColumn":39},{"ruleId":"1530","severity":2,"message":"1531","line":491,"column":23,"nodeType":"1532","messageId":"1533","endLine":491,"endColumn":24,"fix":"1914"},{"ruleId":"1456","severity":2,"message":"1636","line":503,"column":31,"nodeType":"1441","messageId":"1458","endLine":503,"endColumn":37},{"ruleId":"1640","severity":2,"message":"1641","line":504,"column":25,"nodeType":"1642","messageId":"1643","endLine":504,"endColumn":64},{"ruleId":"1456","severity":2,"message":"1636","line":515,"column":31,"nodeType":"1441","messageId":"1458","endLine":515,"endColumn":37},{"ruleId":"1530","severity":2,"message":"1531","line":519,"column":21,"nodeType":"1532","messageId":"1533","endLine":519,"endColumn":22,"fix":"1915"},{"ruleId":"1517","severity":2,"message":"1625","line":545,"column":30,"nodeType":"1521","endLine":545,"endColumn":41,"fix":"1916"},{"ruleId":"1456","severity":2,"message":"1646","line":554,"column":31,"nodeType":"1441","messageId":"1458","endLine":554,"endColumn":41},{"ruleId":"1530","severity":2,"message":"1531","line":558,"column":21,"nodeType":"1532","messageId":"1533","endLine":558,"endColumn":22,"fix":"1917"},{"ruleId":"1456","severity":2,"message":"1646","line":566,"column":29,"nodeType":"1441","messageId":"1458","endLine":566,"endColumn":39},{"ruleId":"1530","severity":2,"message":"1531","line":570,"column":19,"nodeType":"1532","messageId":"1533","endLine":570,"endColumn":20,"fix":"1918"},{"ruleId":"1530","severity":2,"message":"1531","line":603,"column":15,"nodeType":"1532","messageId":"1533","endLine":603,"endColumn":16,"fix":"1919"},{"ruleId":"1456","severity":2,"message":"1650","line":625,"column":35,"nodeType":"1441","messageId":"1458","endLine":625,"endColumn":42},{"ruleId":"1530","severity":2,"message":"1531","line":629,"column":25,"nodeType":"1532","messageId":"1533","endLine":629,"endColumn":26,"fix":"1920"},{"ruleId":"1456","severity":2,"message":"1650","line":637,"column":35,"nodeType":"1441","messageId":"1458","endLine":637,"endColumn":42},{"ruleId":"1530","severity":2,"message":"1531","line":641,"column":25,"nodeType":"1532","messageId":"1533","endLine":641,"endColumn":26,"fix":"1921"},{"ruleId":"1456","severity":2,"message":"1650","line":679,"column":39,"nodeType":"1441","messageId":"1458","endLine":679,"endColumn":46},{"ruleId":"1530","severity":2,"message":"1531","line":685,"column":29,"nodeType":"1532","messageId":"1533","endLine":685,"endColumn":30,"fix":"1922"},{"ruleId":"1456","severity":2,"message":"1650","line":708,"column":39,"nodeType":"1441","messageId":"1458","endLine":708,"endColumn":46},{"ruleId":"1530","severity":2,"message":"1531","line":714,"column":29,"nodeType":"1532","messageId":"1533","endLine":714,"endColumn":30,"fix":"1923"},{"ruleId":"1456","severity":2,"message":"1650","line":738,"column":39,"nodeType":"1441","messageId":"1458","endLine":738,"endColumn":46},{"ruleId":"1530","severity":2,"message":"1531","line":744,"column":29,"nodeType":"1532","messageId":"1533","endLine":744,"endColumn":30,"fix":"1924"},{"ruleId":"1456","severity":2,"message":"1650","line":767,"column":39,"nodeType":"1441","messageId":"1458","endLine":767,"endColumn":46},{"ruleId":"1530","severity":2,"message":"1531","line":773,"column":29,"nodeType":"1532","messageId":"1533","endLine":773,"endColumn":30,"fix":"1925"},{"ruleId":"1456","severity":2,"message":"1650","line":796,"column":39,"nodeType":"1441","messageId":"1458","endLine":796,"endColumn":46},{"ruleId":"1530","severity":2,"message":"1531","line":802,"column":29,"nodeType":"1532","messageId":"1533","endLine":802,"endColumn":30,"fix":"1926"},{"ruleId":"1530","severity":2,"message":"1531","line":857,"column":13,"nodeType":"1532","messageId":"1533","endLine":857,"endColumn":14,"fix":"1927"},{"ruleId":"1456","severity":2,"message":"1659","line":876,"column":31,"nodeType":"1441","messageId":"1458","endLine":876,"endColumn":41},{"ruleId":"1530","severity":2,"message":"1531","line":880,"column":21,"nodeType":"1532","messageId":"1533","endLine":880,"endColumn":22,"fix":"1928"},{"ruleId":"1456","severity":2,"message":"1659","line":896,"column":33,"nodeType":"1441","messageId":"1458","endLine":896,"endColumn":43},{"ruleId":"1530","severity":2,"message":"1531","line":900,"column":23,"nodeType":"1532","messageId":"1533","endLine":900,"endColumn":24,"fix":"1929"},{"ruleId":"1456","severity":2,"message":"1659","line":909,"column":29,"nodeType":"1441","messageId":"1458","endLine":909,"endColumn":39},{"ruleId":"1530","severity":2,"message":"1531","line":913,"column":19,"nodeType":"1532","messageId":"1533","endLine":913,"endColumn":20,"fix":"1930"},{"ruleId":"1517","severity":2,"message":"1625","line":941,"column":27,"nodeType":"1521","endLine":941,"endColumn":38,"fix":"1931"},{"ruleId":"1456","severity":2,"message":"1664","line":950,"column":31,"nodeType":"1441","messageId":"1458","endLine":950,"endColumn":36},{"ruleId":"1530","severity":2,"message":"1531","line":954,"column":21,"nodeType":"1532","messageId":"1533","endLine":954,"endColumn":22,"fix":"1932"},{"ruleId":"1456","severity":2,"message":"1664","line":962,"column":29,"nodeType":"1441","messageId":"1458","endLine":962,"endColumn":34},{"ruleId":"1530","severity":2,"message":"1531","line":966,"column":19,"nodeType":"1532","messageId":"1533","endLine":966,"endColumn":20,"fix":"1933"},{"ruleId":"1503","severity":2,"message":"1504","line":987,"column":29,"nodeType":"1523","endLine":987,"endColumn":47},{"ruleId":"1517","severity":2,"message":"1569","line":44,"column":40,"nodeType":"1521","endLine":44,"endColumn":65,"fix":"1934"},{"ruleId":"1517","severity":2,"message":"1569","line":72,"column":48,"nodeType":"1521","endLine":72,"endColumn":73,"fix":"1935"},{"ruleId":"1517","severity":2,"message":"1571","line":76,"column":46,"nodeType":"1521","endLine":76,"endColumn":67,"fix":"1936"},{"ruleId":"1517","severity":2,"message":"1670","line":86,"column":24,"nodeType":"1521","endLine":86,"endColumn":53,"fix":"1937"},{"ruleId":"1517","severity":2,"message":"1672","line":86,"column":53,"nodeType":"1491","endLine":86,"endColumn":69,"fix":"1938"},{"ruleId":"1436","severity":2,"message":"1475","line":122,"column":1,"nodeType":null,"endLine":123,"endColumn":1,"fix":"1939"},{"ruleId":"1506","severity":2,"message":"1731","line":11,"column":24,"nodeType":"1508","endLine":11,"endColumn":29},{"ruleId":"1506","severity":2,"message":"1732","line":11,"column":31,"nodeType":"1508","endLine":11,"endColumn":44},{"ruleId":"1463","severity":2,"message":"1464","line":43,"column":5,"nodeType":"1465","messageId":"1466","endLine":47,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":44,"column":7,"nodeType":"1465","messageId":"1466","endLine":46,"endColumn":8},{"ruleId":"1456","severity":2,"message":"1733","line":51,"column":11,"nodeType":"1441","messageId":"1458","endLine":51,"endColumn":21},{"ruleId":"1463","severity":2,"message":"1464","line":65,"column":5,"nodeType":"1465","messageId":"1466","endLine":84,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":94,"column":5,"nodeType":"1465","messageId":"1466","endLine":98,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":95,"column":7,"nodeType":"1465","messageId":"1466","endLine":97,"endColumn":8},{"ruleId":"1456","severity":2,"message":"1734","line":102,"column":11,"nodeType":"1441","messageId":"1458","endLine":102,"endColumn":16},{"ruleId":"1463","severity":2,"message":"1464","line":107,"column":5,"nodeType":"1465","messageId":"1466","endLine":112,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":118,"column":5,"nodeType":"1465","messageId":"1466","endLine":124,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":120,"column":9,"nodeType":"1465","messageId":"1466","endLine":122,"endColumn":10},{"ruleId":"1436","severity":2,"message":"1735","line":190,"column":23,"nodeType":null,"endLine":190,"endColumn":23,"fix":"1940"},{"ruleId":"1517","severity":2,"message":"1683","line":214,"column":18,"nodeType":"1521","endLine":214,"endColumn":41,"fix":"1941"},{"ruleId":"1517","severity":2,"message":"1685","line":214,"column":41,"nodeType":"1491","endLine":214,"endColumn":44,"fix":"1942"},{"ruleId":"1517","severity":2,"message":"1687","line":214,"column":44,"nodeType":"1521","endLine":214,"endColumn":67,"fix":"1943"},{"ruleId":"1436","severity":2,"message":"1475","line":214,"column":67,"nodeType":null,"endLine":215,"endColumn":1,"fix":"1944"},{"ruleId":"1549","severity":2,"message":"1741","line":214,"column":67,"nodeType":"1491","endLine":216,"endColumn":1,"fix":"1945"},{"ruleId":"1436","severity":2,"message":"1743","line":216,"column":1,"nodeType":null,"endLine":216,"endColumn":1,"fix":"1946"},{"ruleId":"1577","severity":2,"message":"1578","line":216,"column":1,"nodeType":"1579","endLine":216,"endColumn":9,"fix":"1947"},{"ruleId":"1549","severity":2,"message":"1746","line":216,"column":1,"nodeType":"1579","endLine":216,"endColumn":9,"fix":"1948"},{"ruleId":"1530","severity":2,"message":"1531","line":228,"column":17,"nodeType":"1532","messageId":"1533","endLine":228,"endColumn":18,"fix":"1949"},{"ruleId":"1517","severity":2,"message":"1697","line":236,"column":18,"nodeType":"1521","endLine":236,"endColumn":40,"fix":"1950"},{"ruleId":"1517","severity":2,"message":"1685","line":236,"column":40,"nodeType":"1491","endLine":236,"endColumn":43,"fix":"1951"},{"ruleId":"1517","severity":2,"message":"1700","line":236,"column":43,"nodeType":"1521","endLine":236,"endColumn":65,"fix":"1952"},{"ruleId":"1436","severity":2,"message":"1475","line":236,"column":65,"nodeType":null,"endLine":237,"endColumn":1,"fix":"1953"},{"ruleId":"1549","severity":2,"message":"1741","line":236,"column":65,"nodeType":"1491","endLine":238,"endColumn":1,"fix":"1954"},{"ruleId":"1436","severity":2,"message":"1743","line":238,"column":1,"nodeType":null,"endLine":238,"endColumn":1,"fix":"1955"},{"ruleId":"1577","severity":2,"message":"1578","line":238,"column":1,"nodeType":"1579","endLine":238,"endColumn":9,"fix":"1956"},{"ruleId":"1549","severity":2,"message":"1746","line":238,"column":1,"nodeType":"1579","endLine":238,"endColumn":9,"fix":"1957"},{"ruleId":"1530","severity":2,"message":"1531","line":250,"column":17,"nodeType":"1532","messageId":"1533","endLine":250,"endColumn":18,"fix":"1958"},{"ruleId":"1517","severity":2,"message":"1708","line":258,"column":18,"nodeType":"1521","endLine":258,"endColumn":40,"fix":"1959"},{"ruleId":"1517","severity":2,"message":"1685","line":258,"column":40,"nodeType":"1491","endLine":258,"endColumn":43,"fix":"1960"},{"ruleId":"1517","severity":2,"message":"1711","line":258,"column":43,"nodeType":"1521","endLine":258,"endColumn":65,"fix":"1961"},{"ruleId":"1436","severity":2,"message":"1475","line":258,"column":65,"nodeType":null,"endLine":259,"endColumn":1,"fix":"1962"},{"ruleId":"1549","severity":2,"message":"1741","line":258,"column":65,"nodeType":"1491","endLine":260,"endColumn":1,"fix":"1963"},{"ruleId":"1436","severity":2,"message":"1743","line":260,"column":1,"nodeType":null,"endLine":260,"endColumn":1,"fix":"1964"},{"ruleId":"1577","severity":2,"message":"1578","line":260,"column":1,"nodeType":"1579","endLine":260,"endColumn":9,"fix":"1965"},{"ruleId":"1549","severity":2,"message":"1746","line":260,"column":1,"nodeType":"1579","endLine":260,"endColumn":9,"fix":"1966"},{"ruleId":"1530","severity":2,"message":"1531","line":272,"column":17,"nodeType":"1532","messageId":"1533","endLine":272,"endColumn":18,"fix":"1967"},{"ruleId":"1530","severity":2,"message":"1531","line":307,"column":21,"nodeType":"1532","messageId":"1533","endLine":307,"endColumn":22,"fix":"1968"},{"ruleId":"1530","severity":2,"message":"1531","line":344,"column":21,"nodeType":"1532","messageId":"1533","endLine":344,"endColumn":22,"fix":"1969"},{"ruleId":"1517","severity":2,"message":"1721","line":359,"column":16,"nodeType":"1521","endLine":359,"endColumn":27,"fix":"1970"},{"ruleId":"1517","severity":2,"message":"1685","line":359,"column":27,"nodeType":"1491","endLine":359,"endColumn":30,"fix":"1971"},{"ruleId":"1517","severity":2,"message":"1724","line":359,"column":30,"nodeType":"1521","endLine":359,"endColumn":41,"fix":"1972"},{"ruleId":"1436","severity":2,"message":"1475","line":359,"column":41,"nodeType":null,"endLine":360,"endColumn":1,"fix":"1973"},{"ruleId":"1549","severity":2,"message":"1746","line":359,"column":41,"nodeType":"1491","endLine":361,"endColumn":1,"fix":"1974"},{"ruleId":"1436","severity":2,"message":"1774","line":361,"column":1,"nodeType":null,"endLine":361,"endColumn":1,"fix":"1975"},{"ruleId":"1577","severity":2,"message":"1578","line":361,"column":1,"nodeType":"1579","endLine":361,"endColumn":9,"fix":"1976"},{"ruleId":"1549","severity":2,"message":"1777","line":361,"column":1,"nodeType":"1579","endLine":361,"endColumn":9,"fix":"1977"},{"ruleId":"1436","severity":2,"message":"1475","line":391,"column":28,"nodeType":null,"endLine":392,"endColumn":1,"fix":"1978"},{"ruleId":"1586","severity":2,"message":"1730","line":489,"column":35,"nodeType":"1441","messageId":"1588","endLine":489,"endColumn":40},{"ruleId":"1463","severity":2,"message":"1464","line":47,"column":5,"nodeType":"1465","messageId":"1466","endLine":51,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":48,"column":7,"nodeType":"1465","messageId":"1466","endLine":50,"endColumn":8},{"ruleId":"1456","severity":2,"message":"1675","line":55,"column":11,"nodeType":"1441","messageId":"1458","endLine":55,"endColumn":21},{"ruleId":"1463","severity":2,"message":"1464","line":69,"column":5,"nodeType":"1465","messageId":"1466","endLine":88,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":98,"column":5,"nodeType":"1465","messageId":"1466","endLine":102,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":99,"column":7,"nodeType":"1465","messageId":"1466","endLine":101,"endColumn":8},{"ruleId":"1456","severity":2,"message":"1676","line":106,"column":11,"nodeType":"1441","messageId":"1458","endLine":106,"endColumn":16},{"ruleId":"1463","severity":2,"message":"1464","line":111,"column":5,"nodeType":"1465","messageId":"1466","endLine":116,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":122,"column":5,"nodeType":"1465","messageId":"1466","endLine":128,"endColumn":6},{"ruleId":"1463","severity":2,"message":"1464","line":124,"column":9,"nodeType":"1465","messageId":"1466","endLine":126,"endColumn":10},{"ruleId":"1517","severity":2,"message":"1677","line":183,"column":17,"nodeType":"1678","endLine":183,"endColumn":31,"fix":"1979"},{"ruleId":"1517","severity":2,"message":"1680","line":188,"column":20,"nodeType":"1521","endLine":188,"endColumn":65,"fix":"1980"},{"ruleId":"1530","severity":2,"message":"1531","line":213,"column":23,"nodeType":"1532","messageId":"1533","endLine":213,"endColumn":24,"fix":"1981"},{"ruleId":"1517","severity":2,"message":"1683","line":237,"column":22,"nodeType":"1521","endLine":237,"endColumn":45,"fix":"1982"},{"ruleId":"1517","severity":2,"message":"1685","line":237,"column":45,"nodeType":"1491","endLine":237,"endColumn":48,"fix":"1983"},{"ruleId":"1517","severity":2,"message":"1687","line":237,"column":48,"nodeType":"1521","endLine":237,"endColumn":71,"fix":"1984"},{"ruleId":"1436","severity":2,"message":"1475","line":237,"column":71,"nodeType":null,"endLine":238,"endColumn":1,"fix":"1985"},{"ruleId":"1549","severity":2,"message":"1550","line":237,"column":71,"nodeType":"1491","endLine":239,"endColumn":1,"fix":"1986"},{"ruleId":"1436","severity":2,"message":"1691","line":239,"column":1,"nodeType":null,"endLine":239,"endColumn":1,"fix":"1987"},{"ruleId":"1577","severity":2,"message":"1578","line":239,"column":1,"nodeType":"1579","endLine":239,"endColumn":9,"fix":"1988"},{"ruleId":"1549","severity":2,"message":"1694","line":239,"column":1,"nodeType":"1579","endLine":239,"endColumn":9,"fix":"1989"},{"ruleId":"1530","severity":2,"message":"1531","line":251,"column":21,"nodeType":"1532","messageId":"1533","endLine":251,"endColumn":22,"fix":"1990"},{"ruleId":"1517","severity":2,"message":"1697","line":259,"column":22,"nodeType":"1521","endLine":259,"endColumn":44,"fix":"1991"},{"ruleId":"1517","severity":2,"message":"1685","line":259,"column":44,"nodeType":"1491","endLine":259,"endColumn":47,"fix":"1992"},{"ruleId":"1517","severity":2,"message":"1700","line":259,"column":47,"nodeType":"1521","endLine":259,"endColumn":69,"fix":"1993"},{"ruleId":"1436","severity":2,"message":"1475","line":259,"column":69,"nodeType":null,"endLine":260,"endColumn":1,"fix":"1994"},{"ruleId":"1549","severity":2,"message":"1550","line":259,"column":69,"nodeType":"1491","endLine":261,"endColumn":1,"fix":"1995"},{"ruleId":"1436","severity":2,"message":"1691","line":261,"column":1,"nodeType":null,"endLine":261,"endColumn":1,"fix":"1996"},{"ruleId":"1577","severity":2,"message":"1578","line":261,"column":1,"nodeType":"1579","endLine":261,"endColumn":9,"fix":"1997"},{"ruleId":"1549","severity":2,"message":"1694","line":261,"column":1,"nodeType":"1579","endLine":261,"endColumn":9,"fix":"1998"},{"ruleId":"1530","severity":2,"message":"1531","line":273,"column":21,"nodeType":"1532","messageId":"1533","endLine":273,"endColumn":22,"fix":"1999"},{"ruleId":"1517","severity":2,"message":"1708","line":281,"column":22,"nodeType":"1521","endLine":281,"endColumn":44,"fix":"2000"},{"ruleId":"1517","severity":2,"message":"1685","line":281,"column":44,"nodeType":"1491","endLine":281,"endColumn":47,"fix":"2001"},{"ruleId":"1517","severity":2,"message":"1711","line":281,"column":47,"nodeType":"1521","endLine":281,"endColumn":69,"fix":"2002"},{"ruleId":"1436","severity":2,"message":"1475","line":281,"column":69,"nodeType":null,"endLine":282,"endColumn":1,"fix":"2003"},{"ruleId":"1549","severity":2,"message":"1550","line":281,"column":69,"nodeType":"1491","endLine":283,"endColumn":1,"fix":"2004"},{"ruleId":"1436","severity":2,"message":"1691","line":283,"column":1,"nodeType":null,"endLine":283,"endColumn":1,"fix":"2005"},{"ruleId":"1577","severity":2,"message":"1578","line":283,"column":1,"nodeType":"1579","endLine":283,"endColumn":9,"fix":"2006"},{"ruleId":"1549","severity":2,"message":"1694","line":283,"column":1,"nodeType":"1579","endLine":283,"endColumn":9,"fix":"2007"},{"ruleId":"1530","severity":2,"message":"1531","line":295,"column":21,"nodeType":"1532","messageId":"1533","endLine":295,"endColumn":22,"fix":"2008"},{"ruleId":"1530","severity":2,"message":"1531","line":330,"column":25,"nodeType":"1532","messageId":"1533","endLine":330,"endColumn":26,"fix":"2009"},{"ruleId":"1530","severity":2,"message":"1531","line":367,"column":25,"nodeType":"1532","messageId":"1533","endLine":367,"endColumn":26,"fix":"2010"},{"ruleId":"1517","severity":2,"message":"1721","line":382,"column":20,"nodeType":"1521","endLine":382,"endColumn":31,"fix":"2011"},{"ruleId":"1517","severity":2,"message":"1685","line":382,"column":31,"nodeType":"1491","endLine":382,"endColumn":34,"fix":"2012"},{"ruleId":"1517","severity":2,"message":"1724","line":382,"column":34,"nodeType":"1521","endLine":382,"endColumn":45,"fix":"2013"},{"ruleId":"1517","severity":2,"message":"1726","line":382,"column":45,"nodeType":"1491","endLine":383,"endColumn":17,"fix":"2014"},{"ruleId":"1728","severity":2,"message":"1729","line":423,"column":3,"nodeType":"1508","endLine":423,"endColumn":25},{"ruleId":"1586","severity":2,"message":"1730","line":527,"column":35,"nodeType":"1441","messageId":"1588","endLine":527,"endColumn":40},{"ruleId":"1436","severity":2,"message":"1484","line":48,"column":3,"nodeType":null,"endLine":48,"endColumn":3,"fix":"2015"},{"ruleId":"1503","severity":2,"message":"1504","line":43,"column":31,"nodeType":"1441","endLine":43,"endColumn":41},{"ruleId":"1456","severity":2,"message":"1785","line":45,"column":34,"nodeType":"1441","messageId":"1458","endLine":45,"endColumn":39},{"ruleId":"1503","severity":2,"message":"1504","line":49,"column":36,"nodeType":"1523","endLine":49,"endColumn":63},{"ruleId":"1436","severity":2,"message":"1786","line":62,"column":46,"nodeType":null,"endLine":64,"endColumn":1,"fix":"2016"},{"ruleId":"1549","severity":2,"message":"1788","line":63,"column":1,"nodeType":"1521","endLine":63,"endColumn":6,"fix":"2017"},{"ruleId":"1549","severity":2,"message":"1788","line":64,"column":1,"nodeType":"1790","endLine":64,"endColumn":10,"fix":"2018"},{"ruleId":"1503","severity":2,"message":"1504","line":71,"column":46,"nodeType":"1523","endLine":71,"endColumn":62},{"ruleId":"1436","severity":2,"message":"1795","line":16,"column":33,"nodeType":null,"endLine":18,"endColumn":18,"fix":"2019"},{"ruleId":"1436","severity":2,"message":"1797","line":24,"column":72,"nodeType":null,"endLine":26,"endColumn":22,"fix":"2020"},{"ruleId":"1517","severity":2,"message":"1559","line":26,"column":24,"nodeType":"1521","endLine":26,"endColumn":29,"fix":"2021"},{"ruleId":"1517","severity":2,"message":"1518","line":33,"column":22,"nodeType":"1491","endLine":33,"endColumn":23,"fix":"2022"},{"ruleId":"1517","severity":2,"message":"1801","line":33,"column":23,"nodeType":"1521","endLine":33,"endColumn":38,"fix":"2023"},{"ruleId":"1436","severity":2,"message":"1803","line":42,"column":12,"nodeType":null,"endLine":43,"endColumn":11,"fix":"2024"},{"ruleId":"1436","severity":2,"message":"1803","line":49,"column":12,"nodeType":null,"endLine":50,"endColumn":11,"fix":"2025"},{"ruleId":"1436","severity":2,"message":"1475","line":73,"column":28,"nodeType":null,"endLine":74,"endColumn":1,"fix":"2026"},{"ruleId":"1456","severity":2,"message":"1824","line":22,"column":13,"nodeType":"1441","messageId":"1458","endLine":22,"endColumn":23},{"ruleId":"1459","severity":2,"message":"1487","line":39,"column":5,"nodeType":"1461","messageId":"1462","endLine":41,"endColumn":7},{"ruleId":"1452","severity":2,"message":"1453","line":49,"column":11,"nodeType":"1454","messageId":"1455","endLine":49,"endColumn":49},{"ruleId":"1517","severity":2,"message":"1825","line":151,"column":29,"nodeType":"1521","endLine":151,"endColumn":60,"fix":"2027"},{"ruleId":"1436","severity":2,"message":"1827","line":165,"column":61,"nodeType":null,"endLine":165,"endColumn":61,"fix":"2028"},{"ruleId":"1436","severity":2,"message":"1475","line":169,"column":24,"nodeType":null,"endLine":170,"endColumn":1,"fix":"2029"},{"ruleId":"1517","severity":2,"message":"1685","line":29,"column":24,"nodeType":"1491","endLine":29,"endColumn":27,"fix":"2030"},{"ruleId":"1517","severity":2,"message":"1810","line":29,"column":27,"nodeType":"1521","endLine":29,"endColumn":51,"fix":"2031"},{"ruleId":"1517","severity":2,"message":"1812","line":35,"column":68,"nodeType":"1491","endLine":35,"endColumn":70,"fix":"2032"},{"ruleId":"1517","severity":2,"message":"1559","line":35,"column":70,"nodeType":"1521","endLine":35,"endColumn":75,"fix":"2033"},{"ruleId":"1517","severity":2,"message":"1518","line":41,"column":18,"nodeType":"1491","endLine":41,"endColumn":19,"fix":"2034"},{"ruleId":"1517","severity":2,"message":"1818","line":41,"column":19,"nodeType":"1521","endLine":41,"endColumn":31,"fix":"2035"},{"ruleId":"1456","severity":2,"message":"1836","line":54,"column":17,"nodeType":"1441","messageId":"1458","endLine":54,"endColumn":25},{"ruleId":"1517","severity":2,"message":"1518","line":61,"column":14,"nodeType":"1491","endLine":61,"endColumn":15,"fix":"2036"},{"ruleId":"1517","severity":2,"message":"1838","line":61,"column":15,"nodeType":"1521","endLine":61,"endColumn":38,"fix":"2037"},{"ruleId":"1728","severity":2,"message":"1840","line":80,"column":5,"nodeType":"1508","endLine":80,"endColumn":30},{"ruleId":"1436","severity":2,"message":"1484","line":175,"column":3,"nodeType":null,"endLine":175,"endColumn":3,"fix":"2038"},{"ruleId":"1452","severity":2,"message":"1453","line":34,"column":5,"nodeType":"1454","messageId":"1455","endLine":36,"endColumn":45},{"ruleId":"1452","severity":2,"message":"1453","line":41,"column":5,"nodeType":"1454","messageId":"1455","endLine":43,"endColumn":45},{"ruleId":"1517","severity":2,"message":"1781","line":64,"column":30,"nodeType":"1678","endLine":64,"endColumn":39,"fix":"2039"},{"ruleId":"1517","severity":2,"message":"1781","line":70,"column":30,"nodeType":"1678","endLine":70,"endColumn":39,"fix":"2040"},{"ruleId":"1436","severity":2,"message":"1475","line":107,"column":1,"nodeType":null,"endLine":108,"endColumn":1,"fix":"2041"},{"ruleId":"1503","severity":2,"message":"1504","line":57,"column":29,"nodeType":"1441","endLine":57,"endColumn":34},{"ruleId":"1456","severity":2,"message":"1794","line":59,"column":39,"nodeType":"1441","messageId":"1458","endLine":59,"endColumn":44},{"ruleId":"1503","severity":2,"message":"1504","line":75,"column":44,"nodeType":"1523","endLine":75,"endColumn":60},{"ruleId":"1503","severity":2,"message":"1504","line":42,"column":29,"nodeType":"1441","endLine":42,"endColumn":34},{"ruleId":"1456","severity":2,"message":"1792","line":43,"column":31,"nodeType":"1441","messageId":"1458","endLine":43,"endColumn":36},{"ruleId":"1456","severity":2,"message":"1793","line":43,"column":38,"nodeType":"1441","messageId":"1458","endLine":43,"endColumn":43},{"ruleId":"1503","severity":2,"message":"1504","line":46,"column":39,"nodeType":"1523","endLine":46,"endColumn":61},{"ruleId":"1503","severity":2,"message":"1504","line":58,"column":42,"nodeType":"1523","endLine":58,"endColumn":58},{"ruleId":"1456","severity":2,"message":"1807","line":15,"column":13,"nodeType":"1441","messageId":"1458","endLine":15,"endColumn":17},{"ruleId":"1517","severity":2,"message":"1808","line":31,"column":32,"nodeType":"1491","endLine":31,"endColumn":36,"fix":"2042"},{"ruleId":"1517","severity":2,"message":"1810","line":31,"column":36,"nodeType":"1521","endLine":31,"endColumn":60,"fix":"2043"},{"ruleId":"1517","severity":2,"message":"1812","line":36,"column":74,"nodeType":"1491","endLine":37,"endColumn":1,"fix":"2044"},{"ruleId":"1436","severity":2,"message":"1475","line":36,"column":76,"nodeType":null,"endLine":37,"endColumn":1,"fix":"2045"},{"ruleId":"1549","severity":2,"message":"1815","line":37,"column":1,"nodeType":"1521","endLine":37,"endColumn":6,"fix":"2046"},{"ruleId":"1517","severity":2,"message":"1518","line":44,"column":24,"nodeType":"1491","endLine":44,"endColumn":25,"fix":"2047"},{"ruleId":"1517","severity":2,"message":"1818","line":44,"column":25,"nodeType":"1521","endLine":44,"endColumn":37,"fix":"2048"},{"ruleId":"1517","severity":2,"message":"1518","line":51,"column":18,"nodeType":"1491","endLine":51,"endColumn":19,"fix":"2049"},{"ruleId":"1517","severity":2,"message":"1821","line":51,"column":19,"nodeType":"1521","endLine":51,"endColumn":69,"fix":"2050"},{"ruleId":"1517","severity":2,"message":"1821","line":61,"column":16,"nodeType":"1521","endLine":61,"endColumn":66,"fix":"2051"},{"ruleId":"1452","severity":2,"message":"1453","line":20,"column":5,"nodeType":"1454","messageId":"1455","endLine":22,"endColumn":34},{"ruleId":"1456","severity":2,"message":"1482","line":40,"column":15,"nodeType":"1441","messageId":"1458","endLine":40,"endColumn":21},{"ruleId":"1456","severity":2,"message":"1482","line":49,"column":15,"nodeType":"1441","messageId":"1458","endLine":49,"endColumn":21},{"ruleId":"1456","severity":2,"message":"1483","line":62,"column":11,"nodeType":"1441","messageId":"1458","endLine":62,"endColumn":23},{"ruleId":"1452","severity":2,"message":"1453","line":64,"column":7,"nodeType":"1454","messageId":"1455","endLine":66,"endColumn":61},"lines-around-directive",["2052"],"global-require",[],"no-buffer-constructor",[],"no-new-require",[],"no-path-concat",[],"import/prefer-default-export","Prefer default export.","ExportNamedDeclaration","prettier/prettier","Replace `'·'` with `\"·\"`",{"range":"2053","text":"2054"},"no-use-before-define","'capitalize' was used before it was defined.","Identifier","usedBeforeDefined","Replace `'of',·'and'` with `\"of\",·\"and\"`",{"range":"2055","text":"2056"},"no-else-return","Unnecessary 'else' after 'return'.","BlockStatement","unexpected",{"range":"2057","text":"2058"},"Insert `;`",{"range":"2059","text":"2060"},"no-unused-expressions","Expected an assignment or function call and instead saw an expression.","ExpressionStatement","unusedExpression","no-shadow","'item' is already declared in the upper scope on line 90 column 11.","noShadow","consistent-return","Async arrow function expected no return value.","ReturnStatement","unexpectedReturnValue","no-restricted-syntax","iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.","ForOfStatement","restrictedSyntax","'firstName' is already declared in the upper scope on line 6 column 10.","'lastName' is already declared in the upper scope on line 7 column 10.","'address' is already declared in the upper scope on line 8 column 10.","'zipCode' is already declared in the upper scope on line 10 column 10.","'city' is already declared in the upper scope on line 9 column 10.","'country' is already declared in the upper scope on line 11 column 10.","'phone' is already declared in the upper scope on line 13 column 10.","'email' is already declared in the upper scope on line 12 column 10.","Delete `⏎`",{"range":"2061","text":"2062"},"'name' is already declared in the upper scope on line 6 column 10.","'number' is already declared in the upper scope on line 7 column 10.","'date' is already declared in the upper scope on line 8 column 10.","'cvc' is already declared in the upper scope on line 9 column 10.","'editCard' was used before it was defined.","'slides' is already declared in the upper scope on line 3 column 22.","'slidesGroups' is already declared in the upper scope on line 6 column 10.","Insert `⏎`",{"range":"2063","text":"2064"},"'favorites' is already declared in the upper scope on line 15 column 10.","Arrow function expected no return value.",{"range":"2065","text":"2062"},"react/no-unescaped-entities","`'` can be escaped with `'`, `‘`, `'`, `’`.","Literal","react/jsx-props-no-spreading","Prop spreading is forbidden","JSXSpreadAttribute","'cart' is already declared in the upper scope on line 14 column 10.","'currentUser' is already declared in the upper scope on line 19 column 11.","no-await-in-loop","Unexpected `await` inside a loop.","AwaitExpression","unexpectedAwait","'colors' was used before it was defined.","'slides' is already declared in the upper scope on line 13 column 10.","react/no-array-index-key","Do not use Array index in keys",{"range":"2066","text":"2062"},"react/prop-types","'component' is missing in props validation","Property","'order' is already declared in the upper scope on line 9 column 10.","'filters' is already declared in the upper scope on line 16 column 10.","'sort' is already declared in the upper scope on line 15 column 10.","'displayedItems' is already declared in the upper scope on line 27 column 10.","'designs' is already declared in the upper scope on line 8 column 10.","'item' is already declared in the upper scope on line 24 column 10.","'e' is already declared in the upper scope on line 90 column 34.","'recommendations' is already declared in the upper scope on line 37 column 10.","react/jsx-one-expression-per-line","`£` must be placed on a new line",{"range":"2067","text":"2068"},"`{currentPrice}` must be placed on a new line","JSXExpressionContainer",{"range":"2069","text":"2070"},"TemplateLiteral","`{currentColor.description}` must be placed on a new line",{"range":"2071","text":"2072"},"`{option}` must be placed on a new line",{"range":"2073","text":"2074"},"`: ` must be placed on a new line",{"range":"2075","text":"2076"},"react/jsx-curly-newline","Unexpected newline before '{'.","Punctuator","unexpectedBefore",{"range":"2077","text":"2062"},"'quantity' is already declared in the upper scope on line 34 column 10.","`{dimension}` must be placed on a new line",{"range":"2078","text":"2079"},{"range":"2080","text":"2076"},"`{info}` must be placed on a new line",{"range":"2081","text":"2082"},{"range":"2083","text":"2076"},"'design' is already declared in the upper scope on line 10 column 10.","'items' is already declared in the upper scope on line 11 column 10.","'filters' is already declared in the upper scope on line 15 column 10.","'sort' is already declared in the upper scope on line 14 column 10.","'displayedItems' is already declared in the upper scope on line 26 column 10.","'cards' is already declared in the upper scope on line 26 column 10.",{"range":"2084","text":"2062"},"react/jsx-indent","Expected indentation of 20 space characters but found 0.",{"range":"2085","text":"2086"},{"range":"2087","text":"2062"},{"range":"2088","text":"2086"},"Replace `⏎{'·'}⏎` with `·`",{"range":"2089","text":"2090"},"Expected indentation of 30 space characters but found 0.",{"range":"2091","text":"2092"},{"range":"2093","text":"2094"},"`{\" \"}` must be placed on a new line",{"range":"2095","text":"2096"},"'number' is already declared in the upper scope on line 22 column 10.","'cvc' is already declared in the upper scope on line 24 column 10.","'addresses' is already declared in the upper scope on line 20 column 10.","'address' is already declared in the upper scope on line 31 column 5.","`{address.lastName}` must be placed on a new line",{"range":"2097","text":"2098"},"`{address.city}` must be placed on a new line",{"range":"2099","text":"2100"},"`{order.shipping.lastName}` must be placed on a new line",{"range":"2101","text":"2102"},"`{order.shipping.city}` must be placed on a new line",{"range":"2103","text":"2104"},"Replace `⏎··············{'·'}⏎··············has·been·confirmed.·You·will·be` with `·has·been·confirmed.·You·will·be⏎·············`",{"range":"2105","text":"2106"},"Delete `··`",{"range":"2107","text":"2062"},"react/jsx-closing-tag-location","Expected closing tag to match indentation of opening.","JSXClosingElement",{"range":"2108","text":"2109"},"Expected indentation of 12 space characters but found 14.",{"range":"2110","text":"2109"},{"range":"2111","text":"2096"},{"range":"2112","text":"2096"},"'orders' is already declared in the upper scope on line 10 column 10.","no-unused-vars","'setLinks' is assigned a value but never used.","unusedVar","'addresses' is already declared in the upper scope on line 13 column 10.","'address' is already declared in the upper scope on line 27 column 5.",{"range":"2113","text":"2098"},{"range":"2114","text":"2100"},{"range":"2115","text":"2062"},"'cards' is already declared in the upper scope on line 14 column 10.","`{card.number.slice(-4)}` must be placed on a new line",{"range":"2116","text":"2117"},"Replace `⏎{'·'}⏎(Last·4·digits)⏎` with `·(Last·4·digits)`",{"range":"2118","text":"2119"},"Expected indentation of 22 space characters but found 0.",{"range":"2120","text":"2121"},{"range":"2122","text":"2123"},{"range":"2124","text":"2086"},{"range":"2125","text":"2086"},"'number' is already declared in the upper scope on line 25 column 5.","'cvc' is already declared in the upper scope on line 29 column 5.","'categories' is already declared in the upper scope on line 10 column 10.","'cart' is already declared in the upper scope on line 27 column 10.",{"range":"2126","text":"2062"},{"range":"2127","text":"2062"},{"range":"2128","text":"2096"},"`. ` must be placed on a new line",{"range":"2129","text":"2130"},{"range":"2131","text":"2130"},"'flip' is missing in props validation","'isPaying' is missing in props validation",{"range":"2132","text":"2096"},{"range":"2133","text":"2068"},"`{price}` must be placed on a new line",{"range":"2134","text":"2135"},{"range":"2136","text":"2062"},"'e' is already declared in the upper scope on line 61 column 31.",{"range":"2137","text":"2062"},{"range":"2138","text":"2062"},{"range":"2139","text":"2062"},"`{index + 1}` must be placed on a new line",{"range":"2140","text":"2141"},"'materials' is already declared in the upper scope on line 18 column 10.",{"range":"2142","text":"2062"},{"range":"2143","text":"2062"},"'description' is already declared in the upper scope on line 20 column 10.",{"range":"2144","text":"2141"},"'description' is already declared in the upper scope on line 381 column 29.",{"range":"2145","text":"2062"},{"range":"2146","text":"2062"},{"range":"2147","text":"2062"},"'colors' is already declared in the upper scope on line 22 column 10.",{"range":"2148","text":"2062"},{"range":"2149","text":"2062"},{"range":"2150","text":"2062"},"prefer-destructuring","Use array destructuring.","AssignmentExpression","preferDestructuring",{"range":"2151","text":"2062"},{"range":"2152","text":"2141"},"'categories' is already declared in the upper scope on line 21 column 10.",{"range":"2153","text":"2062"},{"range":"2154","text":"2062"},{"range":"2155","text":"2062"},"'options' is already declared in the upper scope on line 36 column 10.",{"range":"2156","text":"2062"},{"range":"2157","text":"2062"},{"range":"2158","text":"2062"},{"range":"2159","text":"2062"},{"range":"2160","text":"2062"},{"range":"2161","text":"2062"},{"range":"2162","text":"2062"},{"range":"2163","text":"2062"},"'additional' is already declared in the upper scope on line 30 column 10.",{"range":"2164","text":"2062"},{"range":"2165","text":"2062"},{"range":"2166","text":"2062"},{"range":"2167","text":"2141"},"'seats' is already declared in the upper scope on line 53 column 10.",{"range":"2168","text":"2062"},{"range":"2169","text":"2062"},{"range":"2170","text":"2102"},{"range":"2171","text":"2102"},{"range":"2172","text":"2104"},"`{order.card.number.slice(-4)}` must be placed on a new line",{"range":"2173","text":"2174"},"` (Last 4 digits)` must be placed on a new line",{"range":"2175","text":"2176"},{"range":"2177","text":"2062"},"'dimensions' is already declared in the upper scope on line 16 column 10.","'price' is already declared in the upper scope on line 21 column 10.","`FilterIcon` must be placed on a new line","JSXElement",{"range":"2178","text":"2179"},"`{areColorsOpen ? <AngleUp /> : <AngleDown />}` must be placed on a new line",{"range":"2180","text":"2181"},{"range":"2182","text":"2062"},"`{dimensions.height.min}` must be placed on a new line",{"range":"2183","text":"2184"},"` - ` must be placed on a new line",{"range":"2185","text":"2186"},"`{dimensions.height.max}` must be placed on a new line",{"range":"2187","text":"2188"},{"range":"2189","text":"2062"},{"range":"2190","text":"2191"},"Insert `··················`",{"range":"2192","text":"2193"},{"range":"2194","text":"2193"},"Expected indentation of 18 space characters but found 0.",{"range":"2195","text":"2193"},{"range":"2196","text":"2062"},"`{dimensions.width.min}` must be placed on a new line",{"range":"2197","text":"2198"},{"range":"2199","text":"2186"},"`{dimensions.width.max}` must be placed on a new line",{"range":"2200","text":"2201"},{"range":"2202","text":"2062"},{"range":"2203","text":"2191"},{"range":"2204","text":"2193"},{"range":"2205","text":"2193"},{"range":"2206","text":"2193"},{"range":"2207","text":"2062"},"`{dimensions.depth.min}` must be placed on a new line",{"range":"2208","text":"2209"},{"range":"2210","text":"2186"},"`{dimensions.depth.max}` must be placed on a new line",{"range":"2211","text":"2212"},{"range":"2213","text":"2062"},{"range":"2214","text":"2191"},{"range":"2215","text":"2193"},{"range":"2216","text":"2193"},{"range":"2217","text":"2193"},{"range":"2218","text":"2062"},{"range":"2219","text":"2062"},{"range":"2220","text":"2062"},"`{price.min}` must be placed on a new line",{"range":"2221","text":"2222"},{"range":"2223","text":"2186"},"`{price.max}` must be placed on a new line",{"range":"2224","text":"2225"},"`) ` must be placed on a new line",{"range":"2226","text":"2227"},"react/forbid-prop-types","Prop type `array` is forbidden","'props' is defined but never used.","'items' is missing in props validation","'handleFilters' is missing in props validation","'dimensions' is already declared in the upper scope on line 14 column 10.","'price' is already declared in the upper scope on line 19 column 10.","Insert `⏎··················`",{"range":"2228","text":"2229"},{"range":"2230","text":"2184"},{"range":"2231","text":"2186"},{"range":"2232","text":"2188"},{"range":"2233","text":"2062"},"Expected indentation of 16 space characters but found 0.",{"range":"2234","text":"2235"},"Insert `··············`",{"range":"2236","text":"2237"},{"range":"2238","text":"2237"},"Expected indentation of 14 space characters but found 0.",{"range":"2239","text":"2237"},{"range":"2240","text":"2062"},{"range":"2241","text":"2198"},{"range":"2242","text":"2186"},{"range":"2243","text":"2201"},{"range":"2244","text":"2062"},{"range":"2245","text":"2235"},{"range":"2246","text":"2237"},{"range":"2247","text":"2237"},{"range":"2248","text":"2237"},{"range":"2249","text":"2062"},{"range":"2250","text":"2209"},{"range":"2251","text":"2186"},{"range":"2252","text":"2212"},{"range":"2253","text":"2062"},{"range":"2254","text":"2235"},{"range":"2255","text":"2237"},{"range":"2256","text":"2237"},{"range":"2257","text":"2237"},{"range":"2258","text":"2062"},{"range":"2259","text":"2062"},{"range":"2260","text":"2062"},{"range":"2261","text":"2222"},{"range":"2262","text":"2186"},{"range":"2263","text":"2225"},{"range":"2264","text":"2062"},{"range":"2265","text":"2266"},"Insert `············`",{"range":"2267","text":"2109"},{"range":"2268","text":"2109"},"Expected indentation of 12 space characters but found 0.",{"range":"2269","text":"2109"},{"range":"2270","text":"2062"},{"range":"2271","text":"2064"},"`Arrow` must be placed on a new line",{"range":"2272","text":"2273"},{"range":"2274","text":"2273"},{"range":"2275","text":"2062"},"'slide' is already declared in the upper scope on line 41 column 34.","Delete `⏎{'·'}⏎`",{"range":"2276","text":"2062"},"Expected indentation of 36 space characters but found 0.",{"range":"2277","text":"2278"},"JSXOpeningElement",{"range":"2279","text":"2278"},"'slide' is already declared in the upper scope on line 40 column 32.","'index' is already declared in the upper scope on line 40 column 39.","'index' is already declared in the upper scope on line 55 column 39.","Delete `⏎··················{'·'}⏎·················`",{"range":"2280","text":"2062"},"Delete `⏎······················{'·'}⏎·····················`",{"range":"2281","text":"2062"},{"range":"2282","text":"2096"},{"range":"2283","text":"2068"},"`{product.price}` must be placed on a new line",{"range":"2284","text":"2285"},"Delete `⏎··········`",{"range":"2286","text":"2062"},{"range":"2287","text":"2062"},{"range":"2288","text":"2062"},"'cart' is already declared in the upper scope on line 8 column 10.","` in ` must be placed on a new line",{"range":"2289","text":"2290"},"`{item.color.description}` must be placed on a new line",{"range":"2291","text":"2292"},"` -` must be placed on a new line",{"range":"2293","text":"2294"},{"range":"2295","text":"2062"},"Expected indentation of 24 space characters but found 0.",{"range":"2296","text":"2297"},{"range":"2298","text":"2068"},"`{item.price}` must be placed on a new line",{"range":"2299","text":"2300"},{"range":"2301","text":"2068"},"`{cart.reduce((sum, item) => sum + +item.price, 0)}` must be placed on a new line",{"range":"2302","text":"2303"},{"range":"2304","text":"2305"},"'categories' is already declared in the upper scope on line 13 column 10.","`{formatNavLink(activeCategory)}` must be placed on a new line",{"range":"2306","text":"2307"},"Insert `·`",{"range":"2308","text":"2090"},{"range":"2309","text":"2062"},{"range":"2310","text":"2186"},{"range":"2311","text":"2292"},{"range":"2312","text":"2186"},{"range":"2313","text":"2096"},{"range":"2314","text":"2068"},{"range":"2315","text":"2300"},"'quantity' is already declared in the upper scope on line 12 column 10.",{"range":"2316","text":"2068"},"`{item.price * quantity}` must be placed on a new line",{"range":"2317","text":"2318"},"Prop type `object` is forbidden",{"range":"2319","text":"2064"},["2052"],[],[],[],[],{"range":"2320","text":"2064"},{"range":"2321","text":"2062"},{"range":"2322","text":"2064"},{"range":"2323","text":"2062"},{"range":"2324","text":"2068"},{"range":"2325","text":"2070"},{"range":"2326","text":"2072"},{"range":"2327","text":"2074"},{"range":"2328","text":"2076"},{"range":"2329","text":"2062"},{"range":"2330","text":"2079"},{"range":"2331","text":"2076"},{"range":"2332","text":"2082"},{"range":"2333","text":"2076"},{"range":"2334","text":"2062"},{"range":"2335","text":"2086"},{"range":"2336","text":"2062"},{"range":"2337","text":"2086"},{"range":"2338","text":"2090"},{"range":"2339","text":"2092"},{"range":"2340","text":"2094"},{"range":"2341","text":"2096"},{"range":"2342","text":"2098"},{"range":"2343","text":"2100"},{"range":"2344","text":"2102"},{"range":"2345","text":"2104"},{"range":"2346","text":"2106"},{"range":"2347","text":"2062"},{"range":"2348","text":"2109"},{"range":"2349","text":"2109"},{"range":"2350","text":"2096"},{"range":"2351","text":"2096"},{"range":"2352","text":"2098"},{"range":"2353","text":"2100"},{"range":"2354","text":"2062"},{"range":"2355","text":"2117"},{"range":"2356","text":"2119"},{"range":"2357","text":"2121"},{"range":"2358","text":"2123"},{"range":"2359","text":"2086"},{"range":"2360","text":"2086"},{"range":"2361","text":"2062"},{"range":"2362","text":"2062"},{"range":"2363","text":"2062"},{"range":"2364","text":"2054"},{"range":"2365","text":"2056"},{"range":"2366","text":"2058"},{"range":"2367","text":"2060"},{"range":"2368","text":"2096"},{"range":"2369","text":"2130"},{"range":"2370","text":"2130"},{"range":"2371","text":"2096"},{"range":"2372","text":"2068"},{"range":"2373","text":"2135"},{"range":"2374","text":"2062"},{"range":"2375","text":"2062"},{"range":"2376","text":"2062"},{"range":"2377","text":"2062"},{"range":"2378","text":"2141"},{"range":"2379","text":"2062"},{"range":"2380","text":"2062"},{"range":"2381","text":"2141"},{"range":"2382","text":"2062"},{"range":"2383","text":"2062"},{"range":"2384","text":"2062"},{"range":"2385","text":"2062"},{"range":"2386","text":"2062"},{"range":"2387","text":"2062"},{"range":"2388","text":"2062"},{"range":"2389","text":"2141"},{"range":"2390","text":"2062"},{"range":"2391","text":"2062"},{"range":"2392","text":"2062"},{"range":"2393","text":"2062"},{"range":"2394","text":"2062"},{"range":"2395","text":"2062"},{"range":"2396","text":"2062"},{"range":"2397","text":"2062"},{"range":"2398","text":"2062"},{"range":"2399","text":"2062"},{"range":"2400","text":"2062"},{"range":"2401","text":"2062"},{"range":"2402","text":"2062"},{"range":"2403","text":"2062"},{"range":"2404","text":"2141"},{"range":"2405","text":"2062"},{"range":"2406","text":"2062"},{"range":"2407","text":"2102"},{"range":"2408","text":"2102"},{"range":"2409","text":"2104"},{"range":"2410","text":"2174"},{"range":"2411","text":"2176"},{"range":"2412","text":"2062"},{"range":"2413","text":"2229"},{"range":"2414","text":"2184"},{"range":"2415","text":"2186"},{"range":"2416","text":"2188"},{"range":"2417","text":"2062"},{"range":"2418","text":"2235"},{"range":"2419","text":"2237"},{"range":"2420","text":"2237"},{"range":"2421","text":"2237"},{"range":"2422","text":"2062"},{"range":"2423","text":"2198"},{"range":"2424","text":"2186"},{"range":"2425","text":"2201"},{"range":"2426","text":"2062"},{"range":"2427","text":"2235"},{"range":"2428","text":"2237"},{"range":"2429","text":"2237"},{"range":"2430","text":"2237"},{"range":"2431","text":"2062"},{"range":"2432","text":"2209"},{"range":"2433","text":"2186"},{"range":"2434","text":"2212"},{"range":"2435","text":"2062"},{"range":"2436","text":"2235"},{"range":"2437","text":"2237"},{"range":"2438","text":"2237"},{"range":"2439","text":"2237"},{"range":"2440","text":"2062"},{"range":"2441","text":"2062"},{"range":"2442","text":"2062"},{"range":"2443","text":"2222"},{"range":"2444","text":"2186"},{"range":"2445","text":"2225"},{"range":"2446","text":"2062"},{"range":"2447","text":"2266"},{"range":"2448","text":"2109"},{"range":"2449","text":"2109"},{"range":"2450","text":"2109"},{"range":"2451","text":"2062"},{"range":"2452","text":"2179"},{"range":"2453","text":"2181"},{"range":"2454","text":"2062"},{"range":"2455","text":"2184"},{"range":"2456","text":"2186"},{"range":"2457","text":"2188"},{"range":"2458","text":"2062"},{"range":"2459","text":"2191"},{"range":"2460","text":"2193"},{"range":"2461","text":"2193"},{"range":"2462","text":"2193"},{"range":"2463","text":"2062"},{"range":"2464","text":"2198"},{"range":"2465","text":"2186"},{"range":"2466","text":"2201"},{"range":"2467","text":"2062"},{"range":"2468","text":"2191"},{"range":"2469","text":"2193"},{"range":"2470","text":"2193"},{"range":"2471","text":"2193"},{"range":"2472","text":"2062"},{"range":"2473","text":"2209"},{"range":"2474","text":"2186"},{"range":"2475","text":"2212"},{"range":"2476","text":"2062"},{"range":"2477","text":"2191"},{"range":"2478","text":"2193"},{"range":"2479","text":"2193"},{"range":"2480","text":"2193"},{"range":"2481","text":"2062"},{"range":"2482","text":"2062"},{"range":"2483","text":"2062"},{"range":"2484","text":"2222"},{"range":"2485","text":"2186"},{"range":"2486","text":"2225"},{"range":"2487","text":"2227"},{"range":"2488","text":"2064"},{"range":"2489","text":"2062"},{"range":"2490","text":"2278"},{"range":"2491","text":"2278"},{"range":"2492","text":"2062"},{"range":"2493","text":"2062"},{"range":"2494","text":"2096"},{"range":"2495","text":"2068"},{"range":"2496","text":"2285"},{"range":"2497","text":"2062"},{"range":"2498","text":"2062"},{"range":"2499","text":"2062"},{"range":"2500","text":"2307"},{"range":"2501","text":"2090"},{"range":"2502","text":"2062"},{"range":"2503","text":"2186"},{"range":"2504","text":"2292"},{"range":"2505","text":"2186"},{"range":"2506","text":"2096"},{"range":"2507","text":"2068"},{"range":"2508","text":"2300"},{"range":"2509","text":"2068"},{"range":"2510","text":"2318"},{"range":"2511","text":"2064"},{"range":"2512","text":"2273"},{"range":"2513","text":"2273"},{"range":"2514","text":"2062"},{"range":"2515","text":"2290"},{"range":"2516","text":"2292"},{"range":"2517","text":"2294"},{"range":"2518","text":"2062"},{"range":"2519","text":"2297"},{"range":"2520","text":"2068"},{"range":"2521","text":"2300"},{"range":"2522","text":"2068"},{"range":"2523","text":"2303"},{"range":"2524","text":"2305"},"padding-line-between-statements",[116,119],"\" \"",[329,340],"\"of\", \"and\"",[309,442],"(word) => {\n if (!['of', 'and'].includes(word)) {\n return word[0].toUpperCase() + word.slice(1);\n } \n return word\n \n}",[436,436],";",[3592,3593],"",[1690,1690],"\n",[3087,3088],[4072,4073],[6013,6014],"\n£",[6014,6028],"\n{currentPrice}\n",[6401,6427],"\n{' '}\n{currentColor.description}\n",[7550,7558],"\n{option}",[7558,7560],"\n:\n{' '}\n",[9033,9068],[11320,11331],"\n{dimension}",[11331,11333],[12101,12107],"\n{info}",[12107,12109],[2550,2551],[2551,2551]," ",[2777,2778],[2778,2778],[3443,3450]," ",[3444,3444]," ",[3449,3451],"\n —",[3451,3456],"\n{\" \"}",[2593,2611],"\n{' '}\n{address.lastName}",[2778,2792],"\n{' '}\n{address.city}",[1052,1077],"\n{' '}\n{order.shipping.lastName}",[1206,1227],"\n{' '}\n{order.shipping.city}",[1519,1585]," has been confirmed. You will be\n ",[1649,1651],[1649,1663]," ",[1649,1663],[1751,1756],[1916,1921],[2506,2524],[2670,2684],[3075,3100],[2032,2055],"\n{card.number.slice(-4)}",[2055,2078]," (Last 4 digits)",[2056,2056]," ",[2061,2078],"\n (Last 4 digits)\n",[2078,2078],[2078,2078],[3282,3283],[1686,1687],[2007,2012],[2109,2121],"\n.\n",[2219,2231],[2623,2628],[1552,1553],[1553,1560],"\n{price}\n",[2103,2104],[7912,7927],[8278,8293],[8636,8651],[9274,9285],"\n{' '}\n{index + 1}",[9859,9882],[10294,10315],[11004,11015],[11661,11682],[12075,12096],[12587,12602],[13501,13524],[14156,14179],[14705,14728],[15639,15660],[16328,16339],[16827,16848],[17201,17220],[18035,18050],[19002,19027],[19448,19473],[21231,21260],[22481,22510],[23813,23842],[25091,25120],[26363,26392],[28225,28238],[29045,29066],[29825,29848],[30229,30248],[30938,30949],[31410,31431],[31764,31783],[1142,1167],[1855,1880],[2029,2050],[2377,2406],"\n{order.card.number.slice(-4)}",[2406,2422],"\n{' '}\n(Last 4 digits)\n",[3166,3167],[5511,5525],"\n{' '}\n<FilterIcon />",[5679,5724],"\n{' '}\n{areColorsOpen ? <AngleUp /> : <AngleDown />}",[6602,6625],[7284,7307],"\n{dimensions.height.min}",[7307,7310],"\n{' '}\n-",[7310,7333],"\n{' '}\n{dimensions.height.max}",[7333,7334],[7333,7336],"\n )\n",[7336,7336]," ",[7336,7336],[7336,7336],[7765,7786],[7998,8020],"\n{dimensions.width.min}",[8020,8023],[8023,8045],"\n{' '}\n{dimensions.width.max}",[8045,8046],[8045,8048],[8048,8048],[8048,8048],[8048,8048],[8473,8494],[8705,8727],"\n{dimensions.depth.min}",[8727,8730],[8730,8752],"\n{' '}\n{dimensions.depth.max}",[8752,8753],[8752,8755],[8755,8755],[8755,8755],[8755,8755],[9180,9201],[10503,10528],[11795,11820],[12197,12208],"\n{price.min}",[12208,12211],[12211,12222],"\n{' '}\n{price.max}",[12222,12240],"\n)\n",[5888,5888],"\n ",[6468,6491],[6491,6494],[6494,6517],[6517,6518],[6517,6520],"\n )\n",[6520,6520]," ",[6520,6520],[6520,6520],[6905,6922],[7106,7128],[7128,7131],[7131,7153],[7153,7154],[7153,7156],[7156,7156],[7156,7156],[7156,7156],[7537,7554],[7737,7759],[7759,7762],[7762,7784],[7784,7785],[7784,7787],[7787,7787],[7787,7787],[7787,7787],[8168,8185],[9368,9389],[10529,10550],[10871,10882],[10882,10885],[10885,10896],[10896,10897],[10896,10899],"\n )\n",[10899,10899],[10899,10899],[10899,10899],[11612,11613],[1215,1215],[2193,2202],"\n{' '}\n<Arrow />",[2395,2404],[3264,3265],[2365,2372],[2366,2366]," ",[2372,2372],[451,493],[790,840],[842,847],[1067,1068],[1068,1083],"\n{product.price}\n",[1218,1229],[1415,1426],[1955,1956],[832,836],"\n{' '}\nin",[836,860],"\n{' '}\n{item.color.description}",[1112,1115],"\n{' '}\n-\n",[1114,1115],[1115,1115]," ",[1358,1359],[1359,1371],"\n{item.price}\n",[1503,1504],[1504,1554],"\n{cart.reduce((sum, item) => sum + +item.price, 0)}\n",[1780,1830],"\n{cart.reduce((sum, item) => sum + +item.price, 0)}",[5314,5345],"\n{' '}\n{formatNavLink(activeCategory)}",[5636,5636],[5684,5685],[900,903],[903,927],[1166,1168],[1168,1173],[1325,1326],[1326,1338],[1906,1907],[1907,1930],"\n{item.price * quantity}\n",[4046,4046],[1690,1690],[3087,3088],[7214,7214],[4072,4073],[6013,6014],[6014,6028],[6401,6427],[7550,7558],[7558,7560],[9033,9068],[11320,11331],[11331,11333],[12101,12107],[12107,12109],[2550,2551],[2551,2551],[2777,2778],[2778,2778],[3443,3450],[3444,3444],[3449,3451],[3451,3456],[2593,2611],[2778,2792],[1052,1077],[1206,1227],[1519,1585],[1649,1651],[1649,1663],[1649,1663],[1751,1756],[1916,1921],[2506,2524],[2670,2684],[3075,3100],[2032,2055],[2055,2078],[2056,2056],[2061,2078],[2078,2078],[2078,2078],[3282,3283],[1686,1687],[3592,3593],[116,119],[329,340],[309,442],[436,436],[2007,2012],[2109,2121],[2219,2231],[2623,2628],[1552,1553],[1553,1560],[2103,2104],[7912,7927],[8278,8293],[8636,8651],[9274,9285],[9859,9882],[10294,10315],[11004,11015],[11661,11682],[12075,12096],[12587,12602],[13501,13524],[14156,14179],[14705,14728],[15639,15660],[16328,16339],[16827,16848],[17201,17220],[18035,18050],[19002,19027],[19448,19473],[21231,21260],[22481,22510],[23813,23842],[25091,25120],[26363,26392],[28225,28238],[29045,29066],[29825,29848],[30229,30248],[30938,30949],[31410,31431],[31764,31783],[1142,1167],[1855,1880],[2029,2050],[2377,2406],[2406,2422],[3166,3167],[5888,5888],[6468,6491],[6491,6494],[6494,6517],[6517,6518],[6517,6520],[6520,6520],[6520,6520],[6520,6520],[6905,6922],[7106,7128],[7128,7131],[7131,7153],[7153,7154],[7153,7156],[7156,7156],[7156,7156],[7156,7156],[7537,7554],[7737,7759],[7759,7762],[7762,7784],[7784,7785],[7784,7787],[7787,7787],[7787,7787],[7787,7787],[8168,8185],[9368,9389],[10529,10550],[10871,10882],[10882,10885],[10885,10896],[10896,10897],[10896,10899],[10899,10899],[10899,10899],[10899,10899],[11612,11613],[5511,5525],[5679,5724],[6602,6625],[7284,7307],[7307,7310],[7310,7333],[7333,7334],[7333,7336],[7336,7336],[7336,7336],[7336,7336],[7765,7786],[7998,8020],[8020,8023],[8023,8045],[8045,8046],[8045,8048],[8048,8048],[8048,8048],[8048,8048],[8473,8494],[8705,8727],[8727,8730],[8730,8752],[8752,8753],[8752,8755],[8755,8755],[8755,8755],[8755,8755],[9180,9201],[10503,10528],[11795,11820],[12197,12208],[12208,12211],[12211,12222],[12222,12240],[1215,1215],[2365,2372],[2366,2366],[2372,2372],[451,493],[790,840],[842,847],[1067,1068],[1068,1083],[1218,1229],[1415,1426],[1955,1956],[5314,5345],[5636,5636],[5684,5685],[900,903],[903,927],[1166,1168],[1168,1173],[1325,1326],[1326,1338],[1906,1907],[1907,1930],[4046,4046],[2193,2202],[2395,2404],[3264,3265],[832,836],[836,860],[1112,1115],[1114,1115],[1115,1115],[1358,1359],[1359,1371],[1503,1504],[1504,1554],[1780,1830]]