commit adde97c6549c27bfbf314c30d13a1301dea6d731 Author: Isaac Espinosa Date: Thu Sep 17 23:47:51 2026 +0200 Versión inicial funcional de MyDiary diff --git a/assets/css/fontawesome-all.min.css b/assets/css/fontawesome-all.min.css new file mode 100644 index 0000000..03c42e3 --- /dev/null +++ b/assets/css/fontawesome-all.min.css @@ -0,0 +1,101 @@ +/*! + * Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +.fa,.fab,.fad,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-acquisitions-incorporated:before{content:"\f6af"}.fa-ad:before{content:"\f641"}.fa-address-book:before{content:"\f2b9"}.fa-address-card:before{content:"\f2bb"}.fa-adjust:before{content:"\f042"}.fa-adn:before{content:"\f170"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-air-freshener:before{content:"\f5d0"}.fa-airbnb:before{content:"\f834"}.fa-algolia:before{content:"\f36c"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-alipay:before{content:"\f642"}.fa-allergies:before{content:"\f461"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-ambulance:before{content:"\f0f9"}.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-amilia:before{content:"\f36d"}.fa-anchor:before{content:"\f13d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angry:before{content:"\f556"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-ankh:before{content:"\f644"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-alt:before{content:"\f5d1"}.fa-apple-pay:before{content:"\f415"}.fa-archive:before{content:"\f187"}.fa-archway:before{content:"\f557"}.fa-arrow-alt-circle-down:before{content:"\f358"}.fa-arrow-alt-circle-left:before{content:"\f359"}.fa-arrow-alt-circle-right:before{content:"\f35a"}.fa-arrow-alt-circle-up:before{content:"\f35b"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrows-alt:before{content:"\f0b2"}.fa-arrows-alt-h:before{content:"\f337"}.fa-arrows-alt-v:before{content:"\f338"}.fa-artstation:before{content:"\f77a"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asterisk:before{content:"\f069"}.fa-asymmetrik:before{content:"\f372"}.fa-at:before{content:"\f1fa"}.fa-atlas:before{content:"\f558"}.fa-atlassian:before{content:"\f77b"}.fa-atom:before{content:"\f5d2"}.fa-audible:before{content:"\f373"}.fa-audio-description:before{content:"\f29e"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-award:before{content:"\f559"}.fa-aws:before{content:"\f375"}.fa-baby:before{content:"\f77c"}.fa-baby-carriage:before{content:"\f77d"}.fa-backspace:before{content:"\f55a"}.fa-backward:before{content:"\f04a"}.fa-bacon:before{content:"\f7e5"}.fa-bacteria:before{content:"\e059"}.fa-bacterium:before{content:"\e05a"}.fa-bahai:before{content:"\f666"}.fa-balance-scale:before{content:"\f24e"}.fa-balance-scale-left:before{content:"\f515"}.fa-balance-scale-right:before{content:"\f516"}.fa-ban:before{content:"\f05e"}.fa-band-aid:before{content:"\f462"}.fa-bandcamp:before{content:"\f2d5"}.fa-barcode:before{content:"\f02a"}.fa-bars:before{content:"\f0c9"}.fa-baseball-ball:before{content:"\f433"}.fa-basketball-ball:before{content:"\f434"}.fa-bath:before{content:"\f2cd"}.fa-battery-empty:before{content:"\f244"}.fa-battery-full:before{content:"\f240"}.fa-battery-half:before{content:"\f242"}.fa-battery-quarter:before{content:"\f243"}.fa-battery-three-quarters:before{content:"\f241"}.fa-battle-net:before{content:"\f835"}.fa-bed:before{content:"\f236"}.fa-beer:before{content:"\f0fc"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bell:before{content:"\f0f3"}.fa-bell-slash:before{content:"\f1f6"}.fa-bezier-curve:before{content:"\f55b"}.fa-bible:before{content:"\f647"}.fa-bicycle:before{content:"\f206"}.fa-biking:before{content:"\f84a"}.fa-bimobject:before{content:"\f378"}.fa-binoculars:before{content:"\f1e5"}.fa-biohazard:before{content:"\f780"}.fa-birthday-cake:before{content:"\f1fd"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blender:before{content:"\f517"}.fa-blender-phone:before{content:"\f6b6"}.fa-blind:before{content:"\f29d"}.fa-blog:before{content:"\f781"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bold:before{content:"\f032"}.fa-bolt:before{content:"\f0e7"}.fa-bomb:before{content:"\f1e2"}.fa-bone:before{content:"\f5d7"}.fa-bong:before{content:"\f55c"}.fa-book:before{content:"\f02d"}.fa-book-dead:before{content:"\f6b7"}.fa-book-medical:before{content:"\f7e6"}.fa-book-open:before{content:"\f518"}.fa-book-reader:before{content:"\f5da"}.fa-bookmark:before{content:"\f02e"}.fa-bootstrap:before{content:"\f836"}.fa-border-all:before{content:"\f84c"}.fa-border-none:before{content:"\f850"}.fa-border-style:before{content:"\f853"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-box-open:before{content:"\f49e"}.fa-box-tissue:before{content:"\e05b"}.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-brain:before{content:"\f5dc"}.fa-bread-slice:before{content:"\f7ec"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broadcast-tower:before{content:"\f519"}.fa-broom:before{content:"\f51a"}.fa-brush:before{content:"\f55d"}.fa-btc:before{content:"\f15a"}.fa-buffer:before{content:"\f837"}.fa-bug:before{content:"\f188"}.fa-building:before{content:"\f1ad"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burn:before{content:"\f46a"}.fa-buromobelexperte:before{content:"\f37f"}.fa-bus:before{content:"\f207"}.fa-bus-alt:before{content:"\f55e"}.fa-business-time:before{content:"\f64a"}.fa-buy-n-large:before{content:"\f8a6"}.fa-buysellads:before{content:"\f20d"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-alt:before{content:"\f073"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-day:before{content:"\f783"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-times:before{content:"\f273"}.fa-calendar-week:before{content:"\f784"}.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-campground:before{content:"\f6bb"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-candy-cane:before{content:"\f786"}.fa-cannabis:before{content:"\f55f"}.fa-capsules:before{content:"\f46b"}.fa-car:before{content:"\f1b9"}.fa-car-alt:before{content:"\f5de"}.fa-car-battery:before{content:"\f5df"}.fa-car-crash:before{content:"\f5e1"}.fa-car-side:before{content:"\f5e4"}.fa-caravan:before{content:"\f8ff"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-square-down:before{content:"\f150"}.fa-caret-square-left:before{content:"\f191"}.fa-caret-square-right:before{content:"\f152"}.fa-caret-square-up:before{content:"\f151"}.fa-caret-up:before{content:"\f0d8"}.fa-carrot:before{content:"\f787"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-plus:before{content:"\f217"}.fa-cash-register:before{content:"\f788"}.fa-cat:before{content:"\f6be"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-centos:before{content:"\f789"}.fa-certificate:before{content:"\f0a3"}.fa-chair:before{content:"\f6c0"}.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before{content:"\f51c"}.fa-charging-station:before{content:"\f5e7"}.fa-chart-area:before{content:"\f1fe"}.fa-chart-bar:before{content:"\f080"}.fa-chart-line:before{content:"\f201"}.fa-chart-pie:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-circle:before{content:"\f058"}.fa-check-double:before{content:"\f560"}.fa-check-square:before{content:"\f14a"}.fa-cheese:before{content:"\f7ef"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-chrome:before{content:"\f268"}.fa-chromecast:before{content:"\f838"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-circle-notch:before{content:"\f1ce"}.fa-city:before{content:"\f64f"}.fa-clinic-medical:before{content:"\f7f2"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clock:before{content:"\f017"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-download-alt:before{content:"\f381"}.fa-cloud-meatball:before{content:"\f73b"}.fa-cloud-moon:before{content:"\f6c3"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-cloud-rain:before{content:"\f73d"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-cloud-sun:before{content:"\f6c4"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-cloud-upload-alt:before{content:"\f382"}.fa-cloudflare:before{content:"\e07d"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cocktail:before{content:"\f561"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-coffee:before{content:"\f0f4"}.fa-cog:before{content:"\f013"}.fa-cogs:before{content:"\f085"}.fa-coins:before{content:"\f51e"}.fa-columns:before{content:"\f0db"}.fa-comment:before{content:"\f075"}.fa-comment-alt:before{content:"\f27a"}.fa-comment-dollar:before{content:"\f651"}.fa-comment-dots:before{content:"\f4ad"}.fa-comment-medical:before{content:"\f7f5"}.fa-comment-slash:before{content:"\f4b3"}.fa-comments:before{content:"\f086"}.fa-comments-dollar:before{content:"\f653"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compress:before{content:"\f066"}.fa-compress-alt:before{content:"\f422"}.fa-compress-arrows-alt:before{content:"\f78c"}.fa-concierge-bell:before{content:"\f562"}.fa-confluence:before{content:"\f78d"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cookie:before{content:"\f563"}.fa-cookie-bite:before{content:"\f564"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-cotton-bureau:before{content:"\f89e"}.fa-couch:before{content:"\f4b8"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-credit-card:before{content:"\f09d"}.fa-critical-role:before{content:"\f6c9"}.fa-crop:before{content:"\f125"}.fa-crop-alt:before{content:"\f565"}.fa-cross:before{content:"\f654"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-crutch:before{content:"\f7f7"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cut:before{content:"\f0c4"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-dailymotion:before{content:"\e052"}.fa-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.fa-deezer:before{content:"\e077"}.fa-delicious:before{content:"\f1a5"}.fa-democrat:before{content:"\f747"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-desktop:before{content:"\f108"}.fa-dev:before{content:"\f6cc"}.fa-deviantart:before{content:"\f1bd"}.fa-dharmachakra:before{content:"\f655"}.fa-dhl:before{content:"\f790"}.fa-diagnoses:before{content:"\f470"}.fa-diaspora:before{content:"\f791"}.fa-dice:before{content:"\f522"}.fa-dice-d20:before{content:"\f6cf"}.fa-dice-d6:before{content:"\f6d1"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-digital-tachograph:before{content:"\f566"}.fa-directions:before{content:"\f5eb"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-disease:before{content:"\f7fa"}.fa-divide:before{content:"\f529"}.fa-dizzy:before{content:"\f567"}.fa-dna:before{content:"\f471"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-dog:before{content:"\f6d3"}.fa-dollar-sign:before{content:"\f155"}.fa-dolly:before{content:"\f472"}.fa-dolly-flatbed:before{content:"\f474"}.fa-donate:before{content:"\f4b9"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dot-circle:before{content:"\f192"}.fa-dove:before{content:"\f4ba"}.fa-download:before{content:"\f019"}.fa-draft2digital:before{content:"\f396"}.fa-drafting-compass:before{content:"\f568"}.fa-dragon:before{content:"\f6d5"}.fa-draw-polygon:before{content:"\f5ee"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drum:before{content:"\f569"}.fa-drum-steelpan:before{content:"\f56a"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-drupal:before{content:"\f1a9"}.fa-dumbbell:before{content:"\f44b"}.fa-dumpster:before{content:"\f793"}.fa-dumpster-fire:before{content:"\f794"}.fa-dungeon:before{content:"\f6d9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edge-legacy:before{content:"\e078"}.fa-edit:before{content:"\f044"}.fa-egg:before{content:"\f7fb"}.fa-eject:before{content:"\f052"}.fa-elementor:before{content:"\f430"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-text:before{content:"\f658"}.fa-envelope-square:before{content:"\f199"}.fa-envira:before{content:"\f299"}.fa-equals:before{content:"\f52c"}.fa-eraser:before{content:"\f12d"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-ethernet:before{content:"\f796"}.fa-etsy:before{content:"\f2d7"}.fa-euro-sign:before{content:"\f153"}.fa-evernote:before{content:"\f839"}.fa-exchange-alt:before{content:"\f362"}.fa-exclamation:before{content:"\f12a"}.fa-exclamation-circle:before{content:"\f06a"}.fa-exclamation-triangle:before{content:"\f071"}.fa-expand:before{content:"\f065"}.fa-expand-alt:before{content:"\f424"}.fa-expand-arrows-alt:before{content:"\f31e"}.fa-expeditedssl:before{content:"\f23e"}.fa-external-link-alt:before{content:"\f35d"}.fa-external-link-square-alt:before{content:"\f360"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper:before{content:"\f1fb"}.fa-eye-slash:before{content:"\f070"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fan:before{content:"\f863"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-fast-backward:before{content:"\f049"}.fa-fast-forward:before{content:"\f050"}.fa-faucet:before{content:"\e005"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-feather-alt:before{content:"\f56b"}.fa-fedex:before{content:"\f797"}.fa-fedora:before{content:"\f798"}.fa-female:before{content:"\f182"}.fa-fighter-jet:before{content:"\f0fb"}.fa-figma:before{content:"\f799"}.fa-file:before{content:"\f15b"}.fa-file-alt:before{content:"\f15c"}.fa-file-archive:before{content:"\f1c6"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-contract:before{content:"\f56c"}.fa-file-csv:before{content:"\f6dd"}.fa-file-download:before{content:"\f56d"}.fa-file-excel:before{content:"\f1c3"}.fa-file-export:before{content:"\f56e"}.fa-file-image:before{content:"\f1c5"}.fa-file-import:before{content:"\f56f"}.fa-file-invoice:before{content:"\f570"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-file-medical:before{content:"\f477"}.fa-file-medical-alt:before{content:"\f478"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-prescription:before{content:"\f572"}.fa-file-signature:before{content:"\f573"}.fa-file-upload:before{content:"\f574"}.fa-file-video:before{content:"\f1c8"}.fa-file-word:before{content:"\f1c2"}.fa-fill:before{content:"\f575"}.fa-fill-drip:before{content:"\f576"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-fingerprint:before{content:"\f577"}.fa-fire:before{content:"\f06d"}.fa-fire-alt:before{content:"\f7e4"}.fa-fire-extinguisher:before{content:"\f134"}.fa-firefox:before{content:"\f269"}.fa-firefox-browser:before{content:"\e007"}.fa-first-aid:before{content:"\f479"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-fish:before{content:"\f578"}.fa-fist-raised:before{content:"\f6de"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flag-usa:before{content:"\f74d"}.fa-flask:before{content:"\f0c3"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-flushed:before{content:"\f579"}.fa-fly:before{content:"\f417"}.fa-folder:before{content:"\f07b"}.fa-folder-minus:before{content:"\f65d"}.fa-folder-open:before{content:"\f07c"}.fa-folder-plus:before{content:"\f65e"}.fa-font:before{content:"\f031"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-font-awesome-flag:before{content:"\f425"}.fa-font-awesome-logo-full:before{content:"\f4e6"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-football-ball:before{content:"\f44e"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-forward:before{content:"\f04e"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-frog:before{content:"\f52e"}.fa-frown:before{content:"\f119"}.fa-frown-open:before{content:"\f57a"}.fa-fulcrum:before{content:"\f50b"}.fa-funnel-dollar:before{content:"\f662"}.fa-futbol:before{content:"\f1e3"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-gavel:before{content:"\f0e3"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-ghost:before{content:"\f6e2"}.fa-gift:before{content:"\f06b"}.fa-gifts:before{content:"\f79c"}.fa-git:before{content:"\f1d3"}.fa-git-alt:before{content:"\f841"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glass-cheers:before{content:"\f79f"}.fa-glass-martini:before{content:"\f000"}.fa-glass-martini-alt:before{content:"\f57b"}.fa-glass-whiskey:before{content:"\f7a0"}.fa-glasses:before{content:"\f530"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-globe:before{content:"\f0ac"}.fa-globe-africa:before{content:"\f57c"}.fa-globe-americas:before{content:"\f57d"}.fa-globe-asia:before{content:"\f57e"}.fa-globe-europe:before{content:"\f7a2"}.fa-gofore:before{content:"\f3a7"}.fa-golf-ball:before{content:"\f450"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-pay:before{content:"\e079"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-gopuram:before{content:"\f664"}.fa-graduation-cap:before{content:"\f19d"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-greater-than:before{content:"\f531"}.fa-greater-than-equal:before{content:"\f532"}.fa-grimace:before{content:"\f57f"}.fa-grin:before{content:"\f580"}.fa-grin-alt:before{content:"\f581"}.fa-grin-beam:before{content:"\f582"}.fa-grin-beam-sweat:before{content:"\f583"}.fa-grin-hearts:before{content:"\f584"}.fa-grin-squint:before{content:"\f585"}.fa-grin-squint-tears:before{content:"\f586"}.fa-grin-stars:before{content:"\f587"}.fa-grin-tears:before{content:"\f588"}.fa-grin-tongue:before{content:"\f589"}.fa-grin-tongue-squint:before{content:"\f58a"}.fa-grin-tongue-wink:before{content:"\f58b"}.fa-grin-wink:before{content:"\f58c"}.fa-grip-horizontal:before{content:"\f58d"}.fa-grip-lines:before{content:"\f7a4"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-grip-vertical:before{content:"\f58e"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-guilded:before{content:"\e07e"}.fa-guitar:before{content:"\f7a6"}.fa-gulp:before{content:"\f3ae"}.fa-h-square:before{content:"\f0fd"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hackerrank:before{content:"\f5f7"}.fa-hamburger:before{content:"\f805"}.fa-hammer:before{content:"\f6e3"}.fa-hamsa:before{content:"\f665"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-medical:before{content:"\e05c"}.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-holding-water:before{content:"\f4c1"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-middle-finger:before{content:"\f806"}.fa-hand-paper:before{content:"\f256"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-rock:before{content:"\f255"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-sparkles:before{content:"\e05d"}.fa-hand-spock:before{content:"\f259"}.fa-hands:before{content:"\f4c2"}.fa-hands-helping:before{content:"\f4c4"}.fa-hands-wash:before{content:"\e05e"}.fa-handshake:before{content:"\f2b5"}.fa-handshake-alt-slash:before{content:"\e05f"}.fa-handshake-slash:before{content:"\e060"}.fa-hanukiah:before{content:"\f6e6"}.fa-hard-hat:before{content:"\f807"}.fa-hashtag:before{content:"\f292"}.fa-hat-cowboy:before{content:"\f8c0"}.fa-hat-cowboy-side:before{content:"\f8c1"}.fa-hat-wizard:before{content:"\f6e8"}.fa-hdd:before{content:"\f0a0"}.fa-head-side-cough:before{content:"\e061"}.fa-head-side-cough-slash:before{content:"\e062"}.fa-head-side-mask:before{content:"\e063"}.fa-head-side-virus:before{content:"\e064"}.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-headphones-alt:before{content:"\f58f"}.fa-headset:before{content:"\f590"}.fa-heart:before{content:"\f004"}.fa-heart-broken:before{content:"\f7a9"}.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-highlighter:before{content:"\f591"}.fa-hiking:before{content:"\f6ec"}.fa-hippo:before{content:"\f6ed"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-history:before{content:"\f1da"}.fa-hive:before{content:"\e07f"}.fa-hockey-puck:before{content:"\f453"}.fa-holly-berry:before{content:"\f7aa"}.fa-home:before{content:"\f015"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-horse:before{content:"\f6f0"}.fa-horse-head:before{content:"\f7ab"}.fa-hospital:before{content:"\f0f8"}.fa-hospital-alt:before{content:"\f47d"}.fa-hospital-symbol:before{content:"\f47e"}.fa-hospital-user:before{content:"\f80d"}.fa-hot-tub:before{content:"\f593"}.fa-hotdog:before{content:"\f80f"}.fa-hotel:before{content:"\f594"}.fa-hotjar:before{content:"\f3b1"}.fa-hourglass:before{content:"\f254"}.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-start:before{content:"\f251"}.fa-house-damage:before{content:"\f6f1"}.fa-house-user:before{content:"\e065"}.fa-houzz:before{content:"\f27c"}.fa-hryvnia:before{content:"\f6f2"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-i-cursor:before{content:"\f246"}.fa-ice-cream:before{content:"\f810"}.fa-icicles:before{content:"\f7ad"}.fa-icons:before{content:"\f86d"}.fa-id-badge:before{content:"\f2c1"}.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before{content:"\f47f"}.fa-ideal:before{content:"\e013"}.fa-igloo:before{content:"\f7ae"}.fa-image:before{content:"\f03e"}.fa-images:before{content:"\f302"}.fa-imdb:before{content:"\f2d8"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-info-circle:before{content:"\f05a"}.fa-innosoft:before{content:"\e080"}.fa-instagram:before{content:"\f16d"}.fa-instagram-square:before{content:"\e055"}.fa-instalod:before{content:"\e081"}.fa-intercom:before{content:"\f7af"}.fa-internet-explorer:before{content:"\f26b"}.fa-invision:before{content:"\f7b0"}.fa-ioxhost:before{content:"\f208"}.fa-italic:before{content:"\f033"}.fa-itch-io:before{content:"\f83a"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi:before{content:"\f669"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-jira:before{content:"\f7b1"}.fa-joget:before{content:"\f3b7"}.fa-joint:before{content:"\f595"}.fa-joomla:before{content:"\f1aa"}.fa-journal-whills:before{content:"\f66a"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaaba:before{content:"\f66b"}.fa-kaggle:before{content:"\f5fa"}.fa-key:before{content:"\f084"}.fa-keybase:before{content:"\f4f5"}.fa-keyboard:before{content:"\f11c"}.fa-keycdn:before{content:"\f3ba"}.fa-khanda:before{content:"\f66d"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-kiss:before{content:"\f596"}.fa-kiss-beam:before{content:"\f597"}.fa-kiss-wink-heart:before{content:"\f598"}.fa-kiwi-bird:before{content:"\f535"}.fa-korvue:before{content:"\f42f"}.fa-landmark:before{content:"\f66f"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laptop-code:before{content:"\f5fc"}.fa-laptop-house:before{content:"\e066"}.fa-laptop-medical:before{content:"\f812"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-laugh:before{content:"\f599"}.fa-laugh-beam:before{content:"\f59a"}.fa-laugh-squint:before{content:"\f59b"}.fa-laugh-wink:before{content:"\f59c"}.fa-layer-group:before{content:"\f5fd"}.fa-leaf:before{content:"\f06c"}.fa-leanpub:before{content:"\f212"}.fa-lemon:before{content:"\f094"}.fa-less:before{content:"\f41d"}.fa-less-than:before{content:"\f536"}.fa-less-than-equal:before{content:"\f537"}.fa-level-down-alt:before{content:"\f3be"}.fa-level-up-alt:before{content:"\f3bf"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-line:before{content:"\f3c0"}.fa-link:before{content:"\f0c1"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lira-sign:before{content:"\f195"}.fa-list:before{content:"\f03a"}.fa-list-alt:before{content:"\f022"}.fa-list-ol:before{content:"\f0cb"}.fa-list-ul:before{content:"\f0ca"}.fa-location-arrow:before{content:"\f124"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-long-arrow-alt-down:before{content:"\f309"}.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-long-arrow-alt-right:before{content:"\f30b"}.fa-long-arrow-alt-up:before{content:"\f30c"}.fa-low-vision:before{content:"\f2a8"}.fa-luggage-cart:before{content:"\f59d"}.fa-lungs:before{content:"\f604"}.fa-lungs-virus:before{content:"\e067"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-magic:before{content:"\f0d0"}.fa-magnet:before{content:"\f076"}.fa-mail-bulk:before{content:"\f674"}.fa-mailchimp:before{content:"\f59e"}.fa-male:before{content:"\f183"}.fa-mandalorian:before{content:"\f50f"}.fa-map:before{content:"\f279"}.fa-map-marked:before{content:"\f59f"}.fa-map-marked-alt:before{content:"\f5a0"}.fa-map-marker:before{content:"\f041"}.fa-map-marker-alt:before{content:"\f3c5"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-markdown:before{content:"\f60f"}.fa-marker:before{content:"\f5a1"}.fa-mars:before{content:"\f222"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mask:before{content:"\f6fa"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-mdb:before{content:"\f8ca"}.fa-medal:before{content:"\f5a2"}.fa-medapps:before{content:"\f3c6"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f3c7"}.fa-medkit:before{content:"\f0fa"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-meh:before{content:"\f11a"}.fa-meh-blank:before{content:"\f5a4"}.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-memory:before{content:"\f538"}.fa-mendeley:before{content:"\f7b3"}.fa-menorah:before{content:"\f676"}.fa-mercury:before{content:"\f223"}.fa-meteor:before{content:"\f753"}.fa-microblog:before{content:"\e01a"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before{content:"\f3c9"}.fa-microphone-alt-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microscope:before{content:"\f610"}.fa-microsoft:before{content:"\f3ca"}.fa-minus:before{content:"\f068"}.fa-minus-circle:before{content:"\f056"}.fa-minus-square:before{content:"\f146"}.fa-mitten:before{content:"\f7b5"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mixer:before{content:"\e056"}.fa-mizuni:before{content:"\f3cc"}.fa-mobile:before{content:"\f10b"}.fa-mobile-alt:before{content:"\f3cd"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before{content:"\f53d"}.fa-monument:before{content:"\f5a6"}.fa-moon:before{content:"\f186"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-mosque:before{content:"\f678"}.fa-motorcycle:before{content:"\f21c"}.fa-mountain:before{content:"\f6fc"}.fa-mouse:before{content:"\f8cc"}.fa-mouse-pointer:before{content:"\f245"}.fa-mug-hot:before{content:"\f7b6"}.fa-music:before{content:"\f001"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-network-wired:before{content:"\f6ff"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-nimblr:before{content:"\f5a8"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-not-equal:before{content:"\f53e"}.fa-notes-medical:before{content:"\f481"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-octopus-deploy:before{content:"\e082"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-oil-can:before{content:"\f613"}.fa-old-republic:before{content:"\f510"}.fa-om:before{content:"\f679"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-orcid:before{content:"\f8d2"}.fa-osi:before{content:"\f41a"}.fa-otter:before{content:"\f700"}.fa-outdent:before{content:"\f03b"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-pager:before{content:"\f815"}.fa-paint-brush:before{content:"\f1fc"}.fa-paint-roller:before{content:"\f5aa"}.fa-palette:before{content:"\f53f"}.fa-palfed:before{content:"\f3d8"}.fa-pallet:before{content:"\f482"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-parking:before{content:"\f540"}.fa-passport:before{content:"\f5ab"}.fa-pastafarianism:before{content:"\f67b"}.fa-paste:before{content:"\f0ea"}.fa-patreon:before{content:"\f3d9"}.fa-pause:before{content:"\f04c"}.fa-pause-circle:before{content:"\f28b"}.fa-paw:before{content:"\f1b0"}.fa-paypal:before{content:"\f1ed"}.fa-peace:before{content:"\f67c"}.fa-pen:before{content:"\f304"}.fa-pen-alt:before{content:"\f305"}.fa-pen-fancy:before{content:"\f5ac"}.fa-pen-nib:before{content:"\f5ad"}.fa-pen-square:before{content:"\f14b"}.fa-pencil-alt:before{content:"\f303"}.fa-pencil-ruler:before{content:"\f5ae"}.fa-penny-arcade:before{content:"\f704"}.fa-people-arrows:before{content:"\e068"}.fa-people-carry:before{content:"\f4ce"}.fa-pepper-hot:before{content:"\f816"}.fa-perbyte:before{content:"\e083"}.fa-percent:before{content:"\f295"}.fa-percentage:before{content:"\f541"}.fa-periscope:before{content:"\f3da"}.fa-person-booth:before{content:"\f756"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-phone:before{content:"\f095"}.fa-phone-alt:before{content:"\f879"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-square:before{content:"\f098"}.fa-phone-square-alt:before{content:"\f87b"}.fa-phone-volume:before{content:"\f2a0"}.fa-photo-video:before{content:"\f87c"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-square:before{content:"\e01e"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-pizza-slice:before{content:"\f818"}.fa-place-of-worship:before{content:"\f67f"}.fa-plane:before{content:"\f072"}.fa-plane-arrival:before{content:"\f5af"}.fa-plane-departure:before{content:"\f5b0"}.fa-plane-slash:before{content:"\e069"}.fa-play:before{content:"\f04b"}.fa-play-circle:before{content:"\f144"}.fa-playstation:before{content:"\f3df"}.fa-plug:before{content:"\f1e6"}.fa-plus:before{content:"\f067"}.fa-plus-circle:before{content:"\f055"}.fa-plus-square:before{content:"\f0fe"}.fa-podcast:before{content:"\f2ce"}.fa-poll:before{content:"\f681"}.fa-poll-h:before{content:"\f682"}.fa-poo:before{content:"\f2fe"}.fa-poo-storm:before{content:"\f75a"}.fa-poop:before{content:"\f619"}.fa-portrait:before{content:"\f3e0"}.fa-pound-sign:before{content:"\f154"}.fa-power-off:before{content:"\f011"}.fa-pray:before{content:"\f683"}.fa-praying-hands:before{content:"\f684"}.fa-prescription:before{content:"\f5b1"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-procedures:before{content:"\f487"}.fa-product-hunt:before{content:"\f288"}.fa-project-diagram:before{content:"\f542"}.fa-pump-medical:before{content:"\e06a"}.fa-pump-soap:before{content:"\e06b"}.fa-pushed:before{content:"\f3e1"}.fa-puzzle-piece:before{content:"\f12e"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\f128"}.fa-question-circle:before{content:"\f059"}.fa-quidditch:before{content:"\f458"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-quran:before{content:"\f687"}.fa-r-project:before{content:"\f4f7"}.fa-radiation:before{content:"\f7b9"}.fa-radiation-alt:before{content:"\f7ba"}.fa-rainbow:before{content:"\f75b"}.fa-random:before{content:"\f074"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-reacteurope:before{content:"\f75d"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-receipt:before{content:"\f543"}.fa-record-vinyl:before{content:"\f8d9"}.fa-recycle:before{content:"\f1b8"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redhat:before{content:"\f7bc"}.fa-redo:before{content:"\f01e"}.fa-redo-alt:before{content:"\f2f9"}.fa-registered:before{content:"\f25d"}.fa-remove-format:before{content:"\f87d"}.fa-renren:before{content:"\f18b"}.fa-reply:before{content:"\f3e5"}.fa-reply-all:before{content:"\f122"}.fa-replyd:before{content:"\f3e6"}.fa-republican:before{content:"\f75e"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-restroom:before{content:"\f7bd"}.fa-retweet:before{content:"\f079"}.fa-rev:before{content:"\f5b2"}.fa-ribbon:before{content:"\f4d6"}.fa-ring:before{content:"\f70b"}.fa-road:before{content:"\f018"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-route:before{content:"\f4d7"}.fa-rss:before{content:"\f09e"}.fa-rss-square:before{content:"\f143"}.fa-ruble-sign:before{content:"\f158"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-running:before{content:"\f70c"}.fa-rupee-sign:before{content:"\f156"}.fa-rust:before{content:"\e07a"}.fa-sad-cry:before{content:"\f5b3"}.fa-sad-tear:before{content:"\f5b4"}.fa-safari:before{content:"\f267"}.fa-salesforce:before{content:"\f83b"}.fa-sass:before{content:"\f41e"}.fa-satellite:before{content:"\f7bf"}.fa-satellite-dish:before{content:"\f7c0"}.fa-save:before{content:"\f0c7"}.fa-schlix:before{content:"\f3ea"}.fa-school:before{content:"\f549"}.fa-screwdriver:before{content:"\f54a"}.fa-scribd:before{content:"\f28a"}.fa-scroll:before{content:"\f70e"}.fa-sd-card:before{content:"\f7c2"}.fa-search:before{content:"\f002"}.fa-search-dollar:before{content:"\f688"}.fa-search-location:before{content:"\f689"}.fa-search-minus:before{content:"\f010"}.fa-search-plus:before{content:"\f00e"}.fa-searchengin:before{content:"\f3eb"}.fa-seedling:before{content:"\f4d8"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-server:before{content:"\f233"}.fa-servicestack:before{content:"\f3ec"}.fa-shapes:before{content:"\f61f"}.fa-share:before{content:"\f064"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-share-square:before{content:"\f14d"}.fa-shekel-sign:before{content:"\f20b"}.fa-shield-alt:before{content:"\f3ed"}.fa-shield-virus:before{content:"\e06c"}.fa-ship:before{content:"\f21a"}.fa-shipping-fast:before{content:"\f48b"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shoe-prints:before{content:"\f54b"}.fa-shopify:before{content:"\e057"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-shopping-cart:before{content:"\f07a"}.fa-shopware:before{content:"\f5b5"}.fa-shower:before{content:"\f2cc"}.fa-shuttle-van:before{content:"\f5b6"}.fa-sign:before{content:"\f4d9"}.fa-sign-in-alt:before{content:"\f2f6"}.fa-sign-language:before{content:"\f2a7"}.fa-sign-out-alt:before{content:"\f2f5"}.fa-signal:before{content:"\f012"}.fa-signature:before{content:"\f5b7"}.fa-sim-card:before{content:"\f7c4"}.fa-simplybuilt:before{content:"\f215"}.fa-sink:before{content:"\e06d"}.fa-sistrix:before{content:"\f3ee"}.fa-sitemap:before{content:"\f0e8"}.fa-sith:before{content:"\f512"}.fa-skating:before{content:"\f7c5"}.fa-sketch:before{content:"\f7c6"}.fa-skiing:before{content:"\f7c9"}.fa-skiing-nordic:before{content:"\f7ca"}.fa-skull:before{content:"\f54c"}.fa-skull-crossbones:before{content:"\f714"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f3ef"}.fa-slash:before{content:"\f715"}.fa-sleigh:before{content:"\f7cc"}.fa-sliders-h:before{content:"\f1de"}.fa-slideshare:before{content:"\f1e7"}.fa-smile:before{content:"\f118"}.fa-smile-beam:before{content:"\f5b8"}.fa-smile-wink:before{content:"\f4da"}.fa-smog:before{content:"\f75f"}.fa-smoking:before{content:"\f48d"}.fa-smoking-ban:before{content:"\f54d"}.fa-sms:before{content:"\f7cd"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-snowboarding:before{content:"\f7ce"}.fa-snowflake:before{content:"\f2dc"}.fa-snowman:before{content:"\f7d0"}.fa-snowplow:before{content:"\f7d2"}.fa-soap:before{content:"\e06e"}.fa-socks:before{content:"\f696"}.fa-solar-panel:before{content:"\f5ba"}.fa-sort:before{content:"\f0dc"}.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-down-alt:before{content:"\f881"}.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-alpha-up-alt:before{content:"\f882"}.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-down-alt:before{content:"\f884"}.fa-sort-amount-up:before{content:"\f161"}.fa-sort-amount-up-alt:before{content:"\f885"}.fa-sort-down:before{content:"\f0dd"}.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-sort-numeric-up:before{content:"\f163"}.fa-sort-numeric-up-alt:before{content:"\f887"}.fa-sort-up:before{content:"\f0de"}.fa-soundcloud:before{content:"\f1be"}.fa-sourcetree:before{content:"\f7d3"}.fa-spa:before{content:"\f5bb"}.fa-space-shuttle:before{content:"\f197"}.fa-speakap:before{content:"\f3f3"}.fa-speaker-deck:before{content:"\f83c"}.fa-spell-check:before{content:"\f891"}.fa-spider:before{content:"\f717"}.fa-spinner:before{content:"\f110"}.fa-splotch:before{content:"\f5bc"}.fa-spotify:before{content:"\f1bc"}.fa-spray-can:before{content:"\f5bd"}.fa-square:before{content:"\f0c8"}.fa-square-full:before{content:"\f45c"}.fa-square-root-alt:before{content:"\f698"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stackpath:before{content:"\f842"}.fa-stamp:before{content:"\f5bf"}.fa-star:before{content:"\f005"}.fa-star-and-crescent:before{content:"\f699"}.fa-star-half:before{content:"\f089"}.fa-star-half-alt:before{content:"\f5c0"}.fa-star-of-david:before{content:"\f69a"}.fa-star-of-life:before{content:"\f621"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-step-backward:before{content:"\f048"}.fa-step-forward:before{content:"\f051"}.fa-stethoscope:before{content:"\f0f1"}.fa-sticker-mule:before{content:"\f3f7"}.fa-sticky-note:before{content:"\f249"}.fa-stop:before{content:"\f04d"}.fa-stop-circle:before{content:"\f28d"}.fa-stopwatch:before{content:"\f2f2"}.fa-stopwatch-20:before{content:"\e06f"}.fa-store:before{content:"\f54e"}.fa-store-alt:before{content:"\f54f"}.fa-store-alt-slash:before{content:"\e070"}.fa-store-slash:before{content:"\e071"}.fa-strava:before{content:"\f428"}.fa-stream:before{content:"\f550"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-stroopwafel:before{content:"\f551"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-subscript:before{content:"\f12c"}.fa-subway:before{content:"\f239"}.fa-suitcase:before{content:"\f0f2"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-sun:before{content:"\f185"}.fa-superpowers:before{content:"\f2dd"}.fa-superscript:before{content:"\f12b"}.fa-supple:before{content:"\f3f9"}.fa-surprise:before{content:"\f5c2"}.fa-suse:before{content:"\f7d6"}.fa-swatchbook:before{content:"\f5c3"}.fa-swift:before{content:"\f8e1"}.fa-swimmer:before{content:"\f5c4"}.fa-swimming-pool:before{content:"\f5c5"}.fa-symfony:before{content:"\f83d"}.fa-synagogue:before{content:"\f69b"}.fa-sync:before{content:"\f021"}.fa-sync-alt:before{content:"\f2f1"}.fa-syringe:before{content:"\f48e"}.fa-table:before{content:"\f0ce"}.fa-table-tennis:before{content:"\f45d"}.fa-tablet:before{content:"\f10a"}.fa-tablet-alt:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-tachometer-alt:before{content:"\f3fd"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-tasks:before{content:"\f0ae"}.fa-taxi:before{content:"\f1ba"}.fa-teamspeak:before{content:"\f4f9"}.fa-teeth:before{content:"\f62e"}.fa-teeth-open:before{content:"\f62f"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f3fe"}.fa-temperature-high:before{content:"\f769"}.fa-temperature-low:before{content:"\f76b"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-tenge:before{content:"\f7d7"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-th:before{content:"\f00a"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-the-red-yeti:before{content:"\f69d"}.fa-theater-masks:before{content:"\f630"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-thermometer:before{content:"\f491"}.fa-thermometer-empty:before{content:"\f2cb"}.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-think-peaks:before{content:"\f731"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbtack:before{content:"\f08d"}.fa-ticket-alt:before{content:"\f3ff"}.fa-tiktok:before{content:"\e07b"}.fa-times:before{content:"\f00d"}.fa-times-circle:before{content:"\f057"}.fa-tint:before{content:"\f043"}.fa-tint-slash:before{content:"\f5c7"}.fa-tired:before{content:"\f5c8"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toilet:before{content:"\f7d8"}.fa-toilet-paper:before{content:"\f71e"}.fa-toilet-paper-slash:before{content:"\e072"}.fa-toolbox:before{content:"\f552"}.fa-tools:before{content:"\f7d9"}.fa-tooth:before{content:"\f5c9"}.fa-torah:before{content:"\f6a0"}.fa-torii-gate:before{content:"\f6a1"}.fa-tractor:before{content:"\f722"}.fa-trade-federation:before{content:"\f513"}.fa-trademark:before{content:"\f25c"}.fa-traffic-light:before{content:"\f637"}.fa-trailer:before{content:"\e041"}.fa-train:before{content:"\f238"}.fa-tram:before{content:"\f7da"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-alt:before{content:"\f2ed"}.fa-trash-restore:before{content:"\f829"}.fa-trash-restore-alt:before{content:"\f82a"}.fa-tree:before{content:"\f1bb"}.fa-trello:before{content:"\f181"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-truck-loading:before{content:"\f4de"}.fa-truck-monster:before{content:"\f63b"}.fa-truck-moving:before{content:"\f4df"}.fa-truck-pickup:before{content:"\f63c"}.fa-tshirt:before{content:"\f553"}.fa-tty:before{content:"\f1e4"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-tv:before{content:"\f26c"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-ubuntu:before{content:"\f7df"}.fa-uikit:before{content:"\f403"}.fa-umbraco:before{content:"\f8e8"}.fa-umbrella:before{content:"\f0e9"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-uncharted:before{content:"\e084"}.fa-underline:before{content:"\f0cd"}.fa-undo:before{content:"\f0e2"}.fa-undo-alt:before{content:"\f2ea"}.fa-uniregistry:before{content:"\f404"}.fa-unity:before{content:"\e049"}.fa-universal-access:before{content:"\f29a"}.fa-university:before{content:"\f19c"}.fa-unlink:before{content:"\f127"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before{content:"\f13e"}.fa-unsplash:before{content:"\e07c"}.fa-untappd:before{content:"\f405"}.fa-upload:before{content:"\f093"}.fa-ups:before{content:"\f7e0"}.fa-usb:before{content:"\f287"}.fa-user:before{content:"\f007"}.fa-user-alt:before{content:"\f406"}.fa-user-alt-slash:before{content:"\f4fa"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-clock:before{content:"\f4fd"}.fa-user-cog:before{content:"\f4fe"}.fa-user-edit:before{content:"\f4ff"}.fa-user-friends:before{content:"\f500"}.fa-user-graduate:before{content:"\f501"}.fa-user-injured:before{content:"\f728"}.fa-user-lock:before{content:"\f502"}.fa-user-md:before{content:"\f0f0"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-nurse:before{content:"\f82f"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-cog:before{content:"\f509"}.fa-users-slash:before{content:"\e073"}.fa-usps:before{content:"\f7e1"}.fa-ussunnah:before{content:"\f407"}.fa-utensil-spoon:before{content:"\f2e5"}.fa-utensils:before{content:"\f2e7"}.fa-vaadin:before{content:"\f408"}.fa-vector-square:before{content:"\f5cb"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-vest:before{content:"\e085"}.fa-vest-patches:before{content:"\e086"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-vial:before{content:"\f492"}.fa-vials:before{content:"\f493"}.fa-viber:before{content:"\f409"}.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vihara:before{content:"\f6a7"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-virus:before{content:"\e074"}.fa-virus-slash:before{content:"\e075"}.fa-viruses:before{content:"\e076"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-voicemail:before{content:"\f897"}.fa-volleyball-ball:before{content:"\f45f"}.fa-volume-down:before{content:"\f027"}.fa-volume-mute:before{content:"\f6a9"}.fa-volume-off:before{content:"\f026"}.fa-volume-up:before{content:"\f028"}.fa-vote-yea:before{content:"\f772"}.fa-vr-cardboard:before{content:"\f729"}.fa-vuejs:before{content:"\f41f"}.fa-walking:before{content:"\f554"}.fa-wallet:before{content:"\f555"}.fa-warehouse:before{content:"\f494"}.fa-watchman-monitoring:before{content:"\e087"}.fa-water:before{content:"\f773"}.fa-wave-square:before{content:"\f83e"}.fa-waze:before{content:"\f83f"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weight:before{content:"\f496"}.fa-weight-hanging:before{content:"\f5cd"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-wheelchair:before{content:"\f193"}.fa-whmcs:before{content:"\f40d"}.fa-wifi:before{content:"\f1eb"}.fa-wikipedia-w:before{content:"\f266"}.fa-wind:before{content:"\f72e"}.fa-window-close:before{content:"\f410"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-windows:before{content:"\f17a"}.fa-wine-bottle:before{content:"\f72f"}.fa-wine-glass:before{content:"\f4e3"}.fa-wine-glass-alt:before{content:"\f5ce"}.fa-wix:before{content:"\f5cf"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-wodu:before{content:"\e088"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-won-sign:before{content:"\f159"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wpressr:before{content:"\f3e4"}.fa-wrench:before{content:"\f0ad"}.fa-x-ray:before{content:"\f497"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yammer:before{content:"\f840"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yarn:before{content:"\f7e3"}.fa-yelp:before{content:"\f1e9"}.fa-yen-sign:before{content:"\f157"}.fa-yin-yang:before{content:"\f6ad"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-youtube-square:before{content:"\f431"}.fa-zhihu:before{content:"\f63f"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}@font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:"Font Awesome 5 Brands"}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.eot);src:url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.woff) format("woff"),url(../webfonts/fa-regular-400.ttf) format("truetype"),url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")}.fab,.far{font-weight:400}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.far,.fas{font-family:"Font Awesome 5 Free"}.fa,.fas{font-weight:900} \ No newline at end of file diff --git a/assets/css/images/close.svg b/assets/css/images/close.svg new file mode 100644 index 0000000..c6fdf41 --- /dev/null +++ b/assets/css/images/close.svg @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/assets/css/main.css b/assets/css/main.css new file mode 100644 index 0000000..7414869 --- /dev/null +++ b/assets/css/main.css @@ -0,0 +1,1219 @@ +@import url(fontawesome-all.min.css); +@import url("https://fonts.googleapis.com/css?family=Raleway:200,700|Source+Sans+Pro:300,600,300italic,600italic"); + +/* + Solid State by HTML5 UP + html5up.net | @ajlkn + Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +*/ + +html, body, div, span, applet, object, +iframe, h1, h2, h3, h4, h5, h6, p, blockquote, +pre, a, abbr, acronym, address, big, cite, +code, del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, b, +u, i, center, dl, dt, dd, ol, ul, li, fieldset, +form, label, legend, caption, article, aside, +canvas, details, embed, figure, figcaption, +footer, header, hgroup, menu, nav, output, ruby, +section, summary, time, mark, audio, video { + margin: 0; + padding: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline;} + +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block;} + +body { + line-height: 1; +} + +ol, ul { + list-style: none; +} + +blockquote, q { + quotes: none; +} + + blockquote:before, blockquote:after, q:before, q:after { + content: ''; + content: none; + } + + +body { + -webkit-text-size-adjust: none; +} + +mark { + background-color: transparent; + color: inherit; +} + +::-moz-focus-inner { + border: 0; + padding: 0; +} + +input, select, textarea { + -moz-appearance: none; + -webkit-appearance: none; + -ms-appearance: none; + appearance: none; +} + +/* Basic */ + +/*body, input, select, textarea { + color: #ffffff; + font-size: 16.5pt; + font-weight: 300; + line-height: 1.65; + } */ + + html { + box-sizing: border-box; + } + + *, *:before, *:after { + box-sizing: inherit; + } + + body { + background-color: #2e3141; + background-image: linear-gradient(to top, rgba(46, 49, 65, 0.8), rgba(46, 49, 65, 0.8)), url("../../images/bg.jpg"); + background-size: auto, + cover; + background-attachment: fixed, + fixed; + background-position: center, + center; + } + + body.is-preload *, body.is-preload *:before, body.is-preload *:after { + -moz-animation: none !important; + -webkit-animation: none !important; + -ms-animation: none !important; + animation: none !important; + -moz-transition: none !important; + -webkit-transition: none !important; + -ms-transition: none !important; + transition: none !important; + } + +/* Type */ + + + + @media screen and (max-width: 1680px) { + + body, input, select, textarea { + font-size: 13pt; + } + + } + + @media screen and (max-width: 1280px) { + + body, input, select, textarea { + font-size: 12pt; + } + + } + + @media screen and (max-width: 980px) { + + body, input, select, textarea { + font-size: 12pt; + } + + } + + @media screen and (max-width: 736px) { + + body, input, select, textarea { + font-size: 12pt; + } + + } + + @media screen and (max-width: 480px) { + + body, input, select, textarea { + font-size: 12pt; + } + + } + + a { + -moz-transition: color 0.2s ease-in-out, border-bottom-color 0.2s ease-in-out; + -webkit-transition: color 0.2s ease-in-out, border-bottom-color 0.2s ease-in-out; + -ms-transition: color 0.2s ease-in-out, border-bottom-color 0.2s ease-in-out; + transition: color 0.2s ease-in-out, border-bottom-color 0.2s ease-in-out; + border-bottom: dotted 1px rgba(255, 255, 255, 0.35); + color: #ffffff; + text-decoration: none; + } + + a:hover { + border-bottom-color: transparent; + color: #ffffff !important; + } + + a.special:not(.button) { + text-decoration: none; + border-bottom: 0; + display: block; + font-family: Raleway, Helvetica, sans-serif; + font-size: 0.8em; + font-weight: 700; + letter-spacing: 0.1em; + margin: 0 0 2em 0; + text-transform: uppercase; + } + + a.special:not(.button):before { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + display: inline-block; + font-style: normal; + font-variant: normal; + text-rendering: auto; + line-height: 1; + text-transform: none !important; + font-family: 'Font Awesome 5 Free'; + font-weight: 900; + } + + a.special:not(.button):before { + -moz-transition: background-color 0.2s ease-in-out; + -webkit-transition: background-color 0.2s ease-in-out; + -ms-transition: background-color 0.2s ease-in-out; + transition: background-color 0.2s ease-in-out; + border-radius: 100%; + border: solid 2px rgba(255, 255, 255, 0.125); + content: '\f105'; + display: inline-block; + font-size: 1.25em; + height: 2em; + line-height: 1.75em; + margin-right: 0.85em; + text-align: center; + text-indent: 0.15em; + vertical-align: middle; + width: 2em; + } + + a.special:not(.button):hover:before { + background-color: rgba(255, 255, 255, 0.025); + } + + a.special:not(.button):active:before { + background-color: rgba(255, 255, 255, 0.075); + } + + strong, b { + color: #ffffff; + font-weight: 600; + } + + em, i { + font-style: italic; + } + + p { + margin: 0 0 2em 0; + } + + h1, h2, h3, h4, h5, h6 { + font-family: Raleway, Helvetica, sans-serif; + font-weight: 700; + letter-spacing: 0.1em; + margin: 0 0 1em 0; + } + + h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { + text-decoration: none; + border-bottom: 0; + } + + h1 span, h2 span, h3 span, h4 span, h5 span, h6 span { + font-weight: 200; + } + + h1.major, h2.major, h3.major, h4.major, h5.major, h6.major { + padding-bottom: 1em; + border-bottom: solid 2px rgba(255, 255, 255, 0.125); + } + +/* Image */ + + .image { + border-radius: 5px; + border: 0; + display: inline-block; + position: relative; + } + + .image img { + border-radius: 5px; + display: block; + } + + .image.left, .image.right { + max-width: 40%; + } + + .image.left img, .image.right img { + width: 100%; + } + + .image.left { + float: left; + padding: 0 1.5em 1em 0; + top: 0.25em; + } + + .image.right { + float: right; + padding: 0 0 1em 1.5em; + top: 0.25em; + } + + .image.fit { + display: block; + margin: 0 0 2em 0; + width: 100%; + } + + .image.fit img { + width: 100%; + } + + .image.main { + display: block; + margin: 0 0 3em 0; + width: 100%; + } + + .image.main img { + width: 100%; + } + +/* List */ + + ol { + list-style: decimal; + margin: 0 0 2em 0; + padding-left: 1.25em; + } + + ol li { + padding-left: 0.25em; + } + + ul { + list-style: disc; + margin: 0 0 2em 0; + padding-left: 1em; + } + + ul li { + padding-left: 0.5em; + } + + ul.alt { + list-style: none; + padding-left: 0; + } + + ul.alt li { + border-top: solid 1px rgba(255, 255, 255, 0.125); + padding: 0.5em 0; + } + + ul.alt li:first-child { + border-top: 0; + padding-top: 0; + } + + dl { + margin: 0 0 2em 0; + } + + dl dt { + display: block; + font-weight: 600; + margin: 0 0 1em 0; + } + + dl dd { + margin-left: 2em; + } + + +/* Button */ + + input[type="submit"], + input[type="reset"], + input[type="button"], + button, + .button { + -moz-appearance: none; + -webkit-appearance: none; + -ms-appearance: none; + appearance: none; + -moz-transition: background-color 0.2s ease-in-out; + -webkit-transition: background-color 0.2s ease-in-out; + -ms-transition: background-color 0.2s ease-in-out; + transition: background-color 0.2s ease-in-out; + background-color: transparent; + border-radius: 5px; + border: 0; + box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.125); + color: #ffffff !important; + cursor: pointer; + display: inline-block; + font-family: Raleway, Helvetica, sans-serif; + font-size: 0.8em; + font-weight: 700; + height: 3.75em; + letter-spacing: 0.1em; + line-height: 3.75em; + padding: 0 1em; + text-align: center; + text-decoration: none; + text-transform: uppercase; + white-space: nowrap; + } + + .modal button{ + height: 3em; + } + + input[type="submit"]:hover, + input[type="reset"]:hover, + input[type="button"]:hover, + button:hover, + .button:hover { + background-color: rgba(255, 255, 255, 0.025); + } + + input[type="submit"]:active, + input[type="reset"]:active, + input[type="button"]:active, + button:active, + .button:active { + background-color: rgba(255, 255, 255, 0.075); + } + + input[type="submit"].icon:before, + input[type="reset"].icon:before, + input[type="button"].icon:before, + button.icon:before, + .button.icon:before { + margin-right: 0.5em; + color: rgba(255, 255, 255, 0.35); + } + + input[type="submit"].primary, + input[type="reset"].primary, + input[type="button"].primary, + button.primary, + .button.primary { + background-color: #4c5c96; + box-shadow: none; + } + + input[type="submit"].primary:hover, + input[type="reset"].primary:hover, + input[type="button"].primary:hover, + button.primary:hover, + .button.primary:hover { + background-color: #53639e; + } + + input[type="submit"].primary:active, + input[type="reset"].primary:active, + input[type="button"].primary:active, + button.primary:active, + .button.primary:active { + background-color: #45558d; + } + + input[type="submit"].primary.icon:before, + input[type="reset"].primary.icon:before, + input[type="button"].primary.icon:before, + button.primary.icon:before, + .button.primary.icon:before { + color: #7985b0; + } + + input[type="submit"].fit, + input[type="reset"].fit, + input[type="button"].fit, + button.fit, + .button.fit { + width: 100%; + } + + input[type="submit"].small, + input[type="reset"].small, + input[type="button"].small, + button.small, + .button.small { + font-size: 0.6em; + } + + input[type="submit"].large, + input[type="reset"].large, + input[type="button"].large, + button.large, + .button.large { + font-size: 1em; + } + + input[type="submit"].disabled, input[type="submit"]:disabled, + input[type="reset"].disabled, + input[type="reset"]:disabled, + input[type="button"].disabled, + input[type="button"]:disabled, + button.disabled, + button:disabled, + .button.disabled, + .button:disabled { + opacity: 0.25; + } + + @media screen and (max-width: 480px) { + + input[type="submit"], + input[type="reset"], + input[type="button"], + button, + .button { + padding: 0; + } + + } + +/* Header */ + + #header { + -moz-transition: background-color 0.2s ease-in-out; + -webkit-transition: background-color 0.2s ease-in-out; + -ms-transition: background-color 0.2s ease-in-out; + transition: background-color 0.2s ease-in-out; + background-color: rgba(53, 56, 73, 0.95); + height: 3.5em; + left: 0; + line-height: 3.5em; + padding: 0 1.25em; + position: fixed; + top: 0; + width: 100%; + z-index: 10000; + } + + #header h1 { + -moz-transition: opacity 0.2s ease-in-out, visibility 0.2s; + -webkit-transition: opacity 0.2s ease-in-out, visibility 0.2s; + -ms-transition: opacity 0.2s ease-in-out, visibility 0.2s; + transition: opacity 0.2s ease-in-out, visibility 0.2s; + border-bottom: 0; + font-size: 0.8em; + margin-bottom: 0; + opacity: 1; + visibility: visible; + } + + #header h1 a { + border: 0; + } + + #header nav { + font-family: Raleway, Helvetica, sans-serif; + font-size: 0.8em; + font-weight: 700; + height: 3em; + letter-spacing: 0.1em; + line-height: 3em; + position: absolute; + right: 0.7em; + text-transform: uppercase; + top: 0.7em; + } + + #header nav a { + border: 0; + display: inline-block; + padding: 0 1em; + } + + #header nav a:before { + float: right; + margin-left: 0.75em; + } + + #header nav a { + text-decoration: none; + -moz-transition: background-color 0.2s ease-in-out; + -webkit-transition: background-color 0.2s ease-in-out; + -ms-transition: background-color 0.2s ease-in-out; + transition: background-color 0.2s ease-in-out; + border-radius: 5px; + box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.125); + padding: 0 1.35em; + } + + #header nav a:before { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + display: inline-block; + font-style: normal; + font-variant: normal; + text-rendering: auto; + line-height: 1; + text-transform: none !important; + font-family: 'Font Awesome 5 Free'; + font-weight: 900; + } + + #header nav a[href="#menu"]:before { + content: '\f0c9'; + line-height: inherit; + } + + #header nav a:hover { + background-color: rgba(255, 255, 255, 0.025); + } + + #header nav a:active { + background-color: rgba(255, 255, 255, 0.075); + } + + #header.alt { + background-color: transparent; + } + + #header.alt h1 { + opacity: 0; + visibility: hidden; + } + + @media screen and (max-width: 736px) { + + #header { + height: 2.75em; + line-height: 2.75em; + } + + #header nav { + top: 0; + right: 0; + height: inherit; + line-height: inherit; + } + + #header nav a { + height: inherit; + line-height: inherit; + } + + #header nav a { + box-shadow: none; + padding: 0 1em; + border-radius: 0; + } + + #header nav a:hover, #header nav a:active { + background-color: inherit; + } + + } + + @media screen and (max-width: 480px) { + + #header nav a { + width: 4em; + white-space: nowrap; + text-indent: 4em; + } + + #header nav a:before { + width: inherit; + position: absolute; + top: 0; + left: 0; + text-indent: 0; + text-align: right; + margin-left: 0; + padding-right: 1.25em; + } + + } + +/* Menu */ + + #page-wrapper { + -moz-transition: -moz-filter 0.25s ease; + -webkit-transition: -webkit-filter 0.25s ease; + -ms-transition: -ms-filter 0.25s ease; + transition: filter 0.25s ease; + } + + #menu { + -moz-align-items: center; + -webkit-align-items: center; + -ms-align-items: center; + align-items: center; + display: -moz-flex; + display: -webkit-flex; + display: -ms-flex; + display: flex; + -moz-justify-content: center; + -webkit-justify-content: center; + -ms-justify-content: center; + justify-content: center; + pointer-events: none; + -moz-transition: opacity 0.35s ease, visibility 0.35s; + -webkit-transition: opacity 0.35s ease, visibility 0.35s; + -ms-transition: opacity 0.35s ease, visibility 0.35s; + transition: opacity 0.35s ease, visibility 0.35s; + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + background: rgba(46, 49, 65, 0.8); + cursor: default; + height: 100%; + left: 0; + opacity: 0; + position: fixed; + text-align: center; + top: 0; + visibility: hidden; + width: 100%; + } + + #menu .inner { + padding: 2.5em 1.5em 0.5em 1.5em ; + -moz-transform: translateY(0.5em); + -webkit-transform: translateY(0.5em); + -ms-transform: translateY(0.5em); + transform: translateY(0.5em); + -moz-transition: opacity 0.35s ease, -moz-transform 0.35s ease; + -webkit-transition: opacity 0.35s ease, -webkit-transform 0.35s ease; + -ms-transition: opacity 0.35s ease, -ms-transform 0.35s ease; + transition: opacity 0.35s ease, transform 0.35s ease; + -webkit-overflow-scrolling: touch; + /*background: #4c5c96;*/ + background: rgba(53, 56, 73) !important; + border-radius: 5px; + display: block; + max-width: 100%; + opacity: 0; + width: 18em; + } + + #menu h2 { + border-bottom: solid 2px rgba(255, 255, 255, 0.125); + padding-bottom: 1em; + } + + #menu .close { + background-image: url("images/close.svg"); + background-position: 75% 25%; + background-repeat: no-repeat; + background-size: 2em 2em; + border: 0; + content: ''; + display: block; + height: 4em; + overflow: hidden; + position: absolute; + right: 0; + text-align: center; + text-indent: 4em; + top: 0; + width: 4em; + } + + #menu .links { + list-style: none; + margin-bottom: 1.5em; + padding: 0; + } + + #menu .links li { + padding: 0; + } + + #menu .links li a { + border-radius: 5px; + border: 0; + display: block; + font-family: Raleway, Helvetica, sans-serif; + font-size: 0.8em; + font-weight: 200; + letter-spacing: 0.1em; + line-height: 1.85em; + padding: 0.75em 0; + text-transform: uppercase; + } + + #menu .links li a:hover { + background: #4b4a5c; + } + + @media screen and (max-width: 736px) { + + #menu .inner { + max-height: 100%; + overflow-y: auto; + overflow-x: hidden; + } + + #menu .inner .close { + background-size: 1.5em 1.5em; + } + + } + + body.is-menu-visible #page-wrapper { + -moz-filter: blur(1.5px); + -webkit-filter: blur(1.5px); + -ms-filter: blur(1.5px); + filter: blur(1.5px); + } + + body.is-menu-visible #menu { + pointer-events: auto; + opacity: 1; + visibility: visible; + } + + body.is-menu-visible #menu .inner { + -moz-transform: translateY(0); + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + opacity: 1; + } + + + + +/* CSS PROPIO */ + +body { + padding-top: 6em; +} + +#marcaCabecera{ + color: #f4b942 !important; +} + +/* Oculta el header y el menú cuando el modal estÔ activo */ +body.modal-open header, +body.modal-open #header, +body.modal-open #menu, +body.is-menu-visible #header{ + display: none !important; +} + +.modalContent{ + /*background: #4c5c96;*/ + /*background: #1b1f22 !important;*/ + /*background: rgba(46, 49, 65) !important;*/ + background: rgba(53, 56, 73) !important; + color:white; +} + +.table{ + color: black; +} + +.estrella, .botPelicula{ + cursor: pointer; + transition: transform 0.2s, color 0.2s; +} + +.estrella:hover, .botPelicula:hover{ + transform: scale(1.3); +} + +.estrella{ + position: relative; +} + +.contenedorNombre{ + width: 75%; +} + +/* Esto hace que una celda no se traspase si es muy larga, +sino que crea dos filas */ +.tabulator-cell.expandirCelda{ + white-space: normal !important; +} + +#tituloTabla{ + margin:0; + font-size:2rem; +} +#numRegistros{ + margin-bottom:0; + margin-top:1rem !important; + font-size:1.3rem; +} + +.tresPuntos { + top: 50%; + right: .5rem; + margin-top: -0.8rem; +} +.botPuntos{ + position:relative; +} +.menuTabla{ + background-color: #2e3141; + position:absolute; + z-index: 2000 !important; +} +#cajaBusqueda, +#botonBuscar { + height: 25px !important; + padding-top: 0 !important; + padding-bottom: 0 !important; + line-height: 1 !important; +} + +#botonBuscar { + width: 30px; + display: flex; + align-items: center; + justify-content: center; +} + +#botonBuscar i { + font-size: 0.8rem; +} + +.menuTabla li{ + color:white; + + cursor: pointer; + +} +.menuTabla li:hover{ + background-color: #45558d; + color:white; +} + +input[type="text"]{ + color: #2e3141; +} + +#botPerfil{ + cursor:pointer; +} + +.card-body { + display: flex; + align-items: center; + justify-content: center; +} +#tablas{ + width:100%; +} + +/* Forzamos que la tabla no cambie de tamaño total */ +#tablas .tabulator{ + color:black; + width: 100% !important; + max-width: 850px; /* Ancho fijo para el contenedor */ + table-layout: fixed !important; /* IMPORTANTE: Respeta los anchos de columna */ + margin: 0 auto; + overflow: visible !important; +} + +/* Ajuste para que el texto largo no rompa la tabla */ +.tabulator-row { + word-wrap: break-word; + text-overflow: ellipsis; /* Si el nombre es larguísimo pone "..." */ + overflow: visible !important; +} +.tabulator .tabulator-footer .tabulator-page{ + background: rgba(46, 49, 65, 0.8); + color: white; + border: 1px solid #2e3141; + box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.125); + height: 35px; + line-height: 35px; /* Centra el texto verticalmente */ + padding: 0 10px; + font-size: 0.9rem; +} +.tabulator .tabulator-footer .tabulator-page.active{ + background: #ffc107; + color: white; + box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.125); + height: 35px; + line-height: 35px; /* Centra el texto verticalmente */ + padding: 0 10px; + font-size: 0.9rem; +} +.tabulator .tabulator-footer .tabulator-page:hover{ + background: rgba(46, 49, 65, 0.8); + color: white; + box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.125); + height: 35px; + line-height: 35px; /* Centra el texto verticalmente */ + padding: 0 10px; + font-size: 0.9rem; +} +.tabulator .tabulator-footer .tabulator-page.active:hover{ + background: #ffc107; + color: white; + box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.125); + height: 35px; + line-height: 35px; /* Centra el texto verticalmente */ + padding: 0 10px; + font-size: 0.9rem; +} +.tabulator .tabulator-footer .tabulator-page:disabled{ + background: rgba(46, 49, 65, 0.8); + color: white; + box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.125); + height: 35px; + line-height: 35px; /* Centra el texto verticalmente */ + padding: 0 10px; + font-size: 0.9rem; +} + +.tabulator .tabulator-footer select{ + background: rgba(46, 49, 65, 0.8); + color: white; + box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.125); + height: 35px; + line-height: 35px; /* Centra el texto verticalmente */ + padding: 0 10px; + font-size: 0.9rem; +} + +.tabulator .tabulator-cell{ + overflow: visible !important; +} + +.tabulator .tabulator-col-title{ + white-space: normal; + line-height: 1.2; +} + +.tabulator-tableholder{ + overflow: visible !important; +} + +.tabulator{ + overflow: visible !important; +} + +/* Alinear verticalmente la celda del nombre */ + +.tabulator-cell.nombreTabla > div { + position: relative; + height: 100%; +} +.tabulator-cell.nombreTabla > div > .text-center { + position: absolute; + top: 50%; + left: 0; + width: 100%; + transform: translateY(-50%); +} + + +/* Separacion de botones inferiores de la tabla */ +/* Separación entre Anterior y los números */ +.tabulator .tabulator-page[data-page="prev"]{ + margin-right: 0.75rem; +} + +/* Separación entre los números y Siguiente */ +.tabulator .tabulator-page[data-page="next"]{ + margin-left: 0.75rem; +} +/* Separación entre Primera y Filas */ +.tabulator .tabulator-page[data-page="first"]{ + margin-left: 1.5rem; +} + +.tabulator-pages{ + display: inline-flex; + justify-content: center; + width: 250px; /* ajusta a tu gusto */ +} + +.tabulator-pages .tabulator-page{ + width: 36px; + min-width: 36px; + padding: 0; +} + +#cabeceraTabla{ + font-size: 1.6rem; + font-weight: bold; + padding: 12px 0; + border-radius: 5px; + border: 0; + box-shadow: inset 0 0 0 2px rgba(46, 49, 65, 0.8); + /*background-color:rgba(46, 49, 65);*/ + background: rgba(53, 56, 73); +} + +.tabulator .tabulator-row.tabulator-selectable{ + cursor: default; +} + +.fav, +.notas, +#botBuscar, +.botPuntos, +.dropdown-item{ + cursor: pointer; +} + +@media (hover: hover) and (pointer: fine) { + .tabulator .tabulator-footer .tabulator-page:not(.disabled):hover{ + background: rgba(46, 49, 65, 0.8) !important; + border-color: #2e3141 !important; + color: white !important; + } +} + +/* Modal Buscar Api */ +.resultadoApi, .temporadaOpcion, .episodioOpcion, .serieCompleta, .temporadaCompleta{ + cursor:pointer; + border-radius:10px; + padding:10px; + transition:0.2s; +} +.resultadoApi:hover, .temporadaOpcion:hover, .episodioOpcion:hover, .serieCompleta:hover, .temporadaCompleta:hover{ + transform:scale(1.10); +} +.serieCompleta, .temporadaCompleta{ + border: 1px solid; +} +.resultadoApi.principal{ + text-align:center; + margin:auto; + width:50%; +} +.resultadoApi.principal img{ + width:180px; + height:270px; + object-fit:cover; +} +.resultadoApi.secundario img{ + width:80px; + height:120px; + object-fit:cover; +} +.resultadoApi.secundario{ + font-size:0.85rem; +} + +#mensajes{ + position: fixed; + top: 20px; + left: 50%; + transform: translateX(-50%); + z-index: 10000 !important; + width: 400px; + max-width: 90%; +} + +#contenidoAgregar{ + max-height: 60vh; + overflow-y: auto; + overflow-x: hidden; +} +#contenidoAgregarPend{ + max-height: 65vh; + overflow-y: auto; + overflow-x: hidden; +} + +/* Historial */ + +.tarjetaHistorial{ + background-color:rgba(46, 49, 65); +} + +#contenidoHistorial{ + max-height: 65vh; + overflow-y:auto; +} + +#panelHistorial{ + position: absolute; + top: 100%; + left: 0; + width: 100%; + max-height: 550px; + background-color: #4b4a5c; + z-index:1050; +} + +#botHistorial { + height: 20px !important; + padding-top: 0 !important; + padding-bottom: 0 !important; + line-height: 1 !important; +} + +/* Colores */ + +.colorPelicula{ + color: #FFD700 !important; +} +.tablaPelicula .tabulator-page.active, +.tablaPelicula .tabulator-page.active:hover, +.colorPeliculaBoton { + background-color: #FFD700 !important; +} + +.colorSerie{ + color: #FF8A3D !important; +} +.tablaSerie .tabulator-page.active, +.tablaSerie .tabulator-page.active:hover, +.colorSerieBoton { + background-color: #FF8A3D !important; +} + +.colorJuego{ + color: #A3E635 !important; +} +.tablaJuego .tabulator-page.active, +.tablaJuego .tabulator-page.active:hover, +.colorJuegoBoton { + background-color: #A3E635 !important; +} + +.colorLibro{ + color: #20B8D8 !important; +} +.tablaLibro .tabulator-page.active, +.tablaLibro .tabulator-page.active:hover, +.colorLibroBoton { + background-color: #20B8D8 !important; +} + +.botonSerie.active { + border-color: #FF8A3D; +} \ No newline at end of file diff --git a/assets/css/noscript.css b/assets/css/noscript.css new file mode 100644 index 0000000..f4fe536 --- /dev/null +++ b/assets/css/noscript.css @@ -0,0 +1,39 @@ +/* + Solid State by HTML5 UP + html5up.net | @ajlkn + Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +*/ + +/* Banner */ + + body.is-preload #banner .logo { + -moz-transform: none; + -webkit-transform: none; + -ms-transform: none; + transform: none; + opacity: 1; + } + + body.is-preload #banner h2 { + opacity: 1; + -moz-transform: none; + -webkit-transform: none; + -ms-transform: none; + transform: none; + -moz-filter: none; + -webkit-filter: none; + -ms-filter: none; + filter: none; + } + + body.is-preload #banner p { + opacity: 01; + -moz-transform: none; + -webkit-transform: none; + -ms-transform: none; + transform: none; + -moz-filter: none; + -webkit-filter: none; + -ms-filter: none; + filter: none; + } \ No newline at end of file diff --git a/assets/js/breakpoints.min.js b/assets/js/breakpoints.min.js new file mode 100644 index 0000000..e20ae89 --- /dev/null +++ b/assets/js/breakpoints.min.js @@ -0,0 +1,2 @@ +/* breakpoints.js v1.0 | @ajlkn | MIT licensed */ +var breakpoints=function(){"use strict";function e(e){t.init(e)}var t={list:null,media:{},events:[],init:function(e){t.list=e,window.addEventListener("resize",t.poll),window.addEventListener("orientationchange",t.poll),window.addEventListener("load",t.poll),window.addEventListener("fullscreenchange",t.poll)},active:function(e){var n,a,s,i,r,d,c;if(!(e in t.media)){if(">="==e.substr(0,2)?(a="gte",n=e.substr(2)):"<="==e.substr(0,2)?(a="lte",n=e.substr(2)):">"==e.substr(0,1)?(a="gt",n=e.substr(1)):"<"==e.substr(0,1)?(a="lt",n=e.substr(1)):"!"==e.substr(0,1)?(a="not",n=e.substr(1)):(a="eq",n=e),n&&n in t.list)if(i=t.list[n],Array.isArray(i)){if(r=parseInt(i[0]),d=parseInt(i[1]),isNaN(r)){if(isNaN(d))return;c=i[1].substr(String(d).length)}else c=i[0].substr(String(r).length);if(isNaN(r))switch(a){case"gte":s="screen";break;case"lte":s="screen and (max-width: "+d+c+")";break;case"gt":s="screen and (min-width: "+(d+1)+c+")";break;case"lt":s="screen and (max-width: -1px)";break;case"not":s="screen and (min-width: "+(d+1)+c+")";break;default:s="screen and (max-width: "+d+c+")"}else if(isNaN(d))switch(a){case"gte":s="screen and (min-width: "+r+c+")";break;case"lte":s="screen";break;case"gt":s="screen and (max-width: -1px)";break;case"lt":s="screen and (max-width: "+(r-1)+c+")";break;case"not":s="screen and (max-width: "+(r-1)+c+")";break;default:s="screen and (min-width: "+r+c+")"}else switch(a){case"gte":s="screen and (min-width: "+r+c+")";break;case"lte":s="screen and (max-width: "+d+c+")";break;case"gt":s="screen and (min-width: "+(d+1)+c+")";break;case"lt":s="screen and (max-width: "+(r-1)+c+")";break;case"not":s="screen and (max-width: "+(r-1)+c+"), screen and (min-width: "+(d+1)+c+")";break;default:s="screen and (min-width: "+r+c+") and (max-width: "+d+c+")"}}else s="("==i.charAt(0)?"screen and "+i:i;t.media[e]=!!s&&s}return t.media[e]!==!1&&window.matchMedia(t.media[e]).matches},on:function(e,n){t.events.push({query:e,handler:n,state:!1}),t.active(e)&&n()},poll:function(){var e,n;for(e=0;e+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 01){for(var r=0;r=i&&o>=t};break;case"bottom":h=function(t,e,n,i,o){return n>=i&&o>=n};break;case"middle":h=function(t,e,n,i,o){return e>=i&&o>=e};break;case"top-only":h=function(t,e,n,i,o){return i>=t&&n>=i};break;case"bottom-only":h=function(t,e,n,i,o){return n>=o&&o>=t};break;default:case"default":h=function(t,e,n,i,o){return n>=i&&o>=t}}return c=function(t){var i,o,l,s,r,a,u=this.state,h=!1,c=this.$element.offset();i=n.height(),o=t+i/2,l=t+i,s=this.$element.outerHeight(),r=c.top+e(this.options.top,s,i),a=c.top+s-e(this.options.bottom,s,i),h=this.test(t,o,l,r,a),h!=u&&(this.state=h,h?this.options.enter&&this.options.enter.apply(this.element):this.options.leave&&this.options.leave.apply(this.element)),this.options.scroll&&this.options.scroll.apply(this.element,[(o-r)/(a-r)])},p={id:a,options:u,test:h,handler:c,state:null,element:this,$element:s,timeoutId:null},o[a]=p,s.data("_scrollexId",p.id),p.options.initialize&&p.options.initialize.apply(this),s},jQuery.fn.unscrollex=function(){var e=t(this);if(0==this.length)return e;if(this.length>1){for(var n=0;n 0 + && $header.hasClass('alt')) { + + $window.on('resize', function() { $window.trigger('scroll'); }); + + $banner.scrollex({ + bottom: $header.outerHeight(), + terminate: function() { $header.removeClass('alt'); }, + enter: function() { $header.addClass('alt'); }, + leave: function() { $header.removeClass('alt'); } + }); + + } + + // Menu. + var $menu = $('#menu'); + + $menu._locked = false; + + $menu._lock = function() { + + if ($menu._locked) + return false; + + $menu._locked = true; + + window.setTimeout(function() { + $menu._locked = false; + }, 350); + + return true; + + }; + + + $menu._show = function() { + + if ($menu._lock()) + $body.addClass('is-menu-visible'); + + }; + + $menu._hide = function() { + + if ($menu._lock()) + $body.removeClass('is-menu-visible'); + + + }; + + $menu._hide = function() { + + + if ($menu._lock()) + $body.removeClass('is-menu-visible'); + +}; + + $menu._toggle = function() { + + if ($menu._lock()) + $body.toggleClass('is-menu-visible'); + + }; + + $menu + .appendTo($body) + .on('click', function(event) { + + event.stopPropagation(); + + // Hide. + $menu._hide(); + + }) + .find('.inner') + .on('click', '.close', function(event) { + + event.preventDefault(); + event.stopPropagation(); + event.stopImmediatePropagation(); + + // Hide. + $menu._hide(); + + }) + .on('click', function(event) { + event.stopPropagation(); + }) + .on('click', 'a', function(event) { + + var href = $(this).attr('href'); + + event.preventDefault(); + event.stopPropagation(); + + // Hide. + $menu._hide(); + + // Redirect. + window.setTimeout(function() { + window.location.href = href; + }, 350); + + }); + + $body + .on('click', 'a[href="#menu"]', function(event) { + + event.stopPropagation(); + event.preventDefault(); + + // Toggle. + $menu._toggle(); + + }) + .on('keydown', function(event) { + + // Hide on escape. + if (event.keyCode == 27) + $menu._hide(); + + }); + +})(jQuery); \ No newline at end of file diff --git a/assets/js/util.js b/assets/js/util.js new file mode 100644 index 0000000..ecf7b37 --- /dev/null +++ b/assets/js/util.js @@ -0,0 +1,587 @@ +(function($) { + + /** + * Generate an indented list of links from a nav. Meant for use with panel(). + * @return {jQuery} jQuery object. + */ + $.fn.navList = function() { + + var $this = $(this); + $a = $this.find('a'), + b = []; + + $a.each(function() { + + var $this = $(this), + indent = Math.max(0, $this.parents('li').length - 1), + href = $this.attr('href'), + target = $this.attr('target'); + + b.push( + '' + + '' + + $this.text() + + '' + ); + + }); + + return b.join(''); + + }; + + /** + * Panel-ify an element. + * @param {object} userConfig User config. + * @return {jQuery} jQuery object. + */ + $.fn.panel = function(userConfig) { + + // No elements? + if (this.length == 0) + return $this; + + // Multiple elements? + if (this.length > 1) { + + for (var i=0; i < this.length; i++) + $(this[i]).panel(userConfig); + + return $this; + + } + + // Vars. + var $this = $(this), + $body = $('body'), + $window = $(window), + id = $this.attr('id'), + config; + + // Config. + config = $.extend({ + + // Delay. + delay: 0, + + // Hide panel on link click. + hideOnClick: false, + + // Hide panel on escape keypress. + hideOnEscape: false, + + // Hide panel on swipe. + hideOnSwipe: false, + + // Reset scroll position on hide. + resetScroll: false, + + // Reset forms on hide. + resetForms: false, + + // Side of viewport the panel will appear. + side: null, + + // Target element for "class". + target: $this, + + // Class to toggle. + visibleClass: 'visible' + + }, userConfig); + + // Expand "target" if it's not a jQuery object already. + if (typeof config.target != 'jQuery') + config.target = $(config.target); + + // Panel. + + // Methods. + $this._hide = function(event) { + + // Already hidden? Bail. + if (!config.target.hasClass(config.visibleClass)) + return; + + // If an event was provided, cancel it. + if (event) { + + event.preventDefault(); + event.stopPropagation(); + + } + + // Hide. + config.target.removeClass(config.visibleClass); + + // Post-hide stuff. + window.setTimeout(function() { + + // Reset scroll position. + if (config.resetScroll) + $this.scrollTop(0); + + // Reset forms. + if (config.resetForms) + $this.find('form').each(function() { + this.reset(); + }); + + }, config.delay); + + }; + + // Vendor fixes. + $this + .css('-ms-overflow-style', '-ms-autohiding-scrollbar') + .css('-webkit-overflow-scrolling', 'touch'); + + // Hide on click. + if (config.hideOnClick) { + + $this.find('a') + .css('-webkit-tap-highlight-color', 'rgba(0,0,0,0)'); + + $this + .on('click', 'a', function(event) { + + var $a = $(this), + href = $a.attr('href'), + target = $a.attr('target'); + + if (!href || href == '#' || href == '' || href == '#' + id) + return; + + // Cancel original event. + event.preventDefault(); + event.stopPropagation(); + + // Hide panel. + $this._hide(); + + // Redirect to href. + window.setTimeout(function() { + + if (target == '_blank') + window.open(href); + else + window.location.href = href; + + }, config.delay + 10); + + }); + + } + + // Event: Touch stuff. + $this.on('touchstart', function(event) { + + $this.touchPosX = event.originalEvent.touches[0].pageX; + $this.touchPosY = event.originalEvent.touches[0].pageY; + + }) + + $this.on('touchmove', function(event) { + + if ($this.touchPosX === null + || $this.touchPosY === null) + return; + + var diffX = $this.touchPosX - event.originalEvent.touches[0].pageX, + diffY = $this.touchPosY - event.originalEvent.touches[0].pageY, + th = $this.outerHeight(), + ts = ($this.get(0).scrollHeight - $this.scrollTop()); + + // Hide on swipe? + if (config.hideOnSwipe) { + + var result = false, + boundary = 20, + delta = 50; + + switch (config.side) { + + case 'left': + result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX > delta); + break; + + case 'right': + result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX < (-1 * delta)); + break; + + case 'top': + result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY > delta); + break; + + case 'bottom': + result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY < (-1 * delta)); + break; + + default: + break; + + } + + if (result) { + + $this.touchPosX = null; + $this.touchPosY = null; + $this._hide(); + + return false; + + } + + } + + // Prevent vertical scrolling past the top or bottom. + if (($this.scrollTop() < 0 && diffY < 0) + || (ts > (th - 2) && ts < (th + 2) && diffY > 0)) { + + event.preventDefault(); + event.stopPropagation(); + + } + + }); + + // Event: Prevent certain events inside the panel from bubbling. + $this.on('click touchend touchstart touchmove', function(event) { + event.stopPropagation(); + }); + + // Event: Hide panel if a child anchor tag pointing to its ID is clicked. + $this.on('click', 'a[href="#' + id + '"]', function(event) { + + event.preventDefault(); + event.stopPropagation(); + + config.target.removeClass(config.visibleClass); + + }); + + // Body. + + // Event: Hide panel on body click/tap. + $body.on('click touchend', function(event) { + $this._hide(event); + }); + + // Event: Toggle. + $body.on('click', 'a[href="#' + id + '"]', function(event) { + + event.preventDefault(); + event.stopPropagation(); + + config.target.toggleClass(config.visibleClass); + + }); + + // Window. + + // Event: Hide on ESC. + if (config.hideOnEscape) + $window.on('keydown', function(event) { + + if (event.keyCode == 27) + $this._hide(event); + + }); + + return $this; + + }; + + /** + * Apply "placeholder" attribute polyfill to one or more forms. + * @return {jQuery} jQuery object. + */ + $.fn.placeholder = function() { + + // Browser natively supports placeholders? Bail. + if (typeof (document.createElement('input')).placeholder != 'undefined') + return $(this); + + // No elements? + if (this.length == 0) + return $this; + + // Multiple elements? + if (this.length > 1) { + + for (var i=0; i < this.length; i++) + $(this[i]).placeholder(); + + return $this; + + } + + // Vars. + var $this = $(this); + + // Text, TextArea. + $this.find('input[type=text],textarea') + .each(function() { + + var i = $(this); + + if (i.val() == '' + || i.val() == i.attr('placeholder')) + i + .addClass('polyfill-placeholder') + .val(i.attr('placeholder')); + + }) + .on('blur', function() { + + var i = $(this); + + if (i.attr('name').match(/-polyfill-field$/)) + return; + + if (i.val() == '') + i + .addClass('polyfill-placeholder') + .val(i.attr('placeholder')); + + }) + .on('focus', function() { + + var i = $(this); + + if (i.attr('name').match(/-polyfill-field$/)) + return; + + if (i.val() == i.attr('placeholder')) + i + .removeClass('polyfill-placeholder') + .val(''); + + }); + + // Password. + $this.find('input[type=password]') + .each(function() { + + var i = $(this); + var x = $( + $('
') + .append(i.clone()) + .remove() + .html() + .replace(/type="password"/i, 'type="text"') + .replace(/type=password/i, 'type=text') + ); + + if (i.attr('id') != '') + x.attr('id', i.attr('id') + '-polyfill-field'); + + if (i.attr('name') != '') + x.attr('name', i.attr('name') + '-polyfill-field'); + + x.addClass('polyfill-placeholder') + .val(x.attr('placeholder')).insertAfter(i); + + if (i.val() == '') + i.hide(); + else + x.hide(); + + i + .on('blur', function(event) { + + event.preventDefault(); + + var x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]'); + + if (i.val() == '') { + + i.hide(); + x.show(); + + } + + }); + + x + .on('focus', function(event) { + + event.preventDefault(); + + var i = x.parent().find('input[name=' + x.attr('name').replace('-polyfill-field', '') + ']'); + + x.hide(); + + i + .show() + .focus(); + + }) + .on('keypress', function(event) { + + event.preventDefault(); + x.val(''); + + }); + + }); + + // Events. + $this + .on('submit', function() { + + $this.find('input[type=text],input[type=password],textarea') + .each(function(event) { + + var i = $(this); + + if (i.attr('name').match(/-polyfill-field$/)) + i.attr('name', ''); + + if (i.val() == i.attr('placeholder')) { + + i.removeClass('polyfill-placeholder'); + i.val(''); + + } + + }); + + }) + .on('reset', function(event) { + + event.preventDefault(); + + $this.find('select') + .val($('option:first').val()); + + $this.find('input,textarea') + .each(function() { + + var i = $(this), + x; + + i.removeClass('polyfill-placeholder'); + + switch (this.type) { + + case 'submit': + case 'reset': + break; + + case 'password': + i.val(i.attr('defaultValue')); + + x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]'); + + if (i.val() == '') { + i.hide(); + x.show(); + } + else { + i.show(); + x.hide(); + } + + break; + + case 'checkbox': + case 'radio': + i.attr('checked', i.attr('defaultValue')); + break; + + case 'text': + case 'textarea': + i.val(i.attr('defaultValue')); + + if (i.val() == '') { + i.addClass('polyfill-placeholder'); + i.val(i.attr('placeholder')); + } + + break; + + default: + i.val(i.attr('defaultValue')); + break; + + } + }); + + }); + + return $this; + + }; + + /** + * Moves elements to/from the first positions of their respective parents. + * @param {jQuery} $elements Elements (or selector) to move. + * @param {bool} condition If true, moves elements to the top. Otherwise, moves elements back to their original locations. + */ + $.prioritize = function($elements, condition) { + + var key = '__prioritize'; + + // Expand $elements if it's not already a jQuery object. + if (typeof $elements != 'jQuery') + $elements = $($elements); + + // Step through elements. + $elements.each(function() { + + var $e = $(this), $p, + $parent = $e.parent(); + + // No parent? Bail. + if ($parent.length == 0) + return; + + // Not moved? Move it. + if (!$e.data(key)) { + + // Condition is false? Bail. + if (!condition) + return; + + // Get placeholder (which will serve as our point of reference for when this element needs to move back). + $p = $e.prev(); + + // Couldn't find anything? Means this element's already at the top, so bail. + if ($p.length == 0) + return; + + // Move element to top of parent. + $e.prependTo($parent); + + // Mark element as moved. + $e.data(key, $p); + + } + + // Moved already? + else { + + // Condition is true? Bail. + if (condition) + return; + + $p = $e.data(key); + + // Move element back to its original location (using our placeholder). + $e.insertAfter($p); + + // Unmark element as moved. + $e.removeData(key); + + } + + }); + + }; + +})(jQuery); \ No newline at end of file diff --git a/assets/sass/base/_page.scss b/assets/sass/base/_page.scss new file mode 100644 index 0000000..bc72cdf --- /dev/null +++ b/assets/sass/base/_page.scss @@ -0,0 +1,59 @@ +/// +/// Solid State by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Basic */ + + // MSIE: Required for IEMobile. + @-ms-viewport { + width: device-width; + } + + // MSIE: Prevents scrollbar from overlapping content. + body { + -ms-overflow-style: scrollbar; + } + + // Ensures page width is always >=320px. + @include breakpoint('<=xsmall') { + html, body { + min-width: 320px; + } + } + + // Set box model to border-box. + // Based on css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice + html { + box-sizing: border-box; + } + + *, *:before, *:after { + box-sizing: inherit; + } + + body { + background-color: _palette(bg); + + background-image: linear-gradient(to top, transparentize(_palette(bg), 0.2), transparentize(_palette(bg), 0.2)), + url('../../images/bg.jpg'); + + background-size: auto, + cover; + + background-attachment: fixed, + fixed; + + background-position: center, + center; + + // Stops initial animations until page loads. + &.is-preload { + *, *:before, *:after { + @include vendor('animation', 'none !important'); + @include vendor('transition', 'none !important'); + } + } + + } \ No newline at end of file diff --git a/assets/sass/base/_reset.scss b/assets/sass/base/_reset.scss new file mode 100644 index 0000000..8efa65f --- /dev/null +++ b/assets/sass/base/_reset.scss @@ -0,0 +1,76 @@ +/// +/// Solid State by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +// Reset. +// Based on meyerweb.com/eric/tools/css/reset (v2.0 | 20110126 | License: public domain) + + html, body, div, span, applet, object, + iframe, h1, h2, h3, h4, h5, h6, p, blockquote, + pre, a, abbr, acronym, address, big, cite, + code, del, dfn, em, img, ins, kbd, q, s, samp, + small, strike, strong, sub, sup, tt, var, b, + u, i, center, dl, dt, dd, ol, ul, li, fieldset, + form, label, legend, table, caption, tbody, + tfoot, thead, tr, th, td, article, aside, + canvas, details, embed, figure, figcaption, + footer, header, hgroup, menu, nav, output, ruby, + section, summary, time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; + } + + article, aside, details, figcaption, figure, + footer, header, hgroup, menu, nav, section { + display: block; + } + + body { + line-height: 1; + } + + ol, ul { + list-style:none; + } + + blockquote, q { + quotes: none; + + &:before, + &:after { + content: ''; + content: none; + } + } + + table { + border-collapse: collapse; + border-spacing: 0; + } + + body { + -webkit-text-size-adjust: none; + } + + mark { + background-color: transparent; + color: inherit; + } + + input::-moz-focus-inner { + border: 0; + padding: 0; + } + + input, select, textarea { + -moz-appearance: none; + -webkit-appearance: none; + -ms-appearance: none; + appearance: none; + } \ No newline at end of file diff --git a/assets/sass/base/_typography.scss b/assets/sass/base/_typography.scss new file mode 100644 index 0000000..f89af0d --- /dev/null +++ b/assets/sass/base/_typography.scss @@ -0,0 +1,219 @@ +/// +/// Solid State by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Type */ + + body, input, select, textarea { + color: _palette(fg); + font-family: _font(family); + font-size: 16.5pt; + font-weight: _font(weight); + line-height: 1.65; + + @include breakpoint('<=xlarge') { + font-size: 13pt; + } + + @include breakpoint('<=large') { + font-size: 12pt; + } + + @include breakpoint('<=medium') { + font-size: 12pt; + } + + @include breakpoint('<=small') { + font-size: 12pt; + } + + @include breakpoint('<=xsmall') { + font-size: 12pt; + } + } + + a { + @include vendor('transition', 'color #{_duration(transition)} ease-in-out, border-bottom-color #{_duration(transition)} ease-in-out'); + border-bottom: dotted 1px _palette(fg-light); + color: _palette(fg-bold); + text-decoration: none; + + &:hover { + border-bottom-color: transparent; + color: _palette(fg-bold) !important; + } + + &.special:not(.button) { + @include icon(false, solid); + border-bottom: 0; + display: block; + font-family: _font(family-heading); + font-size: 0.8em; + font-weight: _font(weight-heading-bold); + letter-spacing: _font(kern-heading); + margin: 0 0 _size(element-margin) 0; + text-transform: uppercase; + + &:before { + @include vendor('transition', 'background-color #{_duration(transition)} ease-in-out'); + border-radius: 100%; + border: solid 2px _palette(border); + content: '\f105'; + display: inline-block; + font-size: 1.25em; + height: 2em; + line-height: 1.75em; + margin-right: 0.85em; + text-align: center; + text-indent: 0.15em; + vertical-align: middle; + width: 2em; + } + + &:hover { + &:before { + background-color: _palette(border-bg); + } + } + + &:active { + &:before { + background-color: _palette(border2-bg); + } + } + } + } + + strong, b { + color: _palette(fg-bold); + font-weight: _font(weight-bold); + } + + em, i { + font-style: italic; + } + + p { + margin: 0 0 _size(element-margin) 0; + } + + h1, h2, h3, h4, h5, h6 { + color: _palette(fg-bold); + font-family: _font(family-heading); + font-weight: _font(weight-heading-bold); + letter-spacing: _font(kern-heading); + margin: 0 0 (_size(element-margin) * 0.5) 0; + text-transform: uppercase; + + a { + color: inherit; + text-decoration: none; + border-bottom: 0; + } + + span { + font-weight: _font(weight-heading); + } + + &.major { + padding-bottom: 1em; + border-bottom: solid 2px _palette(border); + } + } + + h2 { + font-size: 1.2em; + } + + h3 { + font-size: 0.9em; + } + + h4 { + font-size: 0.7em; + } + + h5 { + font-size: 0.7em; + } + + h6 { + font-size: 0.7em; + } + + @include breakpoint('<=small') { + h2 { + font-size: 1em; + } + + h3 { + font-size: 0.8em + } + } + + sub { + font-size: 0.8em; + position: relative; + top: 0.5em; + } + + sup { + font-size: 0.8em; + position: relative; + top: -0.5em; + } + + blockquote { + border-left: solid 4px _palette(border); + font-style: italic; + margin: 0 0 _size(element-margin) 0; + padding: (_size(element-margin) / 4) 0 (_size(element-margin) / 4) _size(element-margin); + } + + code { + background: _palette(border-bg); + border-radius: _size(border-radius); + border: solid 2px _palette(border); + font-family: _font(family-fixed); + font-size: 0.9em; + margin: 0 0.25em; + padding: 0.25em 0.65em; + } + + pre { + -webkit-overflow-scrolling: touch; + font-family: _font(family-fixed); + font-size: 0.9em; + margin: 0 0 _size(element-margin) 0; + + code { + display: block; + line-height: 1.75em; + padding: 1em 1.5em; + overflow-x: auto; + } + } + + hr { + border: 0; + border-bottom: solid 2px _palette(border); + margin: (_size(element-margin) * 1.25) 0; + + &.major { + margin: (_size(element-margin) * 2) 0; + } + } + + .align-left { + text-align: left; + } + + .align-center { + text-align: center; + } + + .align-right { + text-align: right; + } \ No newline at end of file diff --git a/assets/sass/components/_actions.scss b/assets/sass/components/_actions.scss new file mode 100644 index 0000000..101a9d7 --- /dev/null +++ b/assets/sass/components/_actions.scss @@ -0,0 +1,101 @@ +/// +/// Solid State by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Actions */ + + ul.actions { + @include vendor('display', 'flex'); + cursor: default; + list-style: none; + margin-left: (_size(element-margin) * -0.5); + padding-left: 0; + + li { + padding: 0 0 0 (_size(element-margin) * 0.5); + vertical-align: middle; + } + + &.special { + @include vendor('justify-content', 'center'); + width: 100%; + margin-left: 0; + + li { + &:first-child { + padding-left: 0; + } + } + } + + &.stacked { + @include vendor('flex-direction', 'column'); + margin-left: 0; + + li { + padding: (_size(element-margin) * 0.65) 0 0 0; + + &:first-child { + padding-top: 0; + } + } + } + + &.fit { + width: calc(100% + #{_size(element-margin) * 0.5}); + + li { + @include vendor('flex-grow', '1'); + @include vendor('flex-shrink', '1'); + width: 100%; + + > * { + width: 100%; + } + } + + &.stacked { + width: 100%; + } + } + + @include breakpoint('<=xsmall') { + &:not(.fixed) { + @include vendor('flex-direction', 'column'); + margin-left: 0; + width: 100% !important; + + li { + @include vendor('flex-grow', '1'); + @include vendor('flex-shrink', '1'); + padding: (_size(element-margin) * 0.5) 0 0 0; + text-align: center; + width: 100%; + + > * { + width: 100%; + } + + &:first-child { + padding-top: 0; + } + + input[type="submit"], + input[type="reset"], + input[type="button"], + button, + .button { + width: 100%; + + &.icon { + &:before { + margin-left: -0.5rem; + } + } + } + } + } + } + } \ No newline at end of file diff --git a/assets/sass/components/_box.scss b/assets/sass/components/_box.scss new file mode 100644 index 0000000..b47e9a1 --- /dev/null +++ b/assets/sass/components/_box.scss @@ -0,0 +1,26 @@ +/// +/// Solid State by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Box */ + + .box { + border-radius: _size(border-radius); + border: solid 2px _palette(border); + margin-bottom: _size(element-margin); + padding: 1.5em; + + > :last-child, + > :last-child > :last-child, + > :last-child > :last-child > :last-child { + margin-bottom: 0; + } + + &.alt { + border: 0; + border-radius: 0; + padding: 0; + } + } \ No newline at end of file diff --git a/assets/sass/components/_button.scss b/assets/sass/components/_button.scss new file mode 100644 index 0000000..2ed49b3 --- /dev/null +++ b/assets/sass/components/_button.scss @@ -0,0 +1,89 @@ +/// +/// Solid State by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Button */ + + input[type="submit"], + input[type="reset"], + input[type="button"], + button, + .button { + @include vendor('appearance', 'none'); + @include vendor('transition', 'background-color #{_duration(transition)} ease-in-out'); + background-color: transparent; + border-radius: _size(border-radius); + border: 0; + box-shadow: inset 0 0 0 2px _palette(border); + color: _palette(fg-bold) !important; + cursor: pointer; + display: inline-block; + font-family: _font(family-heading); + font-size: 0.8em; + font-weight: _font(weight-heading-bold); + height: 3.75em; + letter-spacing: _font(kern-heading); + line-height: 3.75em; + padding: 0 2.25em; + text-align: center; + text-decoration: none; + text-transform: uppercase; + white-space: nowrap; + + &:hover { + background-color: _palette(border-bg); + } + + &:active { + background-color: _palette(border2-bg); + } + + &.icon { + &:before { + margin-right: 0.5em; + color: _palette(fg-light); + } + } + + &.primary { + background-color: _palette(accent); + box-shadow: none; + + &:hover { + background-color: desaturate(lighten(_palette(accent), 3), 1.5); + } + + &:active { + background-color: saturate(darken(_palette(accent), 3), 1.5); + } + + &.icon { + &:before { + color: mix(_palette(fg-bold), _palette(accent), 25%); + } + } + } + + &.fit { + width: 100%; + } + + &.small { + font-size: 0.6em; + } + + &.large { + font-size: 1em; + } + + &.disabled, + &:disabled { + opacity: 0.25; + } + + @include breakpoint('<=xsmall') { + padding: 0; + } + } \ No newline at end of file diff --git a/assets/sass/components/_contact.scss b/assets/sass/components/_contact.scss new file mode 100644 index 0000000..4268bc1 --- /dev/null +++ b/assets/sass/components/_contact.scss @@ -0,0 +1,43 @@ +/// +/// Solid State by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Contact */ + + ul.contact { + list-style: none; + padding: 0; + + li { + @include icon; + margin: (_size(element-margin) * 1.25) 0 0 0; + padding: 0 0 0 3.25em; + position: relative; + + &:before { + border-radius: 100%; + border: solid 2px _palette(border); + display: inline-block; + font-size: 0.8em; + height: 2.5em; + left: 0; + line-height: 2.35em; + position: absolute; + text-align: center; + top: 0; + width: 2.5em; + } + + &:first-child { + margin-top: 0; + } + } + + @include breakpoint('<=small') { + li { + margin: (_size(element-margin) * 0.75) 0 0 0; + } + } + } \ No newline at end of file diff --git a/assets/sass/components/_features.scss b/assets/sass/components/_features.scss new file mode 100644 index 0000000..338fa58 --- /dev/null +++ b/assets/sass/components/_features.scss @@ -0,0 +1,71 @@ +/// +/// Solid State by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Features */ + + .features { + @include vendor('display', 'flex'); + @include vendor('flex-wrap', 'wrap'); + margin: 0 0 _size(element-margin) 0; + + article { + @include padding(1.75em, 1.75em); + background-color: desaturate(lighten(_palette(bg), 3), 1.5); + border-radius: _size(border-radius); + margin: (_size(section-spacing, large) * 0.5) _size(section-spacing, large) (_size(section-spacing, large) * 0.5) 0; + width: calc(50% - #{_size(section-spacing, large) * 0.5}); + + &:nth-child(2n) { + margin-right: 0; + } + + .image { + border-radius: _size(border-radius) _size(border-radius) 0 0; + display: block; + margin-bottom: 1.75em; + margin-left: -1.75em; + margin-top: -1.75em; + position: relative; + width: calc(100% + #{3.5em}); + + img { + border-radius: _size(border-radius) _size(border-radius) 0 0; + width: 100%; + } + } + } + + @include breakpoint('<=medium') { + article { + margin: (_size(section-spacing, medium) * 0.5) _size(section-spacing, medium) (_size(section-spacing, medium) * 0.5) 0; + width: calc(50% - #{_size(section-spacing, medium) * 0.5}); + } + } + + @include breakpoint('<=small') { + article { + @include padding(1.5em, 1.5em); + margin: (_size(section-spacing, small) * 0.5) _size(section-spacing, small) (_size(section-spacing, small) * 0.5) 0; + width: calc(50% - #{_size(section-spacing, small) * 0.5} - 1px); + + .image { + margin-bottom: 1.5em; + margin-left: -1.5em; + margin-top: -1.5em; + width: calc(100% + #{3em}); + } + } + } + + @include breakpoint('<=xsmall') { + display: block; + + article { + width: 100%; + margin: 0 0 _size(element-margin) 0 !important; + } + } + } \ No newline at end of file diff --git a/assets/sass/components/_form.scss b/assets/sass/components/_form.scss new file mode 100644 index 0000000..70fe6ea --- /dev/null +++ b/assets/sass/components/_form.scss @@ -0,0 +1,236 @@ +/// +/// Solid State by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Form */ + + form { + margin: 0 0 _size(element-margin) 0; + + > :last-child { + margin-bottom: 0; + } + + > .fields { + $gutter: (_size(element-margin) * 0.75); + + @include vendor('display', 'flex'); + @include vendor('flex-wrap', 'wrap'); + width: calc(100% + #{$gutter * 2}); + margin: ($gutter * -1) 0 _size(element-margin) ($gutter * -1); + + > .field { + @include vendor('flex-grow', '0'); + @include vendor('flex-shrink', '0'); + padding: $gutter 0 0 $gutter; + width: calc(100% - #{$gutter * 1}); + + &.half { + width: calc(50% - #{$gutter * 0.5}); + } + + &.third { + width: calc(#{100% / 3} - #{$gutter * (1 / 3)}); + } + + &.quarter { + width: calc(25% - #{$gutter * 0.25}); + } + } + } + + @include breakpoint('<=xsmall') { + > .fields { + $gutter: (_size(element-margin) * 0.75); + + width: calc(100% + #{$gutter * 2}); + margin: ($gutter * -1) 0 _size(element-margin) ($gutter * -1); + + > .field { + padding: $gutter 0 0 $gutter; + width: calc(100% - #{$gutter * 1}); + + &.half { + width: calc(100% - #{$gutter * 1}); + } + + &.third { + width: calc(100% - #{$gutter * 1}); + } + + &.quarter { + width: calc(100% - #{$gutter * 1}); + } + } + } + } + } + + label { + color: _palette(fg-bold); + display: block; + font-family: _font(family-heading); + font-size: 0.8em; + font-weight: _font(weight-heading-bold); + letter-spacing: _font(kern-heading); + margin: 0 0 (_size(element-margin) * 0.35) 0; + text-transform: uppercase; + } + + input[type="text"], + input[type="password"], + input[type="email"], + input[type="tel"], + select, + textarea { + @include vendor('appearance', 'none'); + background: _palette(border-bg); + border-radius: _size(border-radius); + border: none; + border: solid 2px _palette(border); + color: inherit; + display: block; + outline: 0; + padding: 0 1em; + text-decoration: none; + width: 100%; + + &:invalid { + box-shadow: none; + } + + &:focus { + border-color: desaturate(lighten(_palette(accent), 6), 3); + } + } + + select { + background-image: svg-url(""); + background-size: 1.25rem; + background-repeat: no-repeat; + background-position: calc(100% - 1rem) center; + height: _size(element-height); + padding-right: _size(element-height); + text-overflow: ellipsis; + + option { + color: _palette(fg-bold); + background: _palette(bg); + } + + &:focus { + &::-ms-value { + background-color: transparent; + } + } + + &::-ms-expand { + display: none; + } + } + + input[type="text"], + input[type="password"], + input[type="email"], + select { + height: _size(element-height); + } + + textarea { + padding: 0.75em 1em; + } + + input[type="checkbox"], + input[type="radio"], { + @include vendor('appearance', 'none'); + display: block; + float: left; + margin-right: -2em; + opacity: 0; + width: 1em; + z-index: -1; + + & + label { + @include icon(false, solid); + color: _palette(fg); + cursor: pointer; + display: inline-block; + font-size: 1em; + font-family: _font(family); + text-transform: none; + letter-spacing: 0; + font-weight: _font(weight); + padding-left: (_size(element-height) * 0.6) + 0.75em; + padding-right: 0.75em; + position: relative; + + &:before { + background: _palette(border-bg); + border-radius: _size(border-radius); + border: solid 2px _palette(border); + content: ''; + display: inline-block; + font-size: 0.8em; + height: (_size(element-height) * 0.75); + left: 0; + line-height: (_size(element-height) * 0.75); + position: absolute; + text-align: center; + top: 0; + width: (_size(element-height) * 0.75); + } + } + + &:checked + label { + &:before { + background: _palette(fg-bold); + border-color: _palette(fg-bold); + content: '\f00c'; + color: _palette(bg); + } + } + + &:focus + label { + &:before { + border-color: _palette(accent); + } + } + } + + input[type="checkbox"] { + & + label { + &:before { + border-radius: _size(border-radius); + } + } + } + + input[type="radio"] { + & + label { + &:before { + border-radius: 100%; + } + } + } + + ::-webkit-input-placeholder { + color: _palette(fg-light) !important; + opacity: 1.0; + } + + :-moz-placeholder { + color: _palette(fg-light) !important; + opacity: 1.0; + } + + ::-moz-placeholder { + color: _palette(fg-light) !important; + opacity: 1.0; + } + + :-ms-input-placeholder { + color: _palette(fg-light) !important; + opacity: 1.0; + } \ No newline at end of file diff --git a/assets/sass/components/_icon.scss b/assets/sass/components/_icon.scss new file mode 100644 index 0000000..b9df1c8 --- /dev/null +++ b/assets/sass/components/_icon.scss @@ -0,0 +1,33 @@ +/// +/// Solid State by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Icon */ + + .icon { + @include icon; + border-bottom: none; + position: relative; + + > .label { + display: none; + } + + &:before { + line-height: inherit; + } + + &.solid { + &:before { + font-weight: 900; + } + } + + &.brands { + &:before { + font-family: 'Font Awesome 5 Brands'; + } + } + } \ No newline at end of file diff --git a/assets/sass/components/_icons.scss b/assets/sass/components/_icons.scss new file mode 100644 index 0000000..0b50151 --- /dev/null +++ b/assets/sass/components/_icons.scss @@ -0,0 +1,28 @@ +/// +/// Solid State by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Icons */ + + ul.icons { + cursor: default; + list-style: none; + padding-left: 0; + + li { + display: inline-block; + padding: 0 1em 0 0; + + &:last-child { + padding-right: 0; + } + + .icon { + &:before { + font-size: 1.25em; + } + } + } + } \ No newline at end of file diff --git a/assets/sass/components/_image.scss b/assets/sass/components/_image.scss new file mode 100644 index 0000000..9403b25 --- /dev/null +++ b/assets/sass/components/_image.scss @@ -0,0 +1,60 @@ +/// +/// Solid State by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Image */ + + .image { + border-radius: _size(border-radius); + border: 0; + display: inline-block; + position: relative; + + img { + border-radius: _size(border-radius); + display: block; + } + + &.left, + &.right { + max-width: 40%; + + img { + width: 100%; + } + } + + &.left { + float: left; + padding: 0 1.5em 1em 0; + top: 0.25em; + } + + &.right { + float: right; + padding: 0 0 1em 1.5em; + top: 0.25em; + } + + &.fit { + display: block; + margin: 0 0 _size(element-margin) 0; + width: 100%; + + img { + width: 100%; + } + } + + &.main { + display: block; + margin: 0 0 (_size(element-margin) * 1.5) 0; + width: 100%; + + img { + width: 100%; + } + } + } \ No newline at end of file diff --git a/assets/sass/components/_list.scss b/assets/sass/components/_list.scss new file mode 100644 index 0000000..0bf97be --- /dev/null +++ b/assets/sass/components/_list.scss @@ -0,0 +1,56 @@ +/// +/// Solid State by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* List */ + + ol { + list-style: decimal; + margin: 0 0 _size(element-margin) 0; + padding-left: 1.25em; + + li { + padding-left: 0.25em; + } + } + + ul { + list-style: disc; + margin: 0 0 _size(element-margin) 0; + padding-left: 1em; + + li { + padding-left: 0.5em; + } + + &.alt { + list-style: none; + padding-left: 0; + + li { + border-top: solid 1px _palette(border); + padding: 0.5em 0; + + &:first-child { + border-top: 0; + padding-top: 0; + } + } + } + } + + dl { + margin: 0 0 _size(element-margin) 0; + + dt { + display: block; + font-weight: _font(weight-bold); + margin: 0 0 (_size(element-margin) * 0.5) 0; + } + + dd { + margin-left: _size(element-margin); + } + } \ No newline at end of file diff --git a/assets/sass/components/_pagination.scss b/assets/sass/components/_pagination.scss new file mode 100644 index 0000000..665f96e --- /dev/null +++ b/assets/sass/components/_pagination.scss @@ -0,0 +1,75 @@ +/// +/// Solid State by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Pagination */ + + ul.pagination { + cursor: default; + list-style: none; + padding-left: 0; + + li { + display: inline-block; + padding-left: 0; + vertical-align: middle; + + > .page { + @include vendor('transition', ( + 'background-color #{_duration(transition)} ease-in-out', + 'color #{_duration(transition)} ease-in-out' + )); + border-bottom: 0; + border-radius: _size(border-radius); + display: inline-block; + height: 1.5em; + line-height: 1.5em; + margin: 0 0.125em; + min-width: 1.5em; + padding: 0 0.5em; + text-align: center; + + &:hover { + background-color: _palette(border-bg); + } + + &.active { + background-color: _palette(accent); + } + } + + &:first-child { + padding-right: 0.75em; + } + + &:last-child { + padding-left: 0.75em; + } + } + + @include breakpoint('<=xsmall') { + li { + &:nth-child(n+2):nth-last-child(n+2) { + display: none; + } + + .button { + width: 100%; + } + + &:first-child { + width: calc(50% - 2px); + text-align: left; + padding-right: 0.325em; + } + + &:last-child { + width: calc(50% - 2px); + text-align: right; + padding-left: 0.325em; + } + } + } + } diff --git a/assets/sass/components/_row.scss b/assets/sass/components/_row.scss new file mode 100644 index 0000000..ff63c88 --- /dev/null +++ b/assets/sass/components/_row.scss @@ -0,0 +1,35 @@ +/// +/// Solid State by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Row */ + + .row { + @include html-grid(1.75em); + + @include breakpoint('<=xlarge') { + @include html-grid(1.75em, xlarge); + } + + @include breakpoint('<=large') { + @include html-grid(1.75em, large); + } + + @include breakpoint('<=medium') { + @include html-grid(1.75em, medium); + } + + @include breakpoint('<=small') { + @include html-grid(1.25em, small); + } + + @include breakpoint('<=xsmall') { + @include html-grid(1.25em, xsmall); + } + + @include breakpoint('<=xxsmall') { + @include html-grid(1.25em, xxsmall); + } + } \ No newline at end of file diff --git a/assets/sass/components/_section.scss b/assets/sass/components/_section.scss new file mode 100644 index 0000000..c5d96d6 --- /dev/null +++ b/assets/sass/components/_section.scss @@ -0,0 +1,13 @@ +/// +/// Solid State by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Section/Article */ + + section, article { + &.special { + text-align: center; + } + } \ No newline at end of file diff --git a/assets/sass/components/_table.scss b/assets/sass/components/_table.scss new file mode 100644 index 0000000..5be89dc --- /dev/null +++ b/assets/sass/components/_table.scss @@ -0,0 +1,81 @@ +/// +/// Solid State by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Table */ + + .table-wrapper { + -webkit-overflow-scrolling: touch; + overflow-x: auto; + } + + table { + margin: 0 0 _size(element-margin) 0; + width: 100%; + + tbody { + tr { + border: solid 1px _palette(border); + border-left: 0; + border-right: 0; + + &:nth-child(2n + 1) { + background-color: _palette(border-bg); + } + } + } + + td { + padding: 0.75em 0.75em; + } + + th { + color: _palette(fg-bold); + font-size: 0.9em; + font-weight: _font(weight-bold); + padding: 0 0.75em 0.75em 0.75em; + text-align: left; + } + + thead { + border-bottom: solid 2px _palette(border); + } + + tfoot { + border-top: solid 2px _palette(border); + } + + &.alt { + border-collapse: separate; + + tbody { + tr { + td { + border: solid 1px _palette(border); + border-left-width: 0; + border-top-width: 0; + + &:first-child { + border-left-width: 1px; + } + } + + &:first-child { + td { + border-top-width: 1px; + } + } + } + } + + thead { + border-bottom: 0; + } + + tfoot { + border-top: 0; + } + } + } \ No newline at end of file diff --git a/assets/sass/layout/_banner.scss b/assets/sass/layout/_banner.scss new file mode 100644 index 0000000..c35f48c --- /dev/null +++ b/assets/sass/layout/_banner.scss @@ -0,0 +1,140 @@ +/// +/// Solid State by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Banner */ + + #banner { + @include padding(10em, 0, (0, 0, _size(wrapper-edges, large) * -0.5, 0)); + + .inner { + margin: 0 auto; + width: _size(inner); + } + + .logo { + @include vendor('transition', ( + 'opacity 2s ease', + 'transform 1s ease', + )); + @include vendor('transform', 'translateY(0)'); + opacity: 1; + margin: 0 0 (_size(element-margin) * 0.65) 0; + + .icon { + border-radius: 100%; + border: solid 2px _palette(border); + cursor: default; + display: inline-block; + font-size: 2em; + height: 2.25em; + line-height: 2.25em; + text-align: center; + width: 2.25em; + } + } + + h2 { + @include vendor('transition', ( + 'opacity 0.5s ease', + 'transform 0.5s ease', + 'filter 0.25s ease', + )); + @include vendor('transform', 'translateX(0)'); + @include vendor('transition-delay', '0.65s'); + @include vendor('filter', 'blur(0)'); + opacity: 1; + border-bottom: solid 2px _palette(border); + font-size: 2.25em; + margin-bottom: _size(element-margin) * 0.4; + padding-bottom: _size(element-margin) * 0.2; + } + + p { + @include vendor('transition', ( + 'opacity 0.5s ease', + 'transform 0.5s ease', + 'filter 0.25s ease', + )); + @include vendor('transform', 'translateX(0)'); + @include vendor('transition-delay', '0.8s'); + @include vendor('filter', 'blur(0)'); + opacity: 1; + font-family: _font(family-heading); + font-size: 1em; + font-weight: _font(weight-heading); + letter-spacing: _font(kern-heading); + line-height: 2; + text-transform: uppercase; + } + + @include breakpoint('<=large') { + @include padding(7em, 0, (0, 0, _size(wrapper-edges, large) * 0.5, 0)); + + background-color: _palette(bg); + + background-image: linear-gradient(to top, transparentize(_palette(bg), 0.2), transparentize(_palette(bg), 0.2)), + url('../../images/bg.jpg'); + + background-size: auto, + cover; + + background-position: center, + center; + + margin-bottom: (_size(wrapper-edges, large) * -1); + } + + @include breakpoint('<=medium') { + @include padding(12em, 3em, (0, 0, _size(wrapper-edges, medium) * 0.5, 0)); + + margin-bottom: (_size(wrapper-edges, medium) * -1); + + .inner { + width: 100%; + } + } + + @include breakpoint('<=small') { + @include padding(5em, 2em, (0, 0, _size(wrapper-edges, small) * 0.5, 0)); + + margin-bottom: (_size(wrapper-edges, small) * -1); + + .logo { + margin: 0 0 (_size(element-margin) * 0.5) 0; + + .icon { + font-size: 1.5em; + } + } + + h2 { + font-size: 1.5em; + } + + p { + font-size: 0.8em; + } + } + + body.is-preload & { + .logo { + @include vendor('transform', 'translateY(0.5em)'); + opacity: 0; + } + + h2 { + opacity: 0; + @include vendor('transform', 'translateX(0.25em)'); + @include vendor('filter', 'blur(2px)'); + } + + p { + opacity: 0; + @include vendor('transform', 'translateX(0.5em)'); + @include vendor('filter', 'blur(2px)'); + } + } + } \ No newline at end of file diff --git a/assets/sass/layout/_footer.scss b/assets/sass/layout/_footer.scss new file mode 100644 index 0000000..5b4d542 --- /dev/null +++ b/assets/sass/layout/_footer.scss @@ -0,0 +1,143 @@ +/// +/// Solid State by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Footer */ + + #footer { + .inner { + @include padding(5em, 0); + @include vendor('display', 'flex'); + @include vendor('flex-direction', 'row'); + @include vendor('flex-wrap', 'wrap'); + margin: 0 auto; + width: _size(inner); + + > * { + width: 100%; + } + + form { + margin: 0 _size(section-spacing, large) 0 0; + width: calc(50% - #{_size(section-spacing, large) * 0.5}); + } + + .contact { + width: calc(50% - #{_size(section-spacing, large) * 0.5}); + } + + .copyright { + border-top: solid 2px _palette(border); + list-style: none; + margin: (_size(element-margin) * 2) 0 _size(element-margin) 0; + padding: _size(element-margin) 0 0 0; + width: 100%; + + li { + border-left: solid 2px _palette(border); + color: _palette(fg-light); + display: inline-block; + font-size: 0.9em; + line-height: 1; + margin-left: 1em; + padding: 0; + padding-left: 1em; + + &:first-child { + border-left: 0; + margin-left: 0; + padding-left: 0; + } + + a { + color: inherit; + } + } + } + } + + @include breakpoint('<=large') { + + background-color: _palette(bg); + + background-image: linear-gradient(to top, transparentize(_palette(bg), 0.2), transparentize(_palette(bg), 0.2)), + url('../../images/bg.jpg'); + + background-size: auto, + cover; + + background-position: center, + center; + + margin-top: (_size(wrapper-edges, large) * -1); + padding-top: _size(wrapper-edges, large); + + } + + @include breakpoint('<=medium') { + margin-top: (_size(wrapper-edges, medium) * -1); + padding-top: _size(wrapper-edges, medium); + + .inner { + @include padding(3em, 3em); + display: block; + width: 100%; + + form { + width: 100%; + margin: 0 0 (_size(element-margin) * 2) 0; + } + + .contact { + width: 100%; + margin: 0 0 (_size(element-margin) * 2) 0; + } + + .copyright { + margin: (_size(element-margin) * 2) 0 _size(element-margin) 0; + } + } + } + + @include breakpoint('<=small') { + margin-top: (_size(wrapper-edges, small) * -1); + padding-top: _size(wrapper-edges, small); + + .inner { + @include padding(2em, 2em); + + form { + margin: 0 0 (_size(element-margin) * 1.5) 0; + } + + .contact { + margin: 0 0 (_size(element-margin) * 1.5) 0; + } + } + } + + @include breakpoint('<=xsmall') { + .inner { + .copyright { + li { + border-left: 0; + display: block; + margin: 1em 0 0 0; + padding-left: 0; + + &:first-child { + margin-top: 0; + } + } + } + } + } + + @include breakpoint('<=xxsmall') { + .inner { + @include padding(2em, 1.5em); + } + } + } \ No newline at end of file diff --git a/assets/sass/layout/_header.scss b/assets/sass/layout/_header.scss new file mode 100644 index 0000000..35e42ad --- /dev/null +++ b/assets/sass/layout/_header.scss @@ -0,0 +1,141 @@ +/// +/// Solid State by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Header */ + + #header { + @include vendor('transition', 'background-color #{_duration(transition)} ease-in-out'); + background-color: transparentize(desaturate(lighten(_palette(bg), 3), 1.5), 0.05); + height: 3.5em; + left: 0; + line-height: 3.5em; + padding: 0 1.25em; + position: fixed; + top: 0; + width: 100%; + z-index: _misc(z-index-base); + + h1 { + @include vendor('transition', ( + 'opacity #{_duration(transition)} ease-in-out', + 'visibility #{_duration(transition)}' + )); + border-bottom: 0; + font-size: 0.8em; + margin-bottom: 0; + opacity: 1; + visibility: visible; + + a { + border: 0; + } + } + + nav { + font-family: _font(family-heading); + font-size: 0.8em; + font-weight: _font(weight-heading-bold); + height: 3em; + letter-spacing: _font(kern-heading); + line-height: 3em; + position: absolute; + right: 0.7em; + text-transform: uppercase; + top: 0.7em; + + a { + border: 0; + display: inline-block; + padding: 0 1em; + + &:before { + float: right; + margin-left: 0.75em; + } + + &[href="#menu"] { + @include icon(false, solid); + @include vendor('transition', 'background-color #{_duration(transition)} ease-in-out'); + border-radius: _size(border-radius); + box-shadow: inset 0 0 0 2px _palette(border); + padding: 0 1.35em; + + &:before { + content: '\f0c9'; + line-height: inherit; + } + + &:hover { + background-color: _palette(border-bg); + } + + &:active { + background-color: _palette(border2-bg); + } + } + } + } + + &.alt { + background-color: transparent; + + h1 { + opacity: 0; + visibility: hidden; + } + } + + @include breakpoint('<=small') { + height: 2.75em; + line-height: 2.75em; + + nav { + top: 0; + right: 0; + height: inherit; + line-height: inherit; + + a { + height: inherit; + line-height: inherit; + + &[href="#menu"] { + box-shadow: none; + padding: 0 1em; + border-radius: 0; + + &:hover, &:active { + background-color: inherit; + } + } + } + } + } + + @include breakpoint('<=xsmall') { + nav { + a { + &[href="#menu"] { + width: 4em; + white-space: nowrap; + text-indent: 4em; + position: relative; + + &:before { + width: inherit; + position: absolute; + top: 0; + left: 0; + text-indent: 0; + text-align: right; + margin-left: 0; + padding-right: 1.25em; + } + } + } + } + } + } \ No newline at end of file diff --git a/assets/sass/layout/_menu.scss b/assets/sass/layout/_menu.scss new file mode 100644 index 0000000..c1cbf4f --- /dev/null +++ b/assets/sass/layout/_menu.scss @@ -0,0 +1,127 @@ +/// +/// Solid State by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Menu */ + + #page-wrapper { + @include vendor('transition', 'filter 0.25s ease'); + } + + #menu { + @include vendor('align-items', 'center'); + @include vendor('display', 'flex'); + @include vendor('justify-content', 'center'); + @include vendor('pointer-events', 'none'); + @include vendor('transition', ('opacity #{_duration(menu)} ease', 'visibility #{_duration(menu)}')); + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-tap-highlight-color: rgba(0,0,0,0); + background: transparentize(_palette(bg), 0.2); + cursor: default; + height: 100%; + left: 0; + opacity: 0; + position: fixed; + text-align: center; + top: 0; + visibility: hidden; + width: 100%; + + .inner { + @include padding(2.5em, 1.5em); + @include vendor('transform', 'translateY(0.5em)'); + @include vendor('transition', ('opacity #{_duration(menu)} ease','transform #{_duration(menu)} ease')); + -webkit-overflow-scrolling: touch; + background: _palette(accent); + border-radius: _size(border-radius); + display: block; + max-width: 100%; + opacity: 0; + position: relative; + width: 18em; + } + + h2 { + border-bottom: solid 2px _palette(border); + padding-bottom: 1em; + } + + .close { + background-image: url('images/close.svg'); + background-position: 75% 25%; + background-repeat: no-repeat; + background-size: 2em 2em; + border: 0; + content: ''; + display: block; + height: 4em; + overflow: hidden; + position: absolute; + right: 0; + text-align: center; + text-indent: 4em; + top: 0; + width: 4em; + } + + .links { + list-style: none; + margin-bottom: (_size(element-margin) - 0.5em); + padding: 0; + + li { + padding: 0; + + a { + border-radius: _size(border-radius); + border: 0; + display: block; + font-family: _font(family-heading); + font-size: 0.8em; + font-weight: _font(weight-heading); + letter-spacing: _font(kern-heading); + line-height: 1.85em; + padding: 0.75em 0; + text-transform: uppercase; + + &:hover { + background: saturate(darken(_palette(accent), 3), 1.5); + } + } + } + } + + @include breakpoint('<=small') { + .inner { + max-height: 100%; + overflow-y: auto; + overflow-x: hidden; + + .close { + background-size: 1.5em 1.5em; + } + } + } + } + + body.is-menu-visible { + #page-wrapper { + @include vendor('filter', 'blur(1.5px)'); + } + + #menu { + @include vendor('pointer-events', 'auto'); + opacity: 1; + visibility: visible; + + .inner { + @include vendor('transform', 'translateY(0)'); + opacity: 1; + } + } + } \ No newline at end of file diff --git a/assets/sass/layout/_wrapper.scss b/assets/sass/layout/_wrapper.scss new file mode 100644 index 0000000..7020093 --- /dev/null +++ b/assets/sass/layout/_wrapper.scss @@ -0,0 +1,303 @@ +/// +/// Solid State by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Wrapper */ + + /// Sets the colors of the wrapper's top/bottom edges. + /// @param {string} $color Color. + @mixin wrapper-edges-color($color: black) { + &:before, &:after { + background-image: svg-url(''); + } + + &:before { + box-shadow: inset 0 -1px 0 0 $color, 0 1px 0 0 $color; + } + + &:after { + box-shadow: inset 0 -1px 0 0 $color, 0 1px 0 0 $color; + } + } + + #wrapper { + > header { + @include padding(7.5em, 0, (3.5em, 0, _size(wrapper-edges, large) * -0.5, 0)); + + .inner { + margin: 0 auto; + width: _size(inner); + } + + h2 { + border-bottom: solid 2px _palette(border); + font-size: 2em; + margin-bottom: _size(element-margin) * 0.4; + padding-bottom: _size(element-margin) * 0.2; + } + + p { + font-family: _font(family-heading); + font-size: 1em; + font-weight: _font(weight-heading); + letter-spacing: _font(kern-heading); + line-height: 2; + text-transform: uppercase; + } + } + + @include breakpoint('<=large') { + > header { + @include padding(5em, 0, (4em, 0, _size(wrapper-edges, large) * 0.5, 0)); + + background-color: _palette(bg); + + background-image: linear-gradient(to top, transparentize(_palette(bg), 0.2), transparentize(_palette(bg), 0.2)), + url('../../images/bg.jpg'); + + background-size: auto, + cover; + + background-position: center, + 0% 30%; + + margin-bottom: (_size(wrapper-edges, large) * -1); + } + } + + @include breakpoint('<=medium') { + > header { + @include padding(7em, 3em, (4em, 0, _size(wrapper-edges, medium) * 0.5, 0)); + + background-size: auto, + cover; + + background-position: center, + 0% 0%; + + margin-bottom: (_size(wrapper-edges, medium) * -1); + + .inner { + width: 100%; + } + } + } + + @include breakpoint('<=small') { + > header { + @include padding(3.75em, 2em, (2.75em, 0, _size(wrapper-edges, small) * 0.5, 0)); + + background-size: auto, + 125%; + + margin-bottom: (_size(wrapper-edges, small) * -1); + + h2 { + font-size: 1.25em; + } + + p { + font-size: 0.8em; + } + } + } + } + + .wrapper { + background-color: _palette(bg); + margin: _size(wrapper-edges, large) 0; + position: relative; + @include wrapper-edges-color(_palette(bg)); + + &:before, &:after { + background-repeat: no-repeat; + background-size: 100% 100%; + content: ''; + display: block; + height: _size(wrapper-edges, large); + position: absolute; + width: 100%; + } + + &:before { + left: 0; + top: (_size(wrapper-edges, large) * -1); + } + + &:after { + @include vendor('transform', 'scaleY(-1)'); + bottom: (_size(wrapper-edges, large) * -1); + left: 0; + } + + &.alt { + &:before { + @include vendor('transform', 'scaleX(-1)'); + } + + &:after { + @include vendor('transform', 'scaleY(-1) scaleX(-1)'); + } + } + + .inner { + @include padding(3em, 0); + margin: 0 auto; + width: _size(inner); + } + + @for $i from 2 through _misc(max-wrapper-styles) { + $j: 3 * ($i - 1); + $color: desaturate(lighten(_palette(bg), $j), $j * 0.5); + + &.style#{$i} { + background-color: $color; + @include wrapper-edges-color($color); + } + } + + &.spotlight { + @include wrapper-edges-color(_palette(accent)); + background-color: _palette(accent); + + .inner { + @include vendor('display', 'flex'); + @include vendor('align-items', 'center'); + @include vendor('flex-direction', 'row'); + } + + .image { + border-radius: 100%; + margin: 0 _size(section-spacing, large) _size(element-margin) 0; + width: 22em; + overflow: hidden; + -ms-flex: 1; + + img { + border-radius: 100%; + width: 100%; + } + } + + .content { + width: 100%; + -ms-flex: 2; + } + + &:nth-child(2n - 1) { + .inner { + @include vendor('flex-direction', 'row-reverse'); + text-align: right; + } + + .image { + margin: 0 0 _size(element-margin) _size(section-spacing, large); + } + } + + @for $i from 2 through _misc(max-wrapper-styles) { + $j: 3 * ($i - 1); + $color: saturate(darken(_palette(accent), $j), $j * 0.5); + + &.style#{$i} { + background-color: $color; + @include wrapper-edges-color($color); + } + } + } + + @include breakpoint('<=medium') { + margin: _size(wrapper-edges, medium) 0; + + &:before, &:after { + height: _size(wrapper-edges, medium); + } + + &:before { + top: (_size(wrapper-edges, medium) * -1); + } + + &:after { + bottom: (_size(wrapper-edges, medium) * -1); + left: 0; + } + + .inner { + @include padding(3em, 3em); + width: 100%; + } + + &.spotlight { + .image { + margin: 0 _size(section-spacing, medium) _size(element-margin) 0; + width: 32em; + } + + &:nth-child(2n - 1) { + .image { + margin: 0 0 _size(element-margin) _size(section-spacing, medium); + } + } + } + } + + @include breakpoint('<=small') { + margin: _size(wrapper-edges, small) 0; + + &:before, &:after { + height: _size(wrapper-edges, small); + } + + &:before { + top: (_size(wrapper-edges, small) * -1); + } + + &:after { + bottom: (_size(wrapper-edges, small) * -1); + left: 0; + } + + .inner { + @include padding(2em, 2em); + } + + &.spotlight { + .inner { + @include vendor('align-items', 'flex-start'); + } + + .image { + width: 19em; + margin: 0 _size(section-spacing, small) _size(element-margin) 0; + } + + &:nth-child(2n - 1) { + .image { + margin: 0 0 _size(element-margin) _size(section-spacing, small); + } + } + } + } + + @include breakpoint('<=xsmall') { + &.spotlight { + .inner { + display: block; + } + + .image { + margin: 0 0 (_size(element-margin) * 0.5) 0 !important; + max-width: 85%; + width: 12em; + } + } + } + + @include breakpoint('<=xxsmall') { + .inner { + @include padding(2em, 1.5em); + } + } + } \ No newline at end of file diff --git a/assets/sass/libs/_breakpoints.scss b/assets/sass/libs/_breakpoints.scss new file mode 100644 index 0000000..c5301d8 --- /dev/null +++ b/assets/sass/libs/_breakpoints.scss @@ -0,0 +1,223 @@ +// breakpoints.scss v1.0 | @ajlkn | MIT licensed */ + +// Vars. + + /// Breakpoints. + /// @var {list} + $breakpoints: () !global; + +// Mixins. + + /// Sets breakpoints. + /// @param {map} $x Breakpoints. + @mixin breakpoints($x: ()) { + $breakpoints: $x !global; + } + + /// Wraps @content in a @media block targeting a specific orientation. + /// @param {string} $orientation Orientation. + @mixin orientation($orientation) { + @media screen and (orientation: #{$orientation}) { + @content; + } + } + + /// Wraps @content in a @media block using a given query. + /// @param {string} $query Query. + @mixin breakpoint($query: null) { + + $breakpoint: null; + $op: null; + $media: null; + + // Determine operator, breakpoint. + + // Greater than or equal. + @if (str-slice($query, 0, 2) == '>=') { + + $op: 'gte'; + $breakpoint: str-slice($query, 3); + + } + + // Less than or equal. + @elseif (str-slice($query, 0, 2) == '<=') { + + $op: 'lte'; + $breakpoint: str-slice($query, 3); + + } + + // Greater than. + @elseif (str-slice($query, 0, 1) == '>') { + + $op: 'gt'; + $breakpoint: str-slice($query, 2); + + } + + // Less than. + @elseif (str-slice($query, 0, 1) == '<') { + + $op: 'lt'; + $breakpoint: str-slice($query, 2); + + } + + // Not. + @elseif (str-slice($query, 0, 1) == '!') { + + $op: 'not'; + $breakpoint: str-slice($query, 2); + + } + + // Equal. + @else { + + $op: 'eq'; + $breakpoint: $query; + + } + + // Build media. + @if ($breakpoint and map-has-key($breakpoints, $breakpoint)) { + + $a: map-get($breakpoints, $breakpoint); + + // Range. + @if (type-of($a) == 'list') { + + $x: nth($a, 1); + $y: nth($a, 2); + + // Max only. + @if ($x == null) { + + // Greater than or equal (>= 0 / anything) + @if ($op == 'gte') { + $media: 'screen'; + } + + // Less than or equal (<= y) + @elseif ($op == 'lte') { + $media: 'screen and (max-width: ' + $y + ')'; + } + + // Greater than (> y) + @elseif ($op == 'gt') { + $media: 'screen and (min-width: ' + ($y + 1) + ')'; + } + + // Less than (< 0 / invalid) + @elseif ($op == 'lt') { + $media: 'screen and (max-width: -1px)'; + } + + // Not (> y) + @elseif ($op == 'not') { + $media: 'screen and (min-width: ' + ($y + 1) + ')'; + } + + // Equal (<= y) + @else { + $media: 'screen and (max-width: ' + $y + ')'; + } + + } + + // Min only. + @else if ($y == null) { + + // Greater than or equal (>= x) + @if ($op == 'gte') { + $media: 'screen and (min-width: ' + $x + ')'; + } + + // Less than or equal (<= inf / anything) + @elseif ($op == 'lte') { + $media: 'screen'; + } + + // Greater than (> inf / invalid) + @elseif ($op == 'gt') { + $media: 'screen and (max-width: -1px)'; + } + + // Less than (< x) + @elseif ($op == 'lt') { + $media: 'screen and (max-width: ' + ($x - 1) + ')'; + } + + // Not (< x) + @elseif ($op == 'not') { + $media: 'screen and (max-width: ' + ($x - 1) + ')'; + } + + // Equal (>= x) + @else { + $media: 'screen and (min-width: ' + $x + ')'; + } + + } + + // Min and max. + @else { + + // Greater than or equal (>= x) + @if ($op == 'gte') { + $media: 'screen and (min-width: ' + $x + ')'; + } + + // Less than or equal (<= y) + @elseif ($op == 'lte') { + $media: 'screen and (max-width: ' + $y + ')'; + } + + // Greater than (> y) + @elseif ($op == 'gt') { + $media: 'screen and (min-width: ' + ($y + 1) + ')'; + } + + // Less than (< x) + @elseif ($op == 'lt') { + $media: 'screen and (max-width: ' + ($x - 1) + ')'; + } + + // Not (< x and > y) + @elseif ($op == 'not') { + $media: 'screen and (max-width: ' + ($x - 1) + '), screen and (min-width: ' + ($y + 1) + ')'; + } + + // Equal (>= x and <= y) + @else { + $media: 'screen and (min-width: ' + $x + ') and (max-width: ' + $y + ')'; + } + + } + + } + + // String. + @else { + + // Missing a media type? Prefix with "screen". + @if (str-slice($a, 0, 1) == '(') { + $media: 'screen and ' + $a; + } + + // Otherwise, use as-is. + @else { + $media: $a; + } + + } + + } + + // Output. + @media #{$media} { + @content; + } + + } \ No newline at end of file diff --git a/assets/sass/libs/_functions.scss b/assets/sass/libs/_functions.scss new file mode 100644 index 0000000..b367524 --- /dev/null +++ b/assets/sass/libs/_functions.scss @@ -0,0 +1,90 @@ +/// Removes a specific item from a list. +/// @author Hugo Giraudel +/// @param {list} $list List. +/// @param {integer} $index Index. +/// @return {list} Updated list. +@function remove-nth($list, $index) { + + $result: null; + + @if type-of($index) != number { + @warn "$index: #{quote($index)} is not a number for `remove-nth`."; + } + @else if $index == 0 { + @warn "List index 0 must be a non-zero integer for `remove-nth`."; + } + @else if abs($index) > length($list) { + @warn "List index is #{$index} but list is only #{length($list)} item long for `remove-nth`."; + } + @else { + + $result: (); + $index: if($index < 0, length($list) + $index + 1, $index); + + @for $i from 1 through length($list) { + + @if $i != $index { + $result: append($result, nth($list, $i)); + } + + } + + } + + @return $result; + +} + +/// Gets a value from a map. +/// @author Hugo Giraudel +/// @param {map} $map Map. +/// @param {string} $keys Key(s). +/// @return {string} Value. +@function val($map, $keys...) { + + @if nth($keys, 1) == null { + $keys: remove-nth($keys, 1); + } + + @each $key in $keys { + $map: map-get($map, $key); + } + + @return $map; + +} + +/// Gets a duration value. +/// @param {string} $keys Key(s). +/// @return {string} Value. +@function _duration($keys...) { + @return val($duration, $keys...); +} + +/// Gets a font value. +/// @param {string} $keys Key(s). +/// @return {string} Value. +@function _font($keys...) { + @return val($font, $keys...); +} + +/// Gets a misc value. +/// @param {string} $keys Key(s). +/// @return {string} Value. +@function _misc($keys...) { + @return val($misc, $keys...); +} + +/// Gets a palette value. +/// @param {string} $keys Key(s). +/// @return {string} Value. +@function _palette($keys...) { + @return val($palette, $keys...); +} + +/// Gets a size value. +/// @param {string} $keys Key(s). +/// @return {string} Value. +@function _size($keys...) { + @return val($size, $keys...); +} \ No newline at end of file diff --git a/assets/sass/libs/_html-grid.scss b/assets/sass/libs/_html-grid.scss new file mode 100644 index 0000000..3c08069 --- /dev/null +++ b/assets/sass/libs/_html-grid.scss @@ -0,0 +1,149 @@ +// html-grid.scss v1.0 | @ajlkn | MIT licensed */ + +// Mixins. + + /// Initializes the current element as an HTML grid. + /// @param {mixed} $gutters Gutters (either a single number to set both column/row gutters, or a list to set them individually). + /// @param {mixed} $suffix Column class suffix (optional; either a single suffix or a list). + @mixin html-grid($gutters: 1.5em, $suffix: '') { + + // Initialize. + $cols: 12; + $multipliers: 0, 0.25, 0.5, 1, 1.50, 2.00; + $unit: 100% / $cols; + + // Suffixes. + $suffixes: null; + + @if (type-of($suffix) == 'list') { + $suffixes: $suffix; + } + @else { + $suffixes: ($suffix); + } + + // Gutters. + $guttersCols: null; + $guttersRows: null; + + @if (type-of($gutters) == 'list') { + + $guttersCols: nth($gutters, 1); + $guttersRows: nth($gutters, 2); + + } + @else { + + $guttersCols: $gutters; + $guttersRows: 0; + + } + + // Row. + display: flex; + flex-wrap: wrap; + box-sizing: border-box; + align-items: stretch; + + // Columns. + > * { + box-sizing: border-box; + } + + // Gutters. + &.gtr-uniform { + > * { + > :last-child { + margin-bottom: 0; + } + } + } + + // Alignment. + &.aln-left { + justify-content: flex-start; + } + + &.aln-center { + justify-content: center; + } + + &.aln-right { + justify-content: flex-end; + } + + &.aln-top { + align-items: flex-start; + } + + &.aln-middle { + align-items: center; + } + + &.aln-bottom { + align-items: flex-end; + } + + // Step through suffixes. + @each $suffix in $suffixes { + + // Suffix. + @if ($suffix != '') { + $suffix: '-' + $suffix; + } + @else { + $suffix: ''; + } + + // Row. + + // Important. + > .imp#{$suffix} { + order: -1; + } + + // Columns, offsets. + @for $i from 1 through $cols { + > .col-#{$i}#{$suffix} { + width: $unit * $i; + } + + > .off-#{$i}#{$suffix} { + margin-left: $unit * $i; + } + } + + // Step through multipliers. + @each $multiplier in $multipliers { + + // Gutters. + $class: null; + + @if ($multiplier != 1) { + $class: '.gtr-' + ($multiplier * 100); + } + + &#{$class} { + margin-top: ($guttersRows * $multiplier * -1); + margin-left: ($guttersCols * $multiplier * -1); + + > * { + padding: ($guttersRows * $multiplier) 0 0 ($guttersCols * $multiplier); + } + + // Uniform. + &.gtr-uniform { + margin-top: $guttersCols * $multiplier * -1; + + > * { + padding-top: $guttersCols * $multiplier; + } + } + + } + + } + + } + + } \ No newline at end of file diff --git a/assets/sass/libs/_mixins.scss b/assets/sass/libs/_mixins.scss new file mode 100644 index 0000000..8187463 --- /dev/null +++ b/assets/sass/libs/_mixins.scss @@ -0,0 +1,78 @@ +/// Makes an element's :before pseudoelement a FontAwesome icon. +/// @param {string} $content Optional content value to use. +/// @param {string} $category Optional category to use. +/// @param {string} $where Optional pseudoelement to target (before or after). +@mixin icon($content: false, $category: regular, $where: before) { + + text-decoration: none; + + &:#{$where} { + + @if $content { + content: $content; + } + + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + display: inline-block; + font-style: normal; + font-variant: normal; + text-rendering: auto; + line-height: 1; + text-transform: none !important; + + @if ($category == brands) { + font-family: 'Font Awesome 5 Brands'; + } + @elseif ($category == solid) { + font-family: 'Font Awesome 5 Free'; + font-weight: 900; + } + @else { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; + } + + } + +} + +/// Applies padding to an element, taking the current element-margin value into account. +/// @param {mixed} $tb Top/bottom padding. +/// @param {mixed} $lr Left/right padding. +/// @param {list} $pad Optional extra padding (in the following order top, right, bottom, left) +/// @param {bool} $important If true, adds !important. +@mixin padding($tb, $lr, $pad: (0,0,0,0), $important: null) { + + @if $important { + $important: '!important'; + } + + $x: 0.1em; + + @if unit(_size(element-margin)) == 'rem' { + $x: 0.1rem; + } + + padding: ($tb + nth($pad,1)) ($lr + nth($pad,2)) max($x, $tb - _size(element-margin) + nth($pad,3)) ($lr + nth($pad,4)) #{$important}; + +} + +/// Encodes a SVG data URL so IE doesn't choke (via codepen.io/jakob-e/pen/YXXBrp). +/// @param {string} $svg SVG data URL. +/// @return {string} Encoded SVG data URL. +@function svg-url($svg) { + + $svg: str-replace($svg, '"', '\''); + $svg: str-replace($svg, '%', '%25'); + $svg: str-replace($svg, '<', '%3C'); + $svg: str-replace($svg, '>', '%3E'); + $svg: str-replace($svg, '&', '%26'); + $svg: str-replace($svg, '#', '%23'); + $svg: str-replace($svg, '{', '%7B'); + $svg: str-replace($svg, '}', '%7D'); + $svg: str-replace($svg, ';', '%3B'); + + @return url("data:image/svg+xml;charset=utf8,#{$svg}"); + +} \ No newline at end of file diff --git a/assets/sass/libs/_vars.scss b/assets/sass/libs/_vars.scss new file mode 100644 index 0000000..581effc --- /dev/null +++ b/assets/sass/libs/_vars.scss @@ -0,0 +1,54 @@ +// Misc. + $misc: ( + z-index-base: 10000, + max-wrapper-styles: 6 + ); + +// Duration. + $duration: ( + menu: 0.35s, + transition: 0.2s + ); + +// Size. + $size: ( + border-radius: 5px, + element-height: 2.75em, + element-margin: 2em, + inner: 55em, + section-spacing: ( + large: 3em, + medium: 2em, + small: 1.75em + ), + wrapper-edges: ( + large: 6.5em, + medium: 4.75em, + small: 2.5em + ) + ); + +// Font. + $font: ( + family: ('Source Sans Pro', Helvetica, sans-serif), + family-fixed: ('Courier New', monospace), + family-heading: (Raleway, Helvetica, sans-serif), + weight: 300, + weight-bold: 600, + weight-heading: 200, + weight-heading-bold: 700, + kern-heading: 0.1em + ); + +// Palette. + $palette: ( + bg: #2e3141, + fg: #ffffff, + fg-bold: #ffffff, + fg-light: rgba(255,255,255,0.35), + border: rgba(255,255,255,0.125), + border-bg: rgba(255,255,255,0.025), + border2: rgba(255,255,255,0.25), + border2-bg: rgba(255,255,255,0.075), + accent: #4c5c96 + ); \ No newline at end of file diff --git a/assets/sass/libs/_vendor.scss b/assets/sass/libs/_vendor.scss new file mode 100644 index 0000000..6599a3f --- /dev/null +++ b/assets/sass/libs/_vendor.scss @@ -0,0 +1,376 @@ +// vendor.scss v1.0 | @ajlkn | MIT licensed */ + +// Vars. + + /// Vendor prefixes. + /// @var {list} + $vendor-prefixes: ( + '-moz-', + '-webkit-', + '-ms-', + '' + ); + + /// Properties that should be vendorized. + /// Data via caniuse.com, github.com/postcss/autoprefixer, and developer.mozilla.org + /// @var {list} + $vendor-properties: ( + + // Animation. + 'animation', + 'animation-delay', + 'animation-direction', + 'animation-duration', + 'animation-fill-mode', + 'animation-iteration-count', + 'animation-name', + 'animation-play-state', + 'animation-timing-function', + + // Appearance. + 'appearance', + + // Backdrop filter. + 'backdrop-filter', + + // Background image options. + 'background-clip', + 'background-origin', + 'background-size', + + // Box sizing. + 'box-sizing', + + // Clip path. + 'clip-path', + + // Filter effects. + 'filter', + + // Flexbox. + 'align-content', + 'align-items', + 'align-self', + 'flex', + 'flex-basis', + 'flex-direction', + 'flex-flow', + 'flex-grow', + 'flex-shrink', + 'flex-wrap', + 'justify-content', + 'order', + + // Font feature. + 'font-feature-settings', + 'font-language-override', + 'font-variant-ligatures', + + // Font kerning. + 'font-kerning', + + // Fragmented borders and backgrounds. + 'box-decoration-break', + + // Grid layout. + 'grid-column', + 'grid-column-align', + 'grid-column-end', + 'grid-column-start', + 'grid-row', + 'grid-row-align', + 'grid-row-end', + 'grid-row-start', + 'grid-template-columns', + 'grid-template-rows', + + // Hyphens. + 'hyphens', + 'word-break', + + // Masks. + 'mask', + 'mask-border', + 'mask-border-outset', + 'mask-border-repeat', + 'mask-border-slice', + 'mask-border-source', + 'mask-border-width', + 'mask-clip', + 'mask-composite', + 'mask-image', + 'mask-origin', + 'mask-position', + 'mask-repeat', + 'mask-size', + + // Multicolumn. + 'break-after', + 'break-before', + 'break-inside', + 'column-count', + 'column-fill', + 'column-gap', + 'column-rule', + 'column-rule-color', + 'column-rule-style', + 'column-rule-width', + 'column-span', + 'column-width', + 'columns', + + // Object fit. + 'object-fit', + 'object-position', + + // Regions. + 'flow-from', + 'flow-into', + 'region-fragment', + + // Scroll snap points. + 'scroll-snap-coordinate', + 'scroll-snap-destination', + 'scroll-snap-points-x', + 'scroll-snap-points-y', + 'scroll-snap-type', + + // Shapes. + 'shape-image-threshold', + 'shape-margin', + 'shape-outside', + + // Tab size. + 'tab-size', + + // Text align last. + 'text-align-last', + + // Text decoration. + 'text-decoration-color', + 'text-decoration-line', + 'text-decoration-skip', + 'text-decoration-style', + + // Text emphasis. + 'text-emphasis', + 'text-emphasis-color', + 'text-emphasis-position', + 'text-emphasis-style', + + // Text size adjust. + 'text-size-adjust', + + // Text spacing. + 'text-spacing', + + // Transform. + 'transform', + 'transform-origin', + + // Transform 3D. + 'backface-visibility', + 'perspective', + 'perspective-origin', + 'transform-style', + + // Transition. + 'transition', + 'transition-delay', + 'transition-duration', + 'transition-property', + 'transition-timing-function', + + // Unicode bidi. + 'unicode-bidi', + + // User select. + 'user-select', + + // Writing mode. + 'writing-mode', + + ); + + /// Values that should be vendorized. + /// Data via caniuse.com, github.com/postcss/autoprefixer, and developer.mozilla.org + /// @var {list} + $vendor-values: ( + + // Cross fade. + 'cross-fade', + + // Element function. + 'element', + + // Filter function. + 'filter', + + // Flexbox. + 'flex', + 'inline-flex', + + // Grab cursors. + 'grab', + 'grabbing', + + // Gradients. + 'linear-gradient', + 'repeating-linear-gradient', + 'radial-gradient', + 'repeating-radial-gradient', + + // Grid layout. + 'grid', + 'inline-grid', + + // Image set. + 'image-set', + + // Intrinsic width. + 'max-content', + 'min-content', + 'fit-content', + 'fill', + 'fill-available', + 'stretch', + + // Sticky position. + 'sticky', + + // Transform. + 'transform', + + // Zoom cursors. + 'zoom-in', + 'zoom-out', + + ); + +// Functions. + + /// Removes a specific item from a list. + /// @author Hugo Giraudel + /// @param {list} $list List. + /// @param {integer} $index Index. + /// @return {list} Updated list. + @function remove-nth($list, $index) { + + $result: null; + + @if type-of($index) != number { + @warn "$index: #{quote($index)} is not a number for `remove-nth`."; + } + @else if $index == 0 { + @warn "List index 0 must be a non-zero integer for `remove-nth`."; + } + @else if abs($index) > length($list) { + @warn "List index is #{$index} but list is only #{length($list)} item long for `remove-nth`."; + } + @else { + + $result: (); + $index: if($index < 0, length($list) + $index + 1, $index); + + @for $i from 1 through length($list) { + + @if $i != $index { + $result: append($result, nth($list, $i)); + } + + } + + } + + @return $result; + + } + + /// Replaces a substring within another string. + /// @author Hugo Giraudel + /// @param {string} $string String. + /// @param {string} $search Substring. + /// @param {string} $replace Replacement. + /// @return {string} Updated string. + @function str-replace($string, $search, $replace: '') { + + $index: str-index($string, $search); + + @if $index { + @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace); + } + + @return $string; + + } + + /// Replaces a substring within each string in a list. + /// @param {list} $strings List of strings. + /// @param {string} $search Substring. + /// @param {string} $replace Replacement. + /// @return {list} Updated list of strings. + @function str-replace-all($strings, $search, $replace: '') { + + @each $string in $strings { + $strings: set-nth($strings, index($strings, $string), str-replace($string, $search, $replace)); + } + + @return $strings; + + } + +// Mixins. + + /// Wraps @content in vendorized keyframe blocks. + /// @param {string} $name Name. + @mixin keyframes($name) { + + @-moz-keyframes #{$name} { @content; } + @-webkit-keyframes #{$name} { @content; } + @-ms-keyframes #{$name} { @content; } + @keyframes #{$name} { @content; } + + } + + /// Vendorizes a declaration's property and/or value(s). + /// @param {string} $property Property. + /// @param {mixed} $value String/list of value(s). + @mixin vendor($property, $value) { + + // Determine if property should expand. + $expandProperty: index($vendor-properties, $property); + + // Determine if value should expand (and if so, add '-prefix-' placeholder). + $expandValue: false; + + @each $x in $value { + @each $y in $vendor-values { + @if $y == str-slice($x, 1, str-length($y)) { + + $value: set-nth($value, index($value, $x), '-prefix-' + $x); + $expandValue: true; + + } + } + } + + // Expand property? + @if $expandProperty { + @each $vendor in $vendor-prefixes { + #{$vendor}#{$property}: #{str-replace-all($value, '-prefix-', $vendor)}; + } + } + + // Expand just the value? + @elseif $expandValue { + @each $vendor in $vendor-prefixes { + #{$property}: #{str-replace-all($value, '-prefix-', $vendor)}; + } + } + + // Neither? Treat them as a normal declaration. + @else { + #{$property}: #{$value}; + } + + } \ No newline at end of file diff --git a/assets/sass/main.scss b/assets/sass/main.scss new file mode 100644 index 0000000..84a12a8 --- /dev/null +++ b/assets/sass/main.scss @@ -0,0 +1,56 @@ +@import 'libs/vars'; +@import 'libs/functions'; +@import 'libs/mixins'; +@import 'libs/vendor'; +@import 'libs/breakpoints'; +@import 'libs/html-grid'; +@import 'fontawesome-all.min.css'; +@import url('https://fonts.googleapis.com/css?family=Raleway:200,700|Source+Sans+Pro:300,600,300italic,600italic'); + +/* + Solid State by HTML5 UP + html5up.net | @ajlkn + Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +*/ + +// Breakpoints. + + @include breakpoints(( + xlarge: (1281px, 1680px ), + large: (981px, 1280px ), + medium: (737px, 980px ), + small: (481px, 736px ), + xsmall: (361px, 480px ), + xxsmall: (null, 360px ) + )); + +// Base. + + @import 'base/reset'; + @import 'base/page'; + @import 'base/typography'; + +// Component. + + @import 'components/row'; + @import 'components/section'; + @import 'components/form'; + @import 'components/box'; + @import 'components/icon'; + @import 'components/image'; + @import 'components/list'; + @import 'components/actions'; + @import 'components/icons'; + @import 'components/contact'; + @import 'components/pagination'; + @import 'components/table'; + @import 'components/button'; + @import 'components/features'; + +// Layout. + + @import 'layout/header'; + @import 'layout/menu'; + @import 'layout/banner'; + @import 'layout/wrapper'; + @import 'layout/footer'; \ No newline at end of file diff --git a/assets/sass/noscript.scss b/assets/sass/noscript.scss new file mode 100644 index 0000000..22c65b1 --- /dev/null +++ b/assets/sass/noscript.scss @@ -0,0 +1,35 @@ +@import 'libs/vars'; +@import 'libs/functions'; +@import 'libs/mixins'; +@import 'libs/vendor'; +@import 'libs/breakpoints'; +@import 'libs/html-grid'; + +/* + Solid State by HTML5 UP + html5up.net | @ajlkn + Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +*/ + +/* Banner */ + + #banner { + body.is-preload & { + .logo { + @include vendor('transform', 'none'); + opacity: 1; + } + + h2 { + opacity: 1; + @include vendor('transform', 'none'); + @include vendor('filter', 'none'); + } + + p { + opacity: 01; + @include vendor('transform', 'none'); + @include vendor('filter', 'none'); + } + } + } \ No newline at end of file diff --git a/assets/webfonts/fa-brands-400.eot b/assets/webfonts/fa-brands-400.eot new file mode 100644 index 0000000..cba6c6c Binary files /dev/null and b/assets/webfonts/fa-brands-400.eot differ diff --git a/assets/webfonts/fa-brands-400.svg b/assets/webfonts/fa-brands-400.svg new file mode 100644 index 0000000..b9881a4 --- /dev/null +++ b/assets/webfonts/fa-brands-400.svg @@ -0,0 +1,3717 @@ + + + + +Created by FontForge 20201107 at Wed Aug 4 12:25:29 2021 + By Robert Madole +Copyright (c) Font Awesome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/webfonts/fa-brands-400.ttf b/assets/webfonts/fa-brands-400.ttf new file mode 100644 index 0000000..8d75ded Binary files /dev/null and b/assets/webfonts/fa-brands-400.ttf differ diff --git a/assets/webfonts/fa-brands-400.woff b/assets/webfonts/fa-brands-400.woff new file mode 100644 index 0000000..3375bef Binary files /dev/null and b/assets/webfonts/fa-brands-400.woff differ diff --git a/assets/webfonts/fa-brands-400.woff2 b/assets/webfonts/fa-brands-400.woff2 new file mode 100644 index 0000000..402f81c Binary files /dev/null and b/assets/webfonts/fa-brands-400.woff2 differ diff --git a/assets/webfonts/fa-regular-400.eot b/assets/webfonts/fa-regular-400.eot new file mode 100644 index 0000000..a4e5989 Binary files /dev/null and b/assets/webfonts/fa-regular-400.eot differ diff --git a/assets/webfonts/fa-regular-400.svg b/assets/webfonts/fa-regular-400.svg new file mode 100644 index 0000000..463af27 --- /dev/null +++ b/assets/webfonts/fa-regular-400.svg @@ -0,0 +1,801 @@ + + + + +Created by FontForge 20201107 at Wed Aug 4 12:25:29 2021 + By Robert Madole +Copyright (c) Font Awesome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/webfonts/fa-regular-400.ttf b/assets/webfonts/fa-regular-400.ttf new file mode 100644 index 0000000..7157aaf Binary files /dev/null and b/assets/webfonts/fa-regular-400.ttf differ diff --git a/assets/webfonts/fa-regular-400.woff b/assets/webfonts/fa-regular-400.woff new file mode 100644 index 0000000..ad077c6 Binary files /dev/null and b/assets/webfonts/fa-regular-400.woff differ diff --git a/assets/webfonts/fa-regular-400.woff2 b/assets/webfonts/fa-regular-400.woff2 new file mode 100644 index 0000000..5632894 Binary files /dev/null and b/assets/webfonts/fa-regular-400.woff2 differ diff --git a/assets/webfonts/fa-solid-900.eot b/assets/webfonts/fa-solid-900.eot new file mode 100644 index 0000000..e994171 Binary files /dev/null and b/assets/webfonts/fa-solid-900.eot differ diff --git a/assets/webfonts/fa-solid-900.svg b/assets/webfonts/fa-solid-900.svg new file mode 100644 index 0000000..00296e9 --- /dev/null +++ b/assets/webfonts/fa-solid-900.svg @@ -0,0 +1,5034 @@ + + + + +Created by FontForge 20201107 at Wed Aug 4 12:25:29 2021 + By Robert Madole +Copyright (c) Font Awesome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/webfonts/fa-solid-900.ttf b/assets/webfonts/fa-solid-900.ttf new file mode 100644 index 0000000..25abf38 Binary files /dev/null and b/assets/webfonts/fa-solid-900.ttf differ diff --git a/assets/webfonts/fa-solid-900.woff b/assets/webfonts/fa-solid-900.woff new file mode 100644 index 0000000..23ee663 Binary files /dev/null and b/assets/webfonts/fa-solid-900.woff differ diff --git a/assets/webfonts/fa-solid-900.woff2 b/assets/webfonts/fa-solid-900.woff2 new file mode 100644 index 0000000..2217164 Binary files /dev/null and b/assets/webfonts/fa-solid-900.woff2 differ diff --git a/assetsIndex/css/fontawesome-all.min.css b/assetsIndex/css/fontawesome-all.min.css new file mode 100644 index 0000000..03c42e3 --- /dev/null +++ b/assetsIndex/css/fontawesome-all.min.css @@ -0,0 +1,101 @@ +/*! + * Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +.fa,.fab,.fad,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-acquisitions-incorporated:before{content:"\f6af"}.fa-ad:before{content:"\f641"}.fa-address-book:before{content:"\f2b9"}.fa-address-card:before{content:"\f2bb"}.fa-adjust:before{content:"\f042"}.fa-adn:before{content:"\f170"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-air-freshener:before{content:"\f5d0"}.fa-airbnb:before{content:"\f834"}.fa-algolia:before{content:"\f36c"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-alipay:before{content:"\f642"}.fa-allergies:before{content:"\f461"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-ambulance:before{content:"\f0f9"}.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-amilia:before{content:"\f36d"}.fa-anchor:before{content:"\f13d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angry:before{content:"\f556"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-ankh:before{content:"\f644"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-alt:before{content:"\f5d1"}.fa-apple-pay:before{content:"\f415"}.fa-archive:before{content:"\f187"}.fa-archway:before{content:"\f557"}.fa-arrow-alt-circle-down:before{content:"\f358"}.fa-arrow-alt-circle-left:before{content:"\f359"}.fa-arrow-alt-circle-right:before{content:"\f35a"}.fa-arrow-alt-circle-up:before{content:"\f35b"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrows-alt:before{content:"\f0b2"}.fa-arrows-alt-h:before{content:"\f337"}.fa-arrows-alt-v:before{content:"\f338"}.fa-artstation:before{content:"\f77a"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asterisk:before{content:"\f069"}.fa-asymmetrik:before{content:"\f372"}.fa-at:before{content:"\f1fa"}.fa-atlas:before{content:"\f558"}.fa-atlassian:before{content:"\f77b"}.fa-atom:before{content:"\f5d2"}.fa-audible:before{content:"\f373"}.fa-audio-description:before{content:"\f29e"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-award:before{content:"\f559"}.fa-aws:before{content:"\f375"}.fa-baby:before{content:"\f77c"}.fa-baby-carriage:before{content:"\f77d"}.fa-backspace:before{content:"\f55a"}.fa-backward:before{content:"\f04a"}.fa-bacon:before{content:"\f7e5"}.fa-bacteria:before{content:"\e059"}.fa-bacterium:before{content:"\e05a"}.fa-bahai:before{content:"\f666"}.fa-balance-scale:before{content:"\f24e"}.fa-balance-scale-left:before{content:"\f515"}.fa-balance-scale-right:before{content:"\f516"}.fa-ban:before{content:"\f05e"}.fa-band-aid:before{content:"\f462"}.fa-bandcamp:before{content:"\f2d5"}.fa-barcode:before{content:"\f02a"}.fa-bars:before{content:"\f0c9"}.fa-baseball-ball:before{content:"\f433"}.fa-basketball-ball:before{content:"\f434"}.fa-bath:before{content:"\f2cd"}.fa-battery-empty:before{content:"\f244"}.fa-battery-full:before{content:"\f240"}.fa-battery-half:before{content:"\f242"}.fa-battery-quarter:before{content:"\f243"}.fa-battery-three-quarters:before{content:"\f241"}.fa-battle-net:before{content:"\f835"}.fa-bed:before{content:"\f236"}.fa-beer:before{content:"\f0fc"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bell:before{content:"\f0f3"}.fa-bell-slash:before{content:"\f1f6"}.fa-bezier-curve:before{content:"\f55b"}.fa-bible:before{content:"\f647"}.fa-bicycle:before{content:"\f206"}.fa-biking:before{content:"\f84a"}.fa-bimobject:before{content:"\f378"}.fa-binoculars:before{content:"\f1e5"}.fa-biohazard:before{content:"\f780"}.fa-birthday-cake:before{content:"\f1fd"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blender:before{content:"\f517"}.fa-blender-phone:before{content:"\f6b6"}.fa-blind:before{content:"\f29d"}.fa-blog:before{content:"\f781"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bold:before{content:"\f032"}.fa-bolt:before{content:"\f0e7"}.fa-bomb:before{content:"\f1e2"}.fa-bone:before{content:"\f5d7"}.fa-bong:before{content:"\f55c"}.fa-book:before{content:"\f02d"}.fa-book-dead:before{content:"\f6b7"}.fa-book-medical:before{content:"\f7e6"}.fa-book-open:before{content:"\f518"}.fa-book-reader:before{content:"\f5da"}.fa-bookmark:before{content:"\f02e"}.fa-bootstrap:before{content:"\f836"}.fa-border-all:before{content:"\f84c"}.fa-border-none:before{content:"\f850"}.fa-border-style:before{content:"\f853"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-box-open:before{content:"\f49e"}.fa-box-tissue:before{content:"\e05b"}.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-brain:before{content:"\f5dc"}.fa-bread-slice:before{content:"\f7ec"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broadcast-tower:before{content:"\f519"}.fa-broom:before{content:"\f51a"}.fa-brush:before{content:"\f55d"}.fa-btc:before{content:"\f15a"}.fa-buffer:before{content:"\f837"}.fa-bug:before{content:"\f188"}.fa-building:before{content:"\f1ad"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burn:before{content:"\f46a"}.fa-buromobelexperte:before{content:"\f37f"}.fa-bus:before{content:"\f207"}.fa-bus-alt:before{content:"\f55e"}.fa-business-time:before{content:"\f64a"}.fa-buy-n-large:before{content:"\f8a6"}.fa-buysellads:before{content:"\f20d"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-alt:before{content:"\f073"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-day:before{content:"\f783"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-times:before{content:"\f273"}.fa-calendar-week:before{content:"\f784"}.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-campground:before{content:"\f6bb"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-candy-cane:before{content:"\f786"}.fa-cannabis:before{content:"\f55f"}.fa-capsules:before{content:"\f46b"}.fa-car:before{content:"\f1b9"}.fa-car-alt:before{content:"\f5de"}.fa-car-battery:before{content:"\f5df"}.fa-car-crash:before{content:"\f5e1"}.fa-car-side:before{content:"\f5e4"}.fa-caravan:before{content:"\f8ff"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-square-down:before{content:"\f150"}.fa-caret-square-left:before{content:"\f191"}.fa-caret-square-right:before{content:"\f152"}.fa-caret-square-up:before{content:"\f151"}.fa-caret-up:before{content:"\f0d8"}.fa-carrot:before{content:"\f787"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-plus:before{content:"\f217"}.fa-cash-register:before{content:"\f788"}.fa-cat:before{content:"\f6be"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-centos:before{content:"\f789"}.fa-certificate:before{content:"\f0a3"}.fa-chair:before{content:"\f6c0"}.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before{content:"\f51c"}.fa-charging-station:before{content:"\f5e7"}.fa-chart-area:before{content:"\f1fe"}.fa-chart-bar:before{content:"\f080"}.fa-chart-line:before{content:"\f201"}.fa-chart-pie:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-circle:before{content:"\f058"}.fa-check-double:before{content:"\f560"}.fa-check-square:before{content:"\f14a"}.fa-cheese:before{content:"\f7ef"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-chrome:before{content:"\f268"}.fa-chromecast:before{content:"\f838"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-circle-notch:before{content:"\f1ce"}.fa-city:before{content:"\f64f"}.fa-clinic-medical:before{content:"\f7f2"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clock:before{content:"\f017"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-download-alt:before{content:"\f381"}.fa-cloud-meatball:before{content:"\f73b"}.fa-cloud-moon:before{content:"\f6c3"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-cloud-rain:before{content:"\f73d"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-cloud-sun:before{content:"\f6c4"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-cloud-upload-alt:before{content:"\f382"}.fa-cloudflare:before{content:"\e07d"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cocktail:before{content:"\f561"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-coffee:before{content:"\f0f4"}.fa-cog:before{content:"\f013"}.fa-cogs:before{content:"\f085"}.fa-coins:before{content:"\f51e"}.fa-columns:before{content:"\f0db"}.fa-comment:before{content:"\f075"}.fa-comment-alt:before{content:"\f27a"}.fa-comment-dollar:before{content:"\f651"}.fa-comment-dots:before{content:"\f4ad"}.fa-comment-medical:before{content:"\f7f5"}.fa-comment-slash:before{content:"\f4b3"}.fa-comments:before{content:"\f086"}.fa-comments-dollar:before{content:"\f653"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compress:before{content:"\f066"}.fa-compress-alt:before{content:"\f422"}.fa-compress-arrows-alt:before{content:"\f78c"}.fa-concierge-bell:before{content:"\f562"}.fa-confluence:before{content:"\f78d"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cookie:before{content:"\f563"}.fa-cookie-bite:before{content:"\f564"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-cotton-bureau:before{content:"\f89e"}.fa-couch:before{content:"\f4b8"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-credit-card:before{content:"\f09d"}.fa-critical-role:before{content:"\f6c9"}.fa-crop:before{content:"\f125"}.fa-crop-alt:before{content:"\f565"}.fa-cross:before{content:"\f654"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-crutch:before{content:"\f7f7"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cut:before{content:"\f0c4"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-dailymotion:before{content:"\e052"}.fa-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.fa-deezer:before{content:"\e077"}.fa-delicious:before{content:"\f1a5"}.fa-democrat:before{content:"\f747"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-desktop:before{content:"\f108"}.fa-dev:before{content:"\f6cc"}.fa-deviantart:before{content:"\f1bd"}.fa-dharmachakra:before{content:"\f655"}.fa-dhl:before{content:"\f790"}.fa-diagnoses:before{content:"\f470"}.fa-diaspora:before{content:"\f791"}.fa-dice:before{content:"\f522"}.fa-dice-d20:before{content:"\f6cf"}.fa-dice-d6:before{content:"\f6d1"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-digital-tachograph:before{content:"\f566"}.fa-directions:before{content:"\f5eb"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-disease:before{content:"\f7fa"}.fa-divide:before{content:"\f529"}.fa-dizzy:before{content:"\f567"}.fa-dna:before{content:"\f471"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-dog:before{content:"\f6d3"}.fa-dollar-sign:before{content:"\f155"}.fa-dolly:before{content:"\f472"}.fa-dolly-flatbed:before{content:"\f474"}.fa-donate:before{content:"\f4b9"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dot-circle:before{content:"\f192"}.fa-dove:before{content:"\f4ba"}.fa-download:before{content:"\f019"}.fa-draft2digital:before{content:"\f396"}.fa-drafting-compass:before{content:"\f568"}.fa-dragon:before{content:"\f6d5"}.fa-draw-polygon:before{content:"\f5ee"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drum:before{content:"\f569"}.fa-drum-steelpan:before{content:"\f56a"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-drupal:before{content:"\f1a9"}.fa-dumbbell:before{content:"\f44b"}.fa-dumpster:before{content:"\f793"}.fa-dumpster-fire:before{content:"\f794"}.fa-dungeon:before{content:"\f6d9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edge-legacy:before{content:"\e078"}.fa-edit:before{content:"\f044"}.fa-egg:before{content:"\f7fb"}.fa-eject:before{content:"\f052"}.fa-elementor:before{content:"\f430"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-text:before{content:"\f658"}.fa-envelope-square:before{content:"\f199"}.fa-envira:before{content:"\f299"}.fa-equals:before{content:"\f52c"}.fa-eraser:before{content:"\f12d"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-ethernet:before{content:"\f796"}.fa-etsy:before{content:"\f2d7"}.fa-euro-sign:before{content:"\f153"}.fa-evernote:before{content:"\f839"}.fa-exchange-alt:before{content:"\f362"}.fa-exclamation:before{content:"\f12a"}.fa-exclamation-circle:before{content:"\f06a"}.fa-exclamation-triangle:before{content:"\f071"}.fa-expand:before{content:"\f065"}.fa-expand-alt:before{content:"\f424"}.fa-expand-arrows-alt:before{content:"\f31e"}.fa-expeditedssl:before{content:"\f23e"}.fa-external-link-alt:before{content:"\f35d"}.fa-external-link-square-alt:before{content:"\f360"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper:before{content:"\f1fb"}.fa-eye-slash:before{content:"\f070"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fan:before{content:"\f863"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-fast-backward:before{content:"\f049"}.fa-fast-forward:before{content:"\f050"}.fa-faucet:before{content:"\e005"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-feather-alt:before{content:"\f56b"}.fa-fedex:before{content:"\f797"}.fa-fedora:before{content:"\f798"}.fa-female:before{content:"\f182"}.fa-fighter-jet:before{content:"\f0fb"}.fa-figma:before{content:"\f799"}.fa-file:before{content:"\f15b"}.fa-file-alt:before{content:"\f15c"}.fa-file-archive:before{content:"\f1c6"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-contract:before{content:"\f56c"}.fa-file-csv:before{content:"\f6dd"}.fa-file-download:before{content:"\f56d"}.fa-file-excel:before{content:"\f1c3"}.fa-file-export:before{content:"\f56e"}.fa-file-image:before{content:"\f1c5"}.fa-file-import:before{content:"\f56f"}.fa-file-invoice:before{content:"\f570"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-file-medical:before{content:"\f477"}.fa-file-medical-alt:before{content:"\f478"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-prescription:before{content:"\f572"}.fa-file-signature:before{content:"\f573"}.fa-file-upload:before{content:"\f574"}.fa-file-video:before{content:"\f1c8"}.fa-file-word:before{content:"\f1c2"}.fa-fill:before{content:"\f575"}.fa-fill-drip:before{content:"\f576"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-fingerprint:before{content:"\f577"}.fa-fire:before{content:"\f06d"}.fa-fire-alt:before{content:"\f7e4"}.fa-fire-extinguisher:before{content:"\f134"}.fa-firefox:before{content:"\f269"}.fa-firefox-browser:before{content:"\e007"}.fa-first-aid:before{content:"\f479"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-fish:before{content:"\f578"}.fa-fist-raised:before{content:"\f6de"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flag-usa:before{content:"\f74d"}.fa-flask:before{content:"\f0c3"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-flushed:before{content:"\f579"}.fa-fly:before{content:"\f417"}.fa-folder:before{content:"\f07b"}.fa-folder-minus:before{content:"\f65d"}.fa-folder-open:before{content:"\f07c"}.fa-folder-plus:before{content:"\f65e"}.fa-font:before{content:"\f031"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-font-awesome-flag:before{content:"\f425"}.fa-font-awesome-logo-full:before{content:"\f4e6"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-football-ball:before{content:"\f44e"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-forward:before{content:"\f04e"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-frog:before{content:"\f52e"}.fa-frown:before{content:"\f119"}.fa-frown-open:before{content:"\f57a"}.fa-fulcrum:before{content:"\f50b"}.fa-funnel-dollar:before{content:"\f662"}.fa-futbol:before{content:"\f1e3"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-gavel:before{content:"\f0e3"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-ghost:before{content:"\f6e2"}.fa-gift:before{content:"\f06b"}.fa-gifts:before{content:"\f79c"}.fa-git:before{content:"\f1d3"}.fa-git-alt:before{content:"\f841"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glass-cheers:before{content:"\f79f"}.fa-glass-martini:before{content:"\f000"}.fa-glass-martini-alt:before{content:"\f57b"}.fa-glass-whiskey:before{content:"\f7a0"}.fa-glasses:before{content:"\f530"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-globe:before{content:"\f0ac"}.fa-globe-africa:before{content:"\f57c"}.fa-globe-americas:before{content:"\f57d"}.fa-globe-asia:before{content:"\f57e"}.fa-globe-europe:before{content:"\f7a2"}.fa-gofore:before{content:"\f3a7"}.fa-golf-ball:before{content:"\f450"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-pay:before{content:"\e079"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-gopuram:before{content:"\f664"}.fa-graduation-cap:before{content:"\f19d"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-greater-than:before{content:"\f531"}.fa-greater-than-equal:before{content:"\f532"}.fa-grimace:before{content:"\f57f"}.fa-grin:before{content:"\f580"}.fa-grin-alt:before{content:"\f581"}.fa-grin-beam:before{content:"\f582"}.fa-grin-beam-sweat:before{content:"\f583"}.fa-grin-hearts:before{content:"\f584"}.fa-grin-squint:before{content:"\f585"}.fa-grin-squint-tears:before{content:"\f586"}.fa-grin-stars:before{content:"\f587"}.fa-grin-tears:before{content:"\f588"}.fa-grin-tongue:before{content:"\f589"}.fa-grin-tongue-squint:before{content:"\f58a"}.fa-grin-tongue-wink:before{content:"\f58b"}.fa-grin-wink:before{content:"\f58c"}.fa-grip-horizontal:before{content:"\f58d"}.fa-grip-lines:before{content:"\f7a4"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-grip-vertical:before{content:"\f58e"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-guilded:before{content:"\e07e"}.fa-guitar:before{content:"\f7a6"}.fa-gulp:before{content:"\f3ae"}.fa-h-square:before{content:"\f0fd"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hackerrank:before{content:"\f5f7"}.fa-hamburger:before{content:"\f805"}.fa-hammer:before{content:"\f6e3"}.fa-hamsa:before{content:"\f665"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-medical:before{content:"\e05c"}.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-holding-water:before{content:"\f4c1"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-middle-finger:before{content:"\f806"}.fa-hand-paper:before{content:"\f256"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-rock:before{content:"\f255"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-sparkles:before{content:"\e05d"}.fa-hand-spock:before{content:"\f259"}.fa-hands:before{content:"\f4c2"}.fa-hands-helping:before{content:"\f4c4"}.fa-hands-wash:before{content:"\e05e"}.fa-handshake:before{content:"\f2b5"}.fa-handshake-alt-slash:before{content:"\e05f"}.fa-handshake-slash:before{content:"\e060"}.fa-hanukiah:before{content:"\f6e6"}.fa-hard-hat:before{content:"\f807"}.fa-hashtag:before{content:"\f292"}.fa-hat-cowboy:before{content:"\f8c0"}.fa-hat-cowboy-side:before{content:"\f8c1"}.fa-hat-wizard:before{content:"\f6e8"}.fa-hdd:before{content:"\f0a0"}.fa-head-side-cough:before{content:"\e061"}.fa-head-side-cough-slash:before{content:"\e062"}.fa-head-side-mask:before{content:"\e063"}.fa-head-side-virus:before{content:"\e064"}.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-headphones-alt:before{content:"\f58f"}.fa-headset:before{content:"\f590"}.fa-heart:before{content:"\f004"}.fa-heart-broken:before{content:"\f7a9"}.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-highlighter:before{content:"\f591"}.fa-hiking:before{content:"\f6ec"}.fa-hippo:before{content:"\f6ed"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-history:before{content:"\f1da"}.fa-hive:before{content:"\e07f"}.fa-hockey-puck:before{content:"\f453"}.fa-holly-berry:before{content:"\f7aa"}.fa-home:before{content:"\f015"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-horse:before{content:"\f6f0"}.fa-horse-head:before{content:"\f7ab"}.fa-hospital:before{content:"\f0f8"}.fa-hospital-alt:before{content:"\f47d"}.fa-hospital-symbol:before{content:"\f47e"}.fa-hospital-user:before{content:"\f80d"}.fa-hot-tub:before{content:"\f593"}.fa-hotdog:before{content:"\f80f"}.fa-hotel:before{content:"\f594"}.fa-hotjar:before{content:"\f3b1"}.fa-hourglass:before{content:"\f254"}.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-start:before{content:"\f251"}.fa-house-damage:before{content:"\f6f1"}.fa-house-user:before{content:"\e065"}.fa-houzz:before{content:"\f27c"}.fa-hryvnia:before{content:"\f6f2"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-i-cursor:before{content:"\f246"}.fa-ice-cream:before{content:"\f810"}.fa-icicles:before{content:"\f7ad"}.fa-icons:before{content:"\f86d"}.fa-id-badge:before{content:"\f2c1"}.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before{content:"\f47f"}.fa-ideal:before{content:"\e013"}.fa-igloo:before{content:"\f7ae"}.fa-image:before{content:"\f03e"}.fa-images:before{content:"\f302"}.fa-imdb:before{content:"\f2d8"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-info-circle:before{content:"\f05a"}.fa-innosoft:before{content:"\e080"}.fa-instagram:before{content:"\f16d"}.fa-instagram-square:before{content:"\e055"}.fa-instalod:before{content:"\e081"}.fa-intercom:before{content:"\f7af"}.fa-internet-explorer:before{content:"\f26b"}.fa-invision:before{content:"\f7b0"}.fa-ioxhost:before{content:"\f208"}.fa-italic:before{content:"\f033"}.fa-itch-io:before{content:"\f83a"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi:before{content:"\f669"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-jira:before{content:"\f7b1"}.fa-joget:before{content:"\f3b7"}.fa-joint:before{content:"\f595"}.fa-joomla:before{content:"\f1aa"}.fa-journal-whills:before{content:"\f66a"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaaba:before{content:"\f66b"}.fa-kaggle:before{content:"\f5fa"}.fa-key:before{content:"\f084"}.fa-keybase:before{content:"\f4f5"}.fa-keyboard:before{content:"\f11c"}.fa-keycdn:before{content:"\f3ba"}.fa-khanda:before{content:"\f66d"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-kiss:before{content:"\f596"}.fa-kiss-beam:before{content:"\f597"}.fa-kiss-wink-heart:before{content:"\f598"}.fa-kiwi-bird:before{content:"\f535"}.fa-korvue:before{content:"\f42f"}.fa-landmark:before{content:"\f66f"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laptop-code:before{content:"\f5fc"}.fa-laptop-house:before{content:"\e066"}.fa-laptop-medical:before{content:"\f812"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-laugh:before{content:"\f599"}.fa-laugh-beam:before{content:"\f59a"}.fa-laugh-squint:before{content:"\f59b"}.fa-laugh-wink:before{content:"\f59c"}.fa-layer-group:before{content:"\f5fd"}.fa-leaf:before{content:"\f06c"}.fa-leanpub:before{content:"\f212"}.fa-lemon:before{content:"\f094"}.fa-less:before{content:"\f41d"}.fa-less-than:before{content:"\f536"}.fa-less-than-equal:before{content:"\f537"}.fa-level-down-alt:before{content:"\f3be"}.fa-level-up-alt:before{content:"\f3bf"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-line:before{content:"\f3c0"}.fa-link:before{content:"\f0c1"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lira-sign:before{content:"\f195"}.fa-list:before{content:"\f03a"}.fa-list-alt:before{content:"\f022"}.fa-list-ol:before{content:"\f0cb"}.fa-list-ul:before{content:"\f0ca"}.fa-location-arrow:before{content:"\f124"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-long-arrow-alt-down:before{content:"\f309"}.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-long-arrow-alt-right:before{content:"\f30b"}.fa-long-arrow-alt-up:before{content:"\f30c"}.fa-low-vision:before{content:"\f2a8"}.fa-luggage-cart:before{content:"\f59d"}.fa-lungs:before{content:"\f604"}.fa-lungs-virus:before{content:"\e067"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-magic:before{content:"\f0d0"}.fa-magnet:before{content:"\f076"}.fa-mail-bulk:before{content:"\f674"}.fa-mailchimp:before{content:"\f59e"}.fa-male:before{content:"\f183"}.fa-mandalorian:before{content:"\f50f"}.fa-map:before{content:"\f279"}.fa-map-marked:before{content:"\f59f"}.fa-map-marked-alt:before{content:"\f5a0"}.fa-map-marker:before{content:"\f041"}.fa-map-marker-alt:before{content:"\f3c5"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-markdown:before{content:"\f60f"}.fa-marker:before{content:"\f5a1"}.fa-mars:before{content:"\f222"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mask:before{content:"\f6fa"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-mdb:before{content:"\f8ca"}.fa-medal:before{content:"\f5a2"}.fa-medapps:before{content:"\f3c6"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f3c7"}.fa-medkit:before{content:"\f0fa"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-meh:before{content:"\f11a"}.fa-meh-blank:before{content:"\f5a4"}.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-memory:before{content:"\f538"}.fa-mendeley:before{content:"\f7b3"}.fa-menorah:before{content:"\f676"}.fa-mercury:before{content:"\f223"}.fa-meteor:before{content:"\f753"}.fa-microblog:before{content:"\e01a"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before{content:"\f3c9"}.fa-microphone-alt-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microscope:before{content:"\f610"}.fa-microsoft:before{content:"\f3ca"}.fa-minus:before{content:"\f068"}.fa-minus-circle:before{content:"\f056"}.fa-minus-square:before{content:"\f146"}.fa-mitten:before{content:"\f7b5"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mixer:before{content:"\e056"}.fa-mizuni:before{content:"\f3cc"}.fa-mobile:before{content:"\f10b"}.fa-mobile-alt:before{content:"\f3cd"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before{content:"\f53d"}.fa-monument:before{content:"\f5a6"}.fa-moon:before{content:"\f186"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-mosque:before{content:"\f678"}.fa-motorcycle:before{content:"\f21c"}.fa-mountain:before{content:"\f6fc"}.fa-mouse:before{content:"\f8cc"}.fa-mouse-pointer:before{content:"\f245"}.fa-mug-hot:before{content:"\f7b6"}.fa-music:before{content:"\f001"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-network-wired:before{content:"\f6ff"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-nimblr:before{content:"\f5a8"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-not-equal:before{content:"\f53e"}.fa-notes-medical:before{content:"\f481"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-octopus-deploy:before{content:"\e082"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-oil-can:before{content:"\f613"}.fa-old-republic:before{content:"\f510"}.fa-om:before{content:"\f679"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-orcid:before{content:"\f8d2"}.fa-osi:before{content:"\f41a"}.fa-otter:before{content:"\f700"}.fa-outdent:before{content:"\f03b"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-pager:before{content:"\f815"}.fa-paint-brush:before{content:"\f1fc"}.fa-paint-roller:before{content:"\f5aa"}.fa-palette:before{content:"\f53f"}.fa-palfed:before{content:"\f3d8"}.fa-pallet:before{content:"\f482"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-parking:before{content:"\f540"}.fa-passport:before{content:"\f5ab"}.fa-pastafarianism:before{content:"\f67b"}.fa-paste:before{content:"\f0ea"}.fa-patreon:before{content:"\f3d9"}.fa-pause:before{content:"\f04c"}.fa-pause-circle:before{content:"\f28b"}.fa-paw:before{content:"\f1b0"}.fa-paypal:before{content:"\f1ed"}.fa-peace:before{content:"\f67c"}.fa-pen:before{content:"\f304"}.fa-pen-alt:before{content:"\f305"}.fa-pen-fancy:before{content:"\f5ac"}.fa-pen-nib:before{content:"\f5ad"}.fa-pen-square:before{content:"\f14b"}.fa-pencil-alt:before{content:"\f303"}.fa-pencil-ruler:before{content:"\f5ae"}.fa-penny-arcade:before{content:"\f704"}.fa-people-arrows:before{content:"\e068"}.fa-people-carry:before{content:"\f4ce"}.fa-pepper-hot:before{content:"\f816"}.fa-perbyte:before{content:"\e083"}.fa-percent:before{content:"\f295"}.fa-percentage:before{content:"\f541"}.fa-periscope:before{content:"\f3da"}.fa-person-booth:before{content:"\f756"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-phone:before{content:"\f095"}.fa-phone-alt:before{content:"\f879"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-square:before{content:"\f098"}.fa-phone-square-alt:before{content:"\f87b"}.fa-phone-volume:before{content:"\f2a0"}.fa-photo-video:before{content:"\f87c"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-square:before{content:"\e01e"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-pizza-slice:before{content:"\f818"}.fa-place-of-worship:before{content:"\f67f"}.fa-plane:before{content:"\f072"}.fa-plane-arrival:before{content:"\f5af"}.fa-plane-departure:before{content:"\f5b0"}.fa-plane-slash:before{content:"\e069"}.fa-play:before{content:"\f04b"}.fa-play-circle:before{content:"\f144"}.fa-playstation:before{content:"\f3df"}.fa-plug:before{content:"\f1e6"}.fa-plus:before{content:"\f067"}.fa-plus-circle:before{content:"\f055"}.fa-plus-square:before{content:"\f0fe"}.fa-podcast:before{content:"\f2ce"}.fa-poll:before{content:"\f681"}.fa-poll-h:before{content:"\f682"}.fa-poo:before{content:"\f2fe"}.fa-poo-storm:before{content:"\f75a"}.fa-poop:before{content:"\f619"}.fa-portrait:before{content:"\f3e0"}.fa-pound-sign:before{content:"\f154"}.fa-power-off:before{content:"\f011"}.fa-pray:before{content:"\f683"}.fa-praying-hands:before{content:"\f684"}.fa-prescription:before{content:"\f5b1"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-procedures:before{content:"\f487"}.fa-product-hunt:before{content:"\f288"}.fa-project-diagram:before{content:"\f542"}.fa-pump-medical:before{content:"\e06a"}.fa-pump-soap:before{content:"\e06b"}.fa-pushed:before{content:"\f3e1"}.fa-puzzle-piece:before{content:"\f12e"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\f128"}.fa-question-circle:before{content:"\f059"}.fa-quidditch:before{content:"\f458"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-quran:before{content:"\f687"}.fa-r-project:before{content:"\f4f7"}.fa-radiation:before{content:"\f7b9"}.fa-radiation-alt:before{content:"\f7ba"}.fa-rainbow:before{content:"\f75b"}.fa-random:before{content:"\f074"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-reacteurope:before{content:"\f75d"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-receipt:before{content:"\f543"}.fa-record-vinyl:before{content:"\f8d9"}.fa-recycle:before{content:"\f1b8"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redhat:before{content:"\f7bc"}.fa-redo:before{content:"\f01e"}.fa-redo-alt:before{content:"\f2f9"}.fa-registered:before{content:"\f25d"}.fa-remove-format:before{content:"\f87d"}.fa-renren:before{content:"\f18b"}.fa-reply:before{content:"\f3e5"}.fa-reply-all:before{content:"\f122"}.fa-replyd:before{content:"\f3e6"}.fa-republican:before{content:"\f75e"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-restroom:before{content:"\f7bd"}.fa-retweet:before{content:"\f079"}.fa-rev:before{content:"\f5b2"}.fa-ribbon:before{content:"\f4d6"}.fa-ring:before{content:"\f70b"}.fa-road:before{content:"\f018"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-route:before{content:"\f4d7"}.fa-rss:before{content:"\f09e"}.fa-rss-square:before{content:"\f143"}.fa-ruble-sign:before{content:"\f158"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-running:before{content:"\f70c"}.fa-rupee-sign:before{content:"\f156"}.fa-rust:before{content:"\e07a"}.fa-sad-cry:before{content:"\f5b3"}.fa-sad-tear:before{content:"\f5b4"}.fa-safari:before{content:"\f267"}.fa-salesforce:before{content:"\f83b"}.fa-sass:before{content:"\f41e"}.fa-satellite:before{content:"\f7bf"}.fa-satellite-dish:before{content:"\f7c0"}.fa-save:before{content:"\f0c7"}.fa-schlix:before{content:"\f3ea"}.fa-school:before{content:"\f549"}.fa-screwdriver:before{content:"\f54a"}.fa-scribd:before{content:"\f28a"}.fa-scroll:before{content:"\f70e"}.fa-sd-card:before{content:"\f7c2"}.fa-search:before{content:"\f002"}.fa-search-dollar:before{content:"\f688"}.fa-search-location:before{content:"\f689"}.fa-search-minus:before{content:"\f010"}.fa-search-plus:before{content:"\f00e"}.fa-searchengin:before{content:"\f3eb"}.fa-seedling:before{content:"\f4d8"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-server:before{content:"\f233"}.fa-servicestack:before{content:"\f3ec"}.fa-shapes:before{content:"\f61f"}.fa-share:before{content:"\f064"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-share-square:before{content:"\f14d"}.fa-shekel-sign:before{content:"\f20b"}.fa-shield-alt:before{content:"\f3ed"}.fa-shield-virus:before{content:"\e06c"}.fa-ship:before{content:"\f21a"}.fa-shipping-fast:before{content:"\f48b"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shoe-prints:before{content:"\f54b"}.fa-shopify:before{content:"\e057"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-shopping-cart:before{content:"\f07a"}.fa-shopware:before{content:"\f5b5"}.fa-shower:before{content:"\f2cc"}.fa-shuttle-van:before{content:"\f5b6"}.fa-sign:before{content:"\f4d9"}.fa-sign-in-alt:before{content:"\f2f6"}.fa-sign-language:before{content:"\f2a7"}.fa-sign-out-alt:before{content:"\f2f5"}.fa-signal:before{content:"\f012"}.fa-signature:before{content:"\f5b7"}.fa-sim-card:before{content:"\f7c4"}.fa-simplybuilt:before{content:"\f215"}.fa-sink:before{content:"\e06d"}.fa-sistrix:before{content:"\f3ee"}.fa-sitemap:before{content:"\f0e8"}.fa-sith:before{content:"\f512"}.fa-skating:before{content:"\f7c5"}.fa-sketch:before{content:"\f7c6"}.fa-skiing:before{content:"\f7c9"}.fa-skiing-nordic:before{content:"\f7ca"}.fa-skull:before{content:"\f54c"}.fa-skull-crossbones:before{content:"\f714"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f3ef"}.fa-slash:before{content:"\f715"}.fa-sleigh:before{content:"\f7cc"}.fa-sliders-h:before{content:"\f1de"}.fa-slideshare:before{content:"\f1e7"}.fa-smile:before{content:"\f118"}.fa-smile-beam:before{content:"\f5b8"}.fa-smile-wink:before{content:"\f4da"}.fa-smog:before{content:"\f75f"}.fa-smoking:before{content:"\f48d"}.fa-smoking-ban:before{content:"\f54d"}.fa-sms:before{content:"\f7cd"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-snowboarding:before{content:"\f7ce"}.fa-snowflake:before{content:"\f2dc"}.fa-snowman:before{content:"\f7d0"}.fa-snowplow:before{content:"\f7d2"}.fa-soap:before{content:"\e06e"}.fa-socks:before{content:"\f696"}.fa-solar-panel:before{content:"\f5ba"}.fa-sort:before{content:"\f0dc"}.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-down-alt:before{content:"\f881"}.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-alpha-up-alt:before{content:"\f882"}.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-down-alt:before{content:"\f884"}.fa-sort-amount-up:before{content:"\f161"}.fa-sort-amount-up-alt:before{content:"\f885"}.fa-sort-down:before{content:"\f0dd"}.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-sort-numeric-up:before{content:"\f163"}.fa-sort-numeric-up-alt:before{content:"\f887"}.fa-sort-up:before{content:"\f0de"}.fa-soundcloud:before{content:"\f1be"}.fa-sourcetree:before{content:"\f7d3"}.fa-spa:before{content:"\f5bb"}.fa-space-shuttle:before{content:"\f197"}.fa-speakap:before{content:"\f3f3"}.fa-speaker-deck:before{content:"\f83c"}.fa-spell-check:before{content:"\f891"}.fa-spider:before{content:"\f717"}.fa-spinner:before{content:"\f110"}.fa-splotch:before{content:"\f5bc"}.fa-spotify:before{content:"\f1bc"}.fa-spray-can:before{content:"\f5bd"}.fa-square:before{content:"\f0c8"}.fa-square-full:before{content:"\f45c"}.fa-square-root-alt:before{content:"\f698"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stackpath:before{content:"\f842"}.fa-stamp:before{content:"\f5bf"}.fa-star:before{content:"\f005"}.fa-star-and-crescent:before{content:"\f699"}.fa-star-half:before{content:"\f089"}.fa-star-half-alt:before{content:"\f5c0"}.fa-star-of-david:before{content:"\f69a"}.fa-star-of-life:before{content:"\f621"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-step-backward:before{content:"\f048"}.fa-step-forward:before{content:"\f051"}.fa-stethoscope:before{content:"\f0f1"}.fa-sticker-mule:before{content:"\f3f7"}.fa-sticky-note:before{content:"\f249"}.fa-stop:before{content:"\f04d"}.fa-stop-circle:before{content:"\f28d"}.fa-stopwatch:before{content:"\f2f2"}.fa-stopwatch-20:before{content:"\e06f"}.fa-store:before{content:"\f54e"}.fa-store-alt:before{content:"\f54f"}.fa-store-alt-slash:before{content:"\e070"}.fa-store-slash:before{content:"\e071"}.fa-strava:before{content:"\f428"}.fa-stream:before{content:"\f550"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-stroopwafel:before{content:"\f551"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-subscript:before{content:"\f12c"}.fa-subway:before{content:"\f239"}.fa-suitcase:before{content:"\f0f2"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-sun:before{content:"\f185"}.fa-superpowers:before{content:"\f2dd"}.fa-superscript:before{content:"\f12b"}.fa-supple:before{content:"\f3f9"}.fa-surprise:before{content:"\f5c2"}.fa-suse:before{content:"\f7d6"}.fa-swatchbook:before{content:"\f5c3"}.fa-swift:before{content:"\f8e1"}.fa-swimmer:before{content:"\f5c4"}.fa-swimming-pool:before{content:"\f5c5"}.fa-symfony:before{content:"\f83d"}.fa-synagogue:before{content:"\f69b"}.fa-sync:before{content:"\f021"}.fa-sync-alt:before{content:"\f2f1"}.fa-syringe:before{content:"\f48e"}.fa-table:before{content:"\f0ce"}.fa-table-tennis:before{content:"\f45d"}.fa-tablet:before{content:"\f10a"}.fa-tablet-alt:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-tachometer-alt:before{content:"\f3fd"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-tasks:before{content:"\f0ae"}.fa-taxi:before{content:"\f1ba"}.fa-teamspeak:before{content:"\f4f9"}.fa-teeth:before{content:"\f62e"}.fa-teeth-open:before{content:"\f62f"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f3fe"}.fa-temperature-high:before{content:"\f769"}.fa-temperature-low:before{content:"\f76b"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-tenge:before{content:"\f7d7"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-th:before{content:"\f00a"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-the-red-yeti:before{content:"\f69d"}.fa-theater-masks:before{content:"\f630"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-thermometer:before{content:"\f491"}.fa-thermometer-empty:before{content:"\f2cb"}.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-think-peaks:before{content:"\f731"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbtack:before{content:"\f08d"}.fa-ticket-alt:before{content:"\f3ff"}.fa-tiktok:before{content:"\e07b"}.fa-times:before{content:"\f00d"}.fa-times-circle:before{content:"\f057"}.fa-tint:before{content:"\f043"}.fa-tint-slash:before{content:"\f5c7"}.fa-tired:before{content:"\f5c8"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toilet:before{content:"\f7d8"}.fa-toilet-paper:before{content:"\f71e"}.fa-toilet-paper-slash:before{content:"\e072"}.fa-toolbox:before{content:"\f552"}.fa-tools:before{content:"\f7d9"}.fa-tooth:before{content:"\f5c9"}.fa-torah:before{content:"\f6a0"}.fa-torii-gate:before{content:"\f6a1"}.fa-tractor:before{content:"\f722"}.fa-trade-federation:before{content:"\f513"}.fa-trademark:before{content:"\f25c"}.fa-traffic-light:before{content:"\f637"}.fa-trailer:before{content:"\e041"}.fa-train:before{content:"\f238"}.fa-tram:before{content:"\f7da"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-alt:before{content:"\f2ed"}.fa-trash-restore:before{content:"\f829"}.fa-trash-restore-alt:before{content:"\f82a"}.fa-tree:before{content:"\f1bb"}.fa-trello:before{content:"\f181"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-truck-loading:before{content:"\f4de"}.fa-truck-monster:before{content:"\f63b"}.fa-truck-moving:before{content:"\f4df"}.fa-truck-pickup:before{content:"\f63c"}.fa-tshirt:before{content:"\f553"}.fa-tty:before{content:"\f1e4"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-tv:before{content:"\f26c"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-ubuntu:before{content:"\f7df"}.fa-uikit:before{content:"\f403"}.fa-umbraco:before{content:"\f8e8"}.fa-umbrella:before{content:"\f0e9"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-uncharted:before{content:"\e084"}.fa-underline:before{content:"\f0cd"}.fa-undo:before{content:"\f0e2"}.fa-undo-alt:before{content:"\f2ea"}.fa-uniregistry:before{content:"\f404"}.fa-unity:before{content:"\e049"}.fa-universal-access:before{content:"\f29a"}.fa-university:before{content:"\f19c"}.fa-unlink:before{content:"\f127"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before{content:"\f13e"}.fa-unsplash:before{content:"\e07c"}.fa-untappd:before{content:"\f405"}.fa-upload:before{content:"\f093"}.fa-ups:before{content:"\f7e0"}.fa-usb:before{content:"\f287"}.fa-user:before{content:"\f007"}.fa-user-alt:before{content:"\f406"}.fa-user-alt-slash:before{content:"\f4fa"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-clock:before{content:"\f4fd"}.fa-user-cog:before{content:"\f4fe"}.fa-user-edit:before{content:"\f4ff"}.fa-user-friends:before{content:"\f500"}.fa-user-graduate:before{content:"\f501"}.fa-user-injured:before{content:"\f728"}.fa-user-lock:before{content:"\f502"}.fa-user-md:before{content:"\f0f0"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-nurse:before{content:"\f82f"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-cog:before{content:"\f509"}.fa-users-slash:before{content:"\e073"}.fa-usps:before{content:"\f7e1"}.fa-ussunnah:before{content:"\f407"}.fa-utensil-spoon:before{content:"\f2e5"}.fa-utensils:before{content:"\f2e7"}.fa-vaadin:before{content:"\f408"}.fa-vector-square:before{content:"\f5cb"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-vest:before{content:"\e085"}.fa-vest-patches:before{content:"\e086"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-vial:before{content:"\f492"}.fa-vials:before{content:"\f493"}.fa-viber:before{content:"\f409"}.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vihara:before{content:"\f6a7"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-virus:before{content:"\e074"}.fa-virus-slash:before{content:"\e075"}.fa-viruses:before{content:"\e076"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-voicemail:before{content:"\f897"}.fa-volleyball-ball:before{content:"\f45f"}.fa-volume-down:before{content:"\f027"}.fa-volume-mute:before{content:"\f6a9"}.fa-volume-off:before{content:"\f026"}.fa-volume-up:before{content:"\f028"}.fa-vote-yea:before{content:"\f772"}.fa-vr-cardboard:before{content:"\f729"}.fa-vuejs:before{content:"\f41f"}.fa-walking:before{content:"\f554"}.fa-wallet:before{content:"\f555"}.fa-warehouse:before{content:"\f494"}.fa-watchman-monitoring:before{content:"\e087"}.fa-water:before{content:"\f773"}.fa-wave-square:before{content:"\f83e"}.fa-waze:before{content:"\f83f"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weight:before{content:"\f496"}.fa-weight-hanging:before{content:"\f5cd"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-wheelchair:before{content:"\f193"}.fa-whmcs:before{content:"\f40d"}.fa-wifi:before{content:"\f1eb"}.fa-wikipedia-w:before{content:"\f266"}.fa-wind:before{content:"\f72e"}.fa-window-close:before{content:"\f410"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-windows:before{content:"\f17a"}.fa-wine-bottle:before{content:"\f72f"}.fa-wine-glass:before{content:"\f4e3"}.fa-wine-glass-alt:before{content:"\f5ce"}.fa-wix:before{content:"\f5cf"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-wodu:before{content:"\e088"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-won-sign:before{content:"\f159"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wpressr:before{content:"\f3e4"}.fa-wrench:before{content:"\f0ad"}.fa-x-ray:before{content:"\f497"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yammer:before{content:"\f840"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yarn:before{content:"\f7e3"}.fa-yelp:before{content:"\f1e9"}.fa-yen-sign:before{content:"\f157"}.fa-yin-yang:before{content:"\f6ad"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-youtube-square:before{content:"\f431"}.fa-zhihu:before{content:"\f63f"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}@font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:"Font Awesome 5 Brands"}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.eot);src:url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.woff) format("woff"),url(../webfonts/fa-regular-400.ttf) format("truetype"),url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")}.fab,.far{font-weight:400}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.far,.fas{font-family:"Font Awesome 5 Free"}.fa,.fas{font-weight:900} \ No newline at end of file diff --git a/assetsIndex/css/main.css b/assetsIndex/css/main.css new file mode 100644 index 0000000..4a5fdd2 --- /dev/null +++ b/assetsIndex/css/main.css @@ -0,0 +1,1557 @@ +@import url(fontawesome-all.min.css); +@import url("https://fonts.googleapis.com/css?family=Source+Sans+Pro:300italic,600italic,300,600"); + +html, body, div, span, applet, object, +iframe, h1, h3, h4, h6, p, blockquote, +pre, a, abbr, acronym, address, big, cite, +code, del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, b, +u, i, center, dl, dt, dd, ol, ul, li, fieldset, +form, label, legend, table, caption, tbody, +tfoot, thead, tr, th, td, article, aside, +canvas, details, embed, figure, figcaption, +footer, header, hgroup, menu, nav, output, ruby, +section, summary, time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline;} + +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block;} + +body { + line-height: 1; +} + +ol, ul { + list-style: none; +} + +blockquote, q { + quotes: none; +} + + blockquote:before, blockquote:after, q:before, q:after { + content: ''; + content: none; + } + +table { + border-collapse: collapse; + border-spacing: 0; +} + +body { + -webkit-text-size-adjust: none; +} + +mark { + background-color: transparent; + color: inherit; +} + +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +input, select, textarea { + -moz-appearance: none; + -webkit-appearance: none; + -ms-appearance: none; + appearance: none; +} + +/* Basic */ + + @-ms-viewport { + width: device-width; + } + + @media screen and (max-width: 480px) { + + html, body { + min-width: 320px; + } + + } + + html { + box-sizing: border-box; + } + + *, *:before, *:after { + box-sizing: inherit; + } + + body { + background: #1b1f22; + } + + body.is-preload *, body.is-preload *:before, body.is-preload *:after { + -moz-animation: none !important; + -webkit-animation: none !important; + -ms-animation: none !important; + animation: none !important; + -moz-transition: none !important; + -webkit-transition: none !important; + -ms-transition: none !important; + transition: none !important; + } + +/* Type */ + + html { + font-size: 16pt; + } + + @media screen and (max-width: 1680px) { + + html { + font-size: 12pt; + } + + } + + @media screen and (max-width: 736px) { + + html { + font-size: 11pt; + } + + } + + @media screen and (max-width: 360px) { + + html { + font-size: 10pt; + } + + } + + body, input, select, textarea { + color: #ffffff; + font-family: "Source Sans Pro", sans-serif; + font-weight: 300; + font-size: 1rem; + line-height: 1.65; + } + + a { + -moz-transition: color 0.2s ease-in-out, background-color 0.2s ease-in-out, border-bottom-color 0.2s ease-in-out; + -webkit-transition: color 0.2s ease-in-out, background-color 0.2s ease-in-out, border-bottom-color 0.2s ease-in-out; + -ms-transition: color 0.2s ease-in-out, background-color 0.2s ease-in-out, border-bottom-color 0.2s ease-in-out; + transition: color 0.2s ease-in-out, background-color 0.2s ease-in-out, border-bottom-color 0.2s ease-in-out; + border-bottom: dotted 1px rgba(255, 255, 255, 0.5); + text-decoration: none; + color: inherit; + } + + a:hover { + border-bottom-color: transparent; + } + + strong, b { + color: #ffffff; + font-weight: 600; + } + + em, i { + font-style: italic; + } + + p { + margin: 0 0 2rem 0; + } + + h1, h3, h4, h6 { + color: #ffffff; + font-weight: 600; + line-height: 1.5; + margin: 0 0 1rem 0; + text-transform: uppercase; + letter-spacing: 0.2rem; + } + + h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { + color: inherit; + text-decoration: none; + } + + h1.major, h2.major, h3.major, h4.major, h5.major, h6.major { + border-bottom: solid 1px #ffffff; + width: -moz-max-content; + width: -webkit-max-content; + width: -ms-max-content; + width: max-content; + padding-bottom: 0.5rem; + margin: 0 0 2rem 0; + } + + h1 { + font-size: 2.25rem; + line-height: 1.3; + letter-spacing: 0.5rem; + } + + h2 { + font-size: 1.5rem; + line-height: 1.4; + } + + h3 { + font-size: 1rem; + } + + h4 { + font-size: 0.8rem; + } + + h5 { + font-size: 0.7rem; + } + + h6 { + font-size: 0.6rem; + } + + @media screen and (max-width: 736px) { + + h1 { + font-size: 1.75rem; + line-height: 1.4; + } + + h2 { + font-size: 1.25em; + line-height: 1.5; + } + + } + + sub { + font-size: 0.8rem; + position: relative; + top: 0.5rem; + } + + sup { + font-size: 0.8rem; + position: relative; + top: -0.5rem; + } + + blockquote { + border-left: solid 4px #ffffff; + font-style: italic; + margin: 0 0 2rem 0; + padding: 0.5rem 0 0.5rem 2rem; + } + + code { + background: rgba(255, 255, 255, 0.075); + border-radius: 4px; + font-family: "Courier New", monospace; + font-size: 0.9rem; + margin: 0 0.25rem; + padding: 0.25rem 0.65rem; + } + + pre { + -webkit-overflow-scrolling: touch; + font-family: "Courier New", monospace; + font-size: 0.9rem; + margin: 0 0 2rem 0; + } + + pre code { + display: block; + line-height: 1.75; + padding: 1rem 1.5rem; + overflow-x: auto; + } + + hr { + border: 0; + border-bottom: solid 1px #ffffff; + margin: 2.75rem 0; + } + + .align-left { + text-align: left; + } + + .align-center { + text-align: center; + } + + .align-right { + text-align: right; + } + +/* Form */ + + form { + margin: 0 0 2rem 0; + } + + form > :last-child { + margin-bottom: 0; + } + + form > .fields { + display: -moz-flex; + display: -webkit-flex; + display: -ms-flex; + display: flex; + -moz-flex-wrap: wrap; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + width: calc(100% + 3rem); + margin: -1.5rem 0 2rem -1.5rem; + } + + form > .fields > .field { + -moz-flex-grow: 0; + -webkit-flex-grow: 0; + -ms-flex-grow: 0; + flex-grow: 0; + -moz-flex-shrink: 0; + -webkit-flex-shrink: 0; + -ms-flex-shrink: 0; + flex-shrink: 0; + padding: 1.5rem 0 0 1.5rem; + width: calc(100% - 1.5rem); + } + + form > .fields > .field.half { + width: calc(50% - 0.75rem); + } + + form > .fields > .field.third { + width: calc(100%/3 - 0.5rem); + } + + form > .fields > .field.quarter { + width: calc(25% - 0.375rem); + } + + @media screen and (max-width: 480px) { + + form > .fields { + width: calc(100% + 3rem); + margin: -1.5rem 0 2rem -1.5rem; + } + + form > .fields > .field { + padding: 1.5rem 0 0 1.5rem; + width: calc(100% - 1.5rem); + } + + form > .fields > .field.half { + width: calc(100% - 1.5rem); + } + + form > .fields > .field.third { + width: calc(100% - 1.5rem); + } + + form > .fields > .field.quarter { + width: calc(100% - 1.5rem); + } + + } + + label { + color: #ffffff; + display: block; + font-size: 0.8rem; + font-weight: 300; + letter-spacing: 0.2rem; + line-height: 1.5; + margin: 0 0 1rem 0; + text-transform: uppercase; + } + + input[type="text"], + input[type="password"], + input[type="email"], + input[type="tel"], + select, + textarea { + -moz-appearance: none; + -webkit-appearance: none; + -ms-appearance: none; + appearance: none; + -moz-transition: border-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out, background-color 0.2s ease-in-out; + -webkit-transition: border-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out, background-color 0.2s ease-in-out; + -ms-transition: border-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out, background-color 0.2s ease-in-out; + transition: border-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out, background-color 0.2s ease-in-out; + background-color: transparent; + border-radius: 4px; + border: solid 1px #ffffff; + color: inherit; + display: block; + outline: 0; + padding: 0 1rem; + text-decoration: none; + width: 100%; + } + + input[type="text"]:invalid, + input[type="password"]:invalid, + input[type="email"]:invalid, + input[type="tel"]:invalid, + select:invalid, + textarea:invalid { + box-shadow: none; + } + + input[type="text"]:focus, + input[type="password"]:focus, + input[type="email"]:focus, + input[type="tel"]:focus, + select:focus, + textarea:focus { + background: rgba(255, 255, 255, 0.075); + border-color: #ffffff; + box-shadow: 0 0 0 1px #ffffff; + } + + select { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' preserveAspectRatio='none' viewBox='0 0 40 40'%3E%3Cpath d='M9.4,12.3l10.4,10.4l10.4-10.4c0.2-0.2,0.5-0.4,0.9-0.4c0.3,0,0.6,0.1,0.9,0.4l3.3,3.3c0.2,0.2,0.4,0.5,0.4,0.9 c0,0.4-0.1,0.6-0.4,0.9L20.7,31.9c-0.2,0.2-0.5,0.4-0.9,0.4c-0.3,0-0.6-0.1-0.9-0.4L4.3,17.3c-0.2-0.2-0.4-0.5-0.4-0.9 c0-0.4,0.1-0.6,0.4-0.9l3.3-3.3c0.2-0.2,0.5-0.4,0.9-0.4S9.1,12.1,9.4,12.3z' fill='%23ffffff' /%3E%3C/svg%3E"); + background-size: 1.25rem; + background-repeat: no-repeat; + background-position: calc(100% - 1rem) center; + height: 2.75rem; + padding-right: 2.75rem; + text-overflow: ellipsis; + } + + select option { + color: #ffffff; + background: #1b1f22; + } + + select:focus::-ms-value { + background-color: transparent; + } + + select::-ms-expand { + display: none; + } + + input[type="text"], + input[type="password"], + input[type="email"], + select { + height: 2.75rem; + } + + textarea { + padding: 0.75rem 1rem; + } + + input[type="checkbox"], + input[type="radio"] { + -moz-appearance: none; + -webkit-appearance: none; + -ms-appearance: none; + appearance: none; + display: block; + float: left; + margin-right: -2rem; + opacity: 0; + width: 1rem; + z-index: -1; + } + + input[type="checkbox"] + label, + input[type="radio"] + label { + text-decoration: none; + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; + color: #ffffff; + cursor: pointer; + display: inline-block; + font-size: 0.8rem; + font-weight: 300; + margin: 0 0 0.5rem 0; + padding-left: 2.65rem; + padding-right: 0.75rem; + position: relative; + } + + input[type="checkbox"] + label:before, + input[type="radio"] + label:before { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + display: inline-block; + font-style: normal; + font-variant: normal; + text-rendering: auto; + line-height: 1; + text-transform: none !important; + font-family: 'Font Awesome 5 Free'; + font-weight: 900; + } + + input[type="checkbox"] + label:before, + input[type="radio"] + label:before { + -moz-transition: border-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out, background-color 0.2s ease-in-out; + -webkit-transition: border-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out, background-color 0.2s ease-in-out; + -ms-transition: border-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out, background-color 0.2s ease-in-out; + transition: border-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out, background-color 0.2s ease-in-out; + border-radius: 4px; + border: solid 1px #ffffff; + content: ''; + display: inline-block; + height: 1.65rem; + left: 0; + line-height: 1.65rem; + position: absolute; + text-align: center; + top: -0.15rem; + width: 1.65rem; + } + + input[type="checkbox"]:checked + label:before, + input[type="radio"]:checked + label:before { + background: #ffffff !important; + border-color: #ffffff !important; + color: #1b1f22; + content: '\f00c'; + } + + input[type="checkbox"]:focus + label:before, + input[type="radio"]:focus + label:before { + background: rgba(255, 255, 255, 0.075); + border-color: #ffffff; + box-shadow: 0 0 0 1px #ffffff; + } + + input[type="checkbox"] + label:before { + border-radius: 4px; + } + + input[type="radio"] + label:before { + border-radius: 100%; + } + + ::-webkit-input-placeholder { + color: rgba(255, 255, 255, 0.5) !important; + opacity: 1.0; + } + + :-moz-placeholder { + color: rgba(255, 255, 255, 0.5) !important; + opacity: 1.0; + } + + ::-moz-placeholder { + color: rgba(255, 255, 255, 0.5) !important; + opacity: 1.0; + } + + :-ms-input-placeholder { + color: rgba(255, 255, 255, 0.5) !important; + opacity: 1.0; + } + + .formerize-placeholder { + color: rgba(255, 255, 255, 0.5) !important; + opacity: 1.0; + } + +/* Box */ + + .box { + border-radius: 4px; + border: solid 1px #ffffff; + margin-bottom: 2rem; + padding: 1.5em; + } + + .box > :last-child, + .box > :last-child > :last-child, + .box > :last-child > :last-child > :last-child { + margin-bottom: 0; + } + + .box.alt { + border: 0; + border-radius: 0; + padding: 0; + } + +/* Icon */ + + .icon { + text-decoration: none; + border-bottom: none; + position: relative; + } + + .icon:before { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + display: inline-block; + font-style: normal; + font-variant: normal; + text-rendering: auto; + line-height: 1; + text-transform: none !important; + font-family: 'Font Awesome 5 Free'; + font-weight: 400; + } + + .icon > .label { + display: none; + } + + .icon:before { + line-height: inherit; + } + + .icon.solid:before { + font-weight: 900; + } + + .icon.brands:before { + font-family: 'Font Awesome 5 Brands'; + } + +/* Image */ + + .image { + border-radius: 4px; + border: 0; + display: inline-block; + position: relative; + } + + .image:before { + pointer-events: none; + background-image: url("../../images/overlay.png"); + background-color: rgba(19, 21, 25, 0.5); + border-radius: 4px; + content: ''; + display: block; + height: 100%; + left: 0; + opacity: 0.5; + position: absolute; + top: 0; + width: 100%; + } + + .image img { + border-radius: 4px; + display: block; + } + + .image.left, .image.right { + max-width: 40%; + } + + .image.left img, .image.right img { + width: 100%; + } + + .image.left { + float: left; + padding: 0 1.5em 1em 0; + top: 0.25em; + } + + .image.right { + float: right; + padding: 0 0 1em 1.5em; + top: 0.25em; + } + + .image.fit { + display: block; + margin: 0 0 2rem 0; + width: 100%; + } + + .image.fit img { + width: 100%; + } + + .image.main { + display: block; + margin: 2.5rem 0; + width: 100%; + } + + .image.main img { + width: 100%; + } + + @media screen and (max-width: 736px) { + + .image.main { + margin: 2rem 0; + } + + } + + @media screen and (max-width: 480px) { + + .image.main { + margin: 1.5rem 0; + } + + } + +/* List */ + + ol { + list-style: decimal; + margin: 0 0 2rem 0; + padding-left: 1.25em; + } + + ol li { + padding-left: 0.25em; + } + + ul { + list-style: disc; + margin: 0 0 2rem 0; + padding-left: 1em; + } + + ul li { + padding-left: 0.5em; + } + + ul.alt { + list-style: none; + padding-left: 0; + } + + ul.alt li { + border-top: solid 1px #ffffff; + padding: 0.5em 0; + } + + ul.alt li:first-child { + border-top: 0; + padding-top: 0; + } + + dl { + margin: 0 0 2rem 0; + } + + dl dt { + display: block; + font-weight: 600; + margin: 0 0 1rem 0; + } + + dl dd { + margin-left: 2rem; + } + +/* Actions */ + + ul.actions { + display: -moz-flex; + display: -webkit-flex; + display: -ms-flex; + display: flex; + cursor: default; + list-style: none; + margin-left: -1rem; + padding-left: 0; + } + + ul.actions li { + padding: 0 0 0 1rem; + vertical-align: middle; + } + + ul.actions.special { + -moz-justify-content: center; + -webkit-justify-content: center; + -ms-justify-content: center; + justify-content: center; + width: 100%; + margin-left: 0; + } + + ul.actions.special li:first-child { + padding-left: 0; + } + + ul.actions.stacked { + -moz-flex-direction: column; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + margin-left: 0; + } + + ul.actions.stacked li { + padding: 1.3rem 0 0 0; + } + + ul.actions.stacked li:first-child { + padding-top: 0; + } + + ul.actions.fit { + width: calc(100% + 1rem); + } + + ul.actions.fit li { + -moz-flex-grow: 1; + -webkit-flex-grow: 1; + -ms-flex-grow: 1; + flex-grow: 1; + -moz-flex-shrink: 1; + -webkit-flex-shrink: 1; + -ms-flex-shrink: 1; + flex-shrink: 1; + width: 100%; + } + + ul.actions.fit li > * { + width: 100%; + } + + ul.actions.fit.stacked { + width: 100%; + } + + @media screen and (max-width: 480px) { + + ul.actions:not(.fixed) { + -moz-flex-direction: column; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + margin-left: 0; + width: 100% !important; + } + + ul.actions:not(.fixed) li { + -moz-flex-grow: 1; + -webkit-flex-grow: 1; + -ms-flex-grow: 1; + flex-grow: 1; + -moz-flex-shrink: 1; + -webkit-flex-shrink: 1; + -ms-flex-shrink: 1; + flex-shrink: 1; + padding: 1rem 0 0 0; + text-align: center; + width: 100%; + } + + ul.actions:not(.fixed) li > * { + width: 100%; + } + + ul.actions:not(.fixed) li:first-child { + padding-top: 0; + } + + ul.actions:not(.fixed) li input[type="submit"], + ul.actions:not(.fixed) li input[type="reset"], + ul.actions:not(.fixed) li input[type="button"], + ul.actions:not(.fixed) li button, + ul.actions:not(.fixed) li .button { + width: 100%; + } + + ul.actions:not(.fixed) li input[type="submit"].icon:before, + ul.actions:not(.fixed) li input[type="reset"].icon:before, + ul.actions:not(.fixed) li input[type="button"].icon:before, + ul.actions:not(.fixed) li button.icon:before, + ul.actions:not(.fixed) li .button.icon:before { + margin-left: -0.5em; + } + + } + +/* Icons */ + + ul.icons { + cursor: default; + list-style: none; + padding-left: 0; + } + + ul.icons li { + display: inline-block; + padding: 0 0.75em 0 0; + } + + ul.icons li:last-child { + padding-right: 0; + } + + ul.icons li a { + border-radius: 100%; + box-shadow: inset 0 0 0 1px #ffffff; + display: inline-block; + height: 2.25rem; + line-height: 2.25rem; + text-align: center; + width: 2.25rem; + } + + ul.icons li a:hover { + background-color: rgba(255, 255, 255, 0.075); + } + + ul.icons li a:active { + background-color: rgba(255, 255, 255, 0.175); + } + +/* Button */ + + input[type="submit"], + input[type="reset"], + input[type="button"], + button, + .button { + -moz-appearance: none; + -webkit-appearance: none; + -ms-appearance: none; + appearance: none; + -moz-transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out; + -webkit-transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out; + -ms-transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out; + transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out; + background-color: transparent; + border-radius: 4px; + border: 0; + box-shadow: inset 0 0 0 1px #ffffff; + color: #ffffff !important; + cursor: pointer; + display: inline-block; + font-size: 0.8rem; + font-weight: 300; + height: 2.75rem; + letter-spacing: 0.2rem; + line-height: 2.75rem; + outline: 0; + padding: 0 1.25rem 0 1.35rem; + text-align: center; + text-decoration: none; + text-transform: uppercase; + white-space: nowrap; + } + + input[type="submit"]:hover, + input[type="reset"]:hover, + input[type="button"]:hover, + button:hover, + .button:hover { + background-color: rgba(255, 255, 255, 0.075); + } + + input[type="submit"]:active, + input[type="reset"]:active, + input[type="button"]:active, + button:active, + .button:active { + background-color: rgba(255, 255, 255, 0.175); + } + + input[type="submit"].icon:before, + input[type="reset"].icon:before, + input[type="button"].icon:before, + button.icon:before, + .button.icon:before { + margin-right: 0.5em; + } + + input[type="submit"].fit, + input[type="reset"].fit, + input[type="button"].fit, + button.fit, + .button.fit { + width: 100%; + } + + input[type="submit"].small, + input[type="reset"].small, + input[type="button"].small, + button.small, + .button.small { + font-size: 0.6rem; + height: 2.0625rem; + line-height: 2.0625rem; + } + + input[type="submit"].primary, + input[type="reset"].primary, + input[type="button"].primary, + button.primary, + .button.primary { + background-color: #ffffff; + color: #1b1f22 !important; + font-weight: 600; + } + + input[type="submit"].disabled, input[type="submit"]:disabled, + input[type="reset"].disabled, + input[type="reset"]:disabled, + input[type="button"].disabled, + input[type="button"]:disabled, + button.disabled, + button:disabled, + .button.disabled, + .button:disabled { + pointer-events: none; + cursor: default; + opacity: 0.25; + } + + input[type="submit"], + input[type="reset"], + input[type="button"], + button { + line-height: calc(2.75rem - 2px); + } + + +/* Wrapper */ + + #wrapper { + display: -moz-flex; + display: -webkit-flex; + display: -ms-flex; + display: flex; + -moz-flex-direction: column; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + -moz-align-items: center; + -webkit-align-items: center; + -ms-align-items: center; + align-items: center; + -moz-justify-content: space-between; + -webkit-justify-content: space-between; + -ms-justify-content: space-between; + justify-content: space-between; + position: relative; + min-height: 100vh; + width: 100%; + padding: 4rem 2rem; + z-index: 3; + } + + #wrapper:before { + content: ''; + display: block; + } + + @media screen and (max-width: 1680px) { + + #wrapper { + padding: 3rem 2rem; + } + + } + + @media screen and (max-width: 736px) { + + #wrapper { + padding: 2rem 1rem; + } + + } + + @media screen and (max-width: 480px) { + + #wrapper { + padding: 1rem; + } + + } + +/* Header */ + + #header { + display: -moz-flex; + display: -webkit-flex; + display: -ms-flex; + display: flex; + -moz-flex-direction: column; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + -moz-align-items: center; + -webkit-align-items: center; + -ms-align-items: center; + align-items: center; + -moz-transition: -moz-transform 0.325s ease-in-out, -moz-filter 0.325s ease-in-out, opacity 0.325s ease-in-out; + -webkit-transition: -webkit-transform 0.325s ease-in-out, -webkit-filter 0.325s ease-in-out, opacity 0.325s ease-in-out; + -ms-transition: -ms-transform 0.325s ease-in-out, -ms-filter 0.325s ease-in-out, opacity 0.325s ease-in-out; + transition: transform 0.325s ease-in-out, filter 0.325s ease-in-out, opacity 0.325s ease-in-out; + background-image: -moz-radial-gradient(rgba(0, 0, 0, 0.25) 25%, rgba(0, 0, 0, 0) 55%); + background-image: -webkit-radial-gradient(rgba(0, 0, 0, 0.25) 25%, rgba(0, 0, 0, 0) 55%); + background-image: -ms-radial-gradient(rgba(0, 0, 0, 0.25) 25%, rgba(0, 0, 0, 0) 55%); + background-image: radial-gradient(rgba(0, 0, 0, 0.25) 25%, rgba(0, 0, 0, 0) 55%); + max-width: 100%; + text-align: center; + } + + #header > * { + -moz-transition: opacity 0.325s ease-in-out; + -webkit-transition: opacity 0.325s ease-in-out; + -ms-transition: opacity 0.325s ease-in-out; + transition: opacity 0.325s ease-in-out; + position: relative; + margin-top: 3.5rem; + } + + #header > *:before { + content: ''; + display: block; + position: absolute; + top: calc(-3.5rem - 1px); + left: calc(50% - 1px); + width: 1px; + height: calc(3.5rem + 1px); + background: #ffffff; + } + + #header > :first-child { + margin-top: 0; + } + + #header > :first-child:before { + display: none; + } + + #header .logo { + width: 5.5rem; + height: 5.5rem; + line-height: 5.5rem; + border: solid 1px #ffffff; + border-radius: 100%; + } + + #header .logo .icon:before { + font-size: 2rem; + } + + #header .content { + border-style: solid; + border-color: #ffffff; + border-top-width: 1px; + border-bottom-width: 1px; + max-width: 100%; + } + + #header .content .inner { + -moz-transition: max-height 0.75s ease, padding 0.75s ease, opacity 0.325s ease-in-out; + -webkit-transition: max-height 0.75s ease, padding 0.75s ease, opacity 0.325s ease-in-out; + -ms-transition: max-height 0.75s ease, padding 0.75s ease, opacity 0.325s ease-in-out; + transition: max-height 0.75s ease, padding 0.75s ease, opacity 0.325s ease-in-out; + -moz-transition-delay: 0.25s; + -webkit-transition-delay: 0.25s; + -ms-transition-delay: 0.25s; + transition-delay: 0.25s; + padding: 3rem 2rem; + max-height: 40rem; + overflow: hidden; + } + + #header .content .inner > :last-child { + margin-bottom: 0; + } + + #header .content p { + text-transform: uppercase; + letter-spacing: 0.2rem; + font-size: 0.8rem; + line-height: 2; + } + + #header nav ul { + display: -moz-flex; + display: -webkit-flex; + display: -ms-flex; + display: flex; + margin-bottom: 0; + list-style: none; + padding-left: 0; + border: solid 1px #ffffff; + border-radius: 4px; + } + + #header nav ul li { + padding-left: 0; + border-left: solid 1px #ffffff; + } + + #header nav ul li:first-child { + border-left: 0; + } + + #header nav ul li a { + display: block; + min-width: 7.5rem; + height: 2.75rem; + line-height: 2.75rem; + padding: 0 1.25rem 0 1.45rem; + text-transform: uppercase; + letter-spacing: 0.2rem; + font-size: 0.8rem; + border-bottom: 0; + } + + #header nav ul li a:hover { + background-color: rgba(255, 255, 255, 0.075); + } + + #header nav ul li a:active { + background-color: rgba(255, 255, 255, 0.175); + } + + #header nav.use-middle:after { + content: ''; + display: block; + position: absolute; + top: 0; + left: calc(50% - 1px); + width: 1px; + height: 100%; + background: #ffffff; + } + + #header nav.use-middle ul li.is-middle { + border-left: 0; + } + + body.is-article-visible #header { + -moz-transform: scale(0.95); + -webkit-transform: scale(0.95); + -ms-transform: scale(0.95); + transform: scale(0.95); + -moz-filter: blur(0.1rem); + -webkit-filter: blur(0.1rem); + -ms-filter: blur(0.1rem); + filter: blur(0.1rem); + opacity: 0; + } + + body.is-preload #header { + -moz-filter: blur(0.125rem); + -webkit-filter: blur(0.125rem); + -ms-filter: blur(0.125rem); + filter: blur(0.125rem); + } + + body.is-preload #header > * { + opacity: 0; + } + + body.is-preload #header .content .inner { + max-height: 0; + padding-top: 0; + padding-bottom: 0; + opacity: 0; + } + + @media screen and (max-width: 980px) { + + #header .content p br { + display: none; + } + + } + + @media screen and (max-width: 736px) { + + #header > * { + margin-top: 2rem; + } + + #header > *:before { + top: calc(-2rem - 1px); + height: calc(2rem + 1px); + } + + #header .logo { + width: 4.75rem; + height: 4.75rem; + line-height: 4.75rem; + } + + #header .logo .icon:before { + font-size: 1.75rem; + } + + #header .content .inner { + padding: 2.5rem 1rem; + } + + #header .content p { + line-height: 1.875; + } + + } + + @media screen and (max-width: 480px) { + + #header { + padding: 1.5rem 0; + } + + #header .content .inner { + padding: 2.5rem 0; + } + + #header nav ul { + -moz-flex-direction: column; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + min-width: 10rem; + max-width: 100%; + } + + #header nav ul li { + border-left: 0; + border-top: solid 1px #ffffff; + } + + #header nav ul li:first-child { + border-top: 0; + } + + #header nav ul li a { + height: 3rem; + line-height: 3rem; + min-width: 0; + width: 100%; + } + + #header nav.use-middle:after { + display: none; + } + + } + +/* Main */ + + #main { + -moz-flex-grow: 1; + -webkit-flex-grow: 1; + -ms-flex-grow: 1; + flex-grow: 1; + -moz-flex-shrink: 1; + -webkit-flex-shrink: 1; + -ms-flex-shrink: 1; + flex-shrink: 1; + display: -moz-flex; + display: -webkit-flex; + display: -ms-flex; + display: flex; + -moz-align-items: center; + -webkit-align-items: center; + -ms-align-items: center; + align-items: center; + -moz-justify-content: center; + -webkit-justify-content: center; + -ms-justify-content: center; + justify-content: center; + -moz-flex-direction: column; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + position: relative; + max-width: 100%; + z-index: 3; + } + + #main article { + -moz-transform: translateY(0.25rem); + -webkit-transform: translateY(0.25rem); + -ms-transform: translateY(0.25rem); + transform: translateY(0.25rem); + -moz-transition: opacity 0.325s ease-in-out, -moz-transform 0.325s ease-in-out; + -webkit-transition: opacity 0.325s ease-in-out, -webkit-transform 0.325s ease-in-out; + -ms-transition: opacity 0.325s ease-in-out, -ms-transform 0.325s ease-in-out; + transition: opacity 0.325s ease-in-out, transform 0.325s ease-in-out; + padding: 4.5rem 2.5rem 1.5rem 2.5rem ; + position: relative; + width: 40rem; + max-width: 100%; + background-color: rgba(27, 31, 34, 0.85); + border-radius: 4px; + opacity: 0; + } + + #main article.active { + -moz-transform: translateY(0); + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + opacity: 1; + } + + #main article .close { + display: block; + position: absolute; + top: 0; + right: 0; + width: 4rem; + height: 4rem; + cursor: pointer; + text-indent: 4rem; + overflow: hidden; + white-space: nowrap; + } + + #main article .close:before { + -moz-transition: background-color 0.2s ease-in-out; + -webkit-transition: background-color 0.2s ease-in-out; + -ms-transition: background-color 0.2s ease-in-out; + transition: background-color 0.2s ease-in-out; + content: ''; + display: block; + position: absolute; + top: 0.75rem; + left: 0.75rem; + width: 2.5rem; + height: 2.5rem; + border-radius: 100%; + background-position: center; + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='20px' height='20px' viewBox='0 0 20 20' zoomAndPan='disable'%3E%3Cstyle%3Eline %7B stroke: %23ffffff%3B stroke-width: 1%3B %7D%3C/style%3E%3Cline x1='2' y1='2' x2='18' y2='18' /%3E%3Cline x1='18' y1='2' x2='2' y2='18' /%3E%3C/svg%3E"); + background-size: 20px 20px; + background-repeat: no-repeat; + } + + #main article .close:hover:before { + background-color: rgba(255, 255, 255, 0.075); + } + + #main article .close:active:before { + background-color: rgba(255, 255, 255, 0.175); + } + + @media screen and (max-width: 736px) { + + #main article { + padding: 3.5rem 2rem 0.5rem 2rem ; + } + + #main article .close:before { + top: 0.875rem; + left: 0.875rem; + width: 2.25rem; + height: 2.25rem; + background-size: 14px 14px; + } + + } + + @media screen and (max-width: 480px) { + + #main article { + padding: 3rem 1.5rem 0.5rem 1.5rem ; + } + + } + +/* Footer */ + + #footer { + -moz-transition: -moz-transform 0.325s ease-in-out, -moz-filter 0.325s ease-in-out, opacity 0.325s ease-in-out; + -webkit-transition: -webkit-transform 0.325s ease-in-out, -webkit-filter 0.325s ease-in-out, opacity 0.325s ease-in-out; + -ms-transition: -ms-transform 0.325s ease-in-out, -ms-filter 0.325s ease-in-out, opacity 0.325s ease-in-out; + transition: transform 0.325s ease-in-out, filter 0.325s ease-in-out, opacity 0.325s ease-in-out; + width: 100%; + max-width: 100%; + margin-top: 2rem; + text-align: center; + } + + #footer .copyright { + letter-spacing: 0.2rem; + font-size: 0.6rem; + opacity: 0.75; + margin-bottom: 0; + text-transform: uppercase; + } + + body.is-article-visible #footer { + -moz-transform: scale(0.95); + -webkit-transform: scale(0.95); + -ms-transform: scale(0.95); + transform: scale(0.95); + -moz-filter: blur(0.1rem); + -webkit-filter: blur(0.1rem); + -ms-filter: blur(0.1rem); + filter: blur(0.1rem); + opacity: 0; + } + + body.is-preload #footer { + opacity: 0; + } + + +/* CSS PROPIO */ + +.icon, #marca{ + color: #E879F9 !important; +} +#botFormSesionConfirmar, #botFormRegistroConfirmar, #botFormNombreConfirmar{ + background-color: #f4b942 !important; +} +#navStats, #navSesion{ + display:flex; + justify-content:center; + align-items:center; +} +#navStats ul, #navSesion ul{ + width: 75%; +} +#navStats ul li, #navSesion ul li{ + width:100%; +} + +.inner{ + padding-bottom: 0; +} +a{ + cursor:pointer; +} + +.modalContent{ + background-color: #1b1f22; + color:white; +} +.modalContent .form-control:focus{ + background-color: white; + color: black; +} + +#header .content { + width: 100%; +} + +#header .content .inner { + width: 100%; + box-sizing: border-box; +} \ No newline at end of file diff --git a/assetsIndex/css/noscript.css b/assetsIndex/css/noscript.css new file mode 100644 index 0000000..a27f428 --- /dev/null +++ b/assetsIndex/css/noscript.css @@ -0,0 +1,37 @@ +/* + Dimension by HTML5 UP + html5up.net | @ajlkn + Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +*/ + +/* BG */ + + body.is-preload #bg:before { + background-color: transparent; + } + +/* Header */ + + body.is-preload #header { + -moz-filter: none; + -webkit-filter: none; + -ms-filter: none; + filter: none; + } + + body.is-preload #header > * { + opacity: 1; + } + + body.is-preload #header .content .inner { + max-height: none; + padding: 3rem 2rem; + opacity: 1; + } + +/* Main */ + + #main article { + opacity: 1; + margin: 4rem 0 0 0; + } \ No newline at end of file diff --git a/assetsIndex/js/breakpoints.min.js b/assetsIndex/js/breakpoints.min.js new file mode 100644 index 0000000..e20ae89 --- /dev/null +++ b/assetsIndex/js/breakpoints.min.js @@ -0,0 +1,2 @@ +/* breakpoints.js v1.0 | @ajlkn | MIT licensed */ +var breakpoints=function(){"use strict";function e(e){t.init(e)}var t={list:null,media:{},events:[],init:function(e){t.list=e,window.addEventListener("resize",t.poll),window.addEventListener("orientationchange",t.poll),window.addEventListener("load",t.poll),window.addEventListener("fullscreenchange",t.poll)},active:function(e){var n,a,s,i,r,d,c;if(!(e in t.media)){if(">="==e.substr(0,2)?(a="gte",n=e.substr(2)):"<="==e.substr(0,2)?(a="lte",n=e.substr(2)):">"==e.substr(0,1)?(a="gt",n=e.substr(1)):"<"==e.substr(0,1)?(a="lt",n=e.substr(1)):"!"==e.substr(0,1)?(a="not",n=e.substr(1)):(a="eq",n=e),n&&n in t.list)if(i=t.list[n],Array.isArray(i)){if(r=parseInt(i[0]),d=parseInt(i[1]),isNaN(r)){if(isNaN(d))return;c=i[1].substr(String(d).length)}else c=i[0].substr(String(r).length);if(isNaN(r))switch(a){case"gte":s="screen";break;case"lte":s="screen and (max-width: "+d+c+")";break;case"gt":s="screen and (min-width: "+(d+1)+c+")";break;case"lt":s="screen and (max-width: -1px)";break;case"not":s="screen and (min-width: "+(d+1)+c+")";break;default:s="screen and (max-width: "+d+c+")"}else if(isNaN(d))switch(a){case"gte":s="screen and (min-width: "+r+c+")";break;case"lte":s="screen";break;case"gt":s="screen and (max-width: -1px)";break;case"lt":s="screen and (max-width: "+(r-1)+c+")";break;case"not":s="screen and (max-width: "+(r-1)+c+")";break;default:s="screen and (min-width: "+r+c+")"}else switch(a){case"gte":s="screen and (min-width: "+r+c+")";break;case"lte":s="screen and (max-width: "+d+c+")";break;case"gt":s="screen and (min-width: "+(d+1)+c+")";break;case"lt":s="screen and (max-width: "+(r-1)+c+")";break;case"not":s="screen and (max-width: "+(r-1)+c+"), screen and (min-width: "+(d+1)+c+")";break;default:s="screen and (min-width: "+r+c+") and (max-width: "+d+c+")"}}else s="("==i.charAt(0)?"screen and "+i:i;t.media[e]=!!s&&s}return t.media[e]!==!1&&window.matchMedia(t.media[e]).matches},on:function(e,n){t.events.push({query:e,handler:n,state:!1}),t.active(e)&&n()},poll:function(){var e,n;for(e=0;e+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0 $window.height()) + $wrapper.css('height', 'auto'); + else + $wrapper.css('height', '100vh'); + + }, 250); + + }).triggerHandler('resize.flexbox-fix'); + + } + + // Nav. + var $nav = $header.children('nav'), + $nav_li = $nav.find('li'); + + // Add "middle" alignment classes if we're dealing with an even number of items. + if ($nav_li.length % 2 == 0) { + + $nav.addClass('use-middle'); + $nav_li.eq( ($nav_li.length / 2) ).addClass('is-middle'); + + } + + // Main. + var delay = 325, + locked = false; + + // Methods. + $main._show = function(id, initial) { + + var $article = $main_articles.filter('#' + id); + + // No such article? Bail. + if ($article.length == 0) + return; + + // Handle lock. + + // Already locked? Speed through "show" steps w/o delays. + if (locked || (typeof initial != 'undefined' && initial === true)) { + + // Mark as switching. + $body.addClass('is-switching'); + + // Mark as visible. + $body.addClass('is-article-visible'); + + // Deactivate all articles (just in case one's already active). + $main_articles.removeClass('active'); + + // Hide header, footer. + $header.hide(); + $footer.hide(); + + // Show main, article. + $main.show(); + $article.show(); + + // Activate article. + $article.addClass('active'); + + // Unlock. + locked = false; + + // Unmark as switching. + setTimeout(function() { + $body.removeClass('is-switching'); + }, (initial ? 1000 : 0)); + + return; + + } + + // Lock. + locked = true; + + // Article already visible? Just swap articles. + if ($body.hasClass('is-article-visible')) { + + // Deactivate current article. + var $currentArticle = $main_articles.filter('.active'); + + $currentArticle.removeClass('active'); + + // Show article. + setTimeout(function() { + + // Hide current article. + $currentArticle.hide(); + + // Show article. + $article.show(); + + // Activate article. + setTimeout(function() { + + $article.addClass('active'); + + // Window stuff. + $window + .scrollTop(0) + .triggerHandler('resize.flexbox-fix'); + + // Unlock. + setTimeout(function() { + locked = false; + }, delay); + + }, 25); + + }, delay); + + } + + // Otherwise, handle as normal. + else { + + // Mark as visible. + $body + .addClass('is-article-visible'); + + // Show article. + setTimeout(function() { + + // Hide header, footer. + $header.hide(); + $footer.hide(); + + // Show main, article. + $main.show(); + $article.show(); + + // Activate article. + setTimeout(function() { + + $article.addClass('active'); + + // Window stuff. + $window + .scrollTop(0) + .triggerHandler('resize.flexbox-fix'); + + // Unlock. + setTimeout(function() { + locked = false; + }, delay); + + }, 25); + + }, delay); + + } + + }; + + $main._hide = function(addState) { + + var $article = $main_articles.filter('.active'); + + // Article not visible? Bail. + if (!$body.hasClass('is-article-visible')) + return; + + // Add state? + if (typeof addState != 'undefined' + && addState === true) + history.pushState(null, null, '#'); + + // Handle lock. + + // Already locked? Speed through "hide" steps w/o delays. + if (locked) { + + // Mark as switching. + $body.addClass('is-switching'); + + // Deactivate article. + $article.removeClass('active'); + + // Hide article, main. + $article.hide(); + $main.hide(); + + // Show footer, header. + $footer.show(); + $header.show(); + + // Unmark as visible. + $body.removeClass('is-article-visible'); + + // Unlock. + locked = false; + + // Unmark as switching. + $body.removeClass('is-switching'); + + // Window stuff. + $window + .scrollTop(0) + .triggerHandler('resize.flexbox-fix'); + + return; + + } + + // Lock. + locked = true; + + // Deactivate article. + $article.removeClass('active'); + + // Hide article. + setTimeout(function() { + + // Hide article, main. + $article.hide(); + $main.hide(); + + // Show footer, header. + $footer.show(); + $header.show(); + + // Unmark as visible. + setTimeout(function() { + + $body.removeClass('is-article-visible'); + + // Window stuff. + $window + .scrollTop(0) + .triggerHandler('resize.flexbox-fix'); + + // Unlock. + setTimeout(function() { + locked = false; + }, delay); + + }, 25); + + }, delay); + + + }; + + // Articles. + $main_articles.each(function() { + + var $this = $(this); + + // Close. + $('
Close
') + .appendTo($this) + .on('click', function() { + location.hash = ''; + }); + + // Prevent clicks from inside article from bubbling. + $this.on('click', function(event) { + event.stopPropagation(); + }); + + }); + + // Events. + $body.on('click', function(event) { + + // Article visible? Hide. + if ($body.hasClass('is-article-visible')) + $main._hide(true); + + }); + + $window.on('keyup', function(event) { + + switch (event.keyCode) { + + case 27: + + // Article visible? Hide. + if ($body.hasClass('is-article-visible')) + $main._hide(true); + + break; + + default: + break; + + } + + }); + + $window.on('hashchange', function(event) { + + // Empty hash? + if (location.hash == '' + || location.hash == '#') { + + // Prevent default. + event.preventDefault(); + event.stopPropagation(); + + // Hide. + $main._hide(); + + } + + // Otherwise, check for a matching article. + else if ($main_articles.filter(location.hash).length > 0) { + + // Prevent default. + event.preventDefault(); + event.stopPropagation(); + + // Show article. + $main._show(location.hash.substr(1)); + + } + + }); + + // Scroll restoration. + // This prevents the page from scrolling back to the top on a hashchange. + if ('scrollRestoration' in history) + history.scrollRestoration = 'manual'; + else { + + var oldScrollPos = 0, + scrollPos = 0, + $htmlbody = $('html,body'); + + $window + .on('scroll', function() { + + oldScrollPos = scrollPos; + scrollPos = $htmlbody.scrollTop(); + + }) + .on('hashchange', function() { + $window.scrollTop(oldScrollPos); + }); + + } + + // Initialize. + + // Hide main, articles. + $main.hide(); + $main_articles.hide(); + + // Initial article. + if (location.hash != '' + && location.hash != '#') + $window.on('load', function() { + $main._show(location.hash.substr(1), true); + }); + +})(jQuery); \ No newline at end of file diff --git a/assetsIndex/js/util.js b/assetsIndex/js/util.js new file mode 100644 index 0000000..ecf7b37 --- /dev/null +++ b/assetsIndex/js/util.js @@ -0,0 +1,587 @@ +(function($) { + + /** + * Generate an indented list of links from a nav. Meant for use with panel(). + * @return {jQuery} jQuery object. + */ + $.fn.navList = function() { + + var $this = $(this); + $a = $this.find('a'), + b = []; + + $a.each(function() { + + var $this = $(this), + indent = Math.max(0, $this.parents('li').length - 1), + href = $this.attr('href'), + target = $this.attr('target'); + + b.push( + '' + + '' + + $this.text() + + '' + ); + + }); + + return b.join(''); + + }; + + /** + * Panel-ify an element. + * @param {object} userConfig User config. + * @return {jQuery} jQuery object. + */ + $.fn.panel = function(userConfig) { + + // No elements? + if (this.length == 0) + return $this; + + // Multiple elements? + if (this.length > 1) { + + for (var i=0; i < this.length; i++) + $(this[i]).panel(userConfig); + + return $this; + + } + + // Vars. + var $this = $(this), + $body = $('body'), + $window = $(window), + id = $this.attr('id'), + config; + + // Config. + config = $.extend({ + + // Delay. + delay: 0, + + // Hide panel on link click. + hideOnClick: false, + + // Hide panel on escape keypress. + hideOnEscape: false, + + // Hide panel on swipe. + hideOnSwipe: false, + + // Reset scroll position on hide. + resetScroll: false, + + // Reset forms on hide. + resetForms: false, + + // Side of viewport the panel will appear. + side: null, + + // Target element for "class". + target: $this, + + // Class to toggle. + visibleClass: 'visible' + + }, userConfig); + + // Expand "target" if it's not a jQuery object already. + if (typeof config.target != 'jQuery') + config.target = $(config.target); + + // Panel. + + // Methods. + $this._hide = function(event) { + + // Already hidden? Bail. + if (!config.target.hasClass(config.visibleClass)) + return; + + // If an event was provided, cancel it. + if (event) { + + event.preventDefault(); + event.stopPropagation(); + + } + + // Hide. + config.target.removeClass(config.visibleClass); + + // Post-hide stuff. + window.setTimeout(function() { + + // Reset scroll position. + if (config.resetScroll) + $this.scrollTop(0); + + // Reset forms. + if (config.resetForms) + $this.find('form').each(function() { + this.reset(); + }); + + }, config.delay); + + }; + + // Vendor fixes. + $this + .css('-ms-overflow-style', '-ms-autohiding-scrollbar') + .css('-webkit-overflow-scrolling', 'touch'); + + // Hide on click. + if (config.hideOnClick) { + + $this.find('a') + .css('-webkit-tap-highlight-color', 'rgba(0,0,0,0)'); + + $this + .on('click', 'a', function(event) { + + var $a = $(this), + href = $a.attr('href'), + target = $a.attr('target'); + + if (!href || href == '#' || href == '' || href == '#' + id) + return; + + // Cancel original event. + event.preventDefault(); + event.stopPropagation(); + + // Hide panel. + $this._hide(); + + // Redirect to href. + window.setTimeout(function() { + + if (target == '_blank') + window.open(href); + else + window.location.href = href; + + }, config.delay + 10); + + }); + + } + + // Event: Touch stuff. + $this.on('touchstart', function(event) { + + $this.touchPosX = event.originalEvent.touches[0].pageX; + $this.touchPosY = event.originalEvent.touches[0].pageY; + + }) + + $this.on('touchmove', function(event) { + + if ($this.touchPosX === null + || $this.touchPosY === null) + return; + + var diffX = $this.touchPosX - event.originalEvent.touches[0].pageX, + diffY = $this.touchPosY - event.originalEvent.touches[0].pageY, + th = $this.outerHeight(), + ts = ($this.get(0).scrollHeight - $this.scrollTop()); + + // Hide on swipe? + if (config.hideOnSwipe) { + + var result = false, + boundary = 20, + delta = 50; + + switch (config.side) { + + case 'left': + result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX > delta); + break; + + case 'right': + result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX < (-1 * delta)); + break; + + case 'top': + result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY > delta); + break; + + case 'bottom': + result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY < (-1 * delta)); + break; + + default: + break; + + } + + if (result) { + + $this.touchPosX = null; + $this.touchPosY = null; + $this._hide(); + + return false; + + } + + } + + // Prevent vertical scrolling past the top or bottom. + if (($this.scrollTop() < 0 && diffY < 0) + || (ts > (th - 2) && ts < (th + 2) && diffY > 0)) { + + event.preventDefault(); + event.stopPropagation(); + + } + + }); + + // Event: Prevent certain events inside the panel from bubbling. + $this.on('click touchend touchstart touchmove', function(event) { + event.stopPropagation(); + }); + + // Event: Hide panel if a child anchor tag pointing to its ID is clicked. + $this.on('click', 'a[href="#' + id + '"]', function(event) { + + event.preventDefault(); + event.stopPropagation(); + + config.target.removeClass(config.visibleClass); + + }); + + // Body. + + // Event: Hide panel on body click/tap. + $body.on('click touchend', function(event) { + $this._hide(event); + }); + + // Event: Toggle. + $body.on('click', 'a[href="#' + id + '"]', function(event) { + + event.preventDefault(); + event.stopPropagation(); + + config.target.toggleClass(config.visibleClass); + + }); + + // Window. + + // Event: Hide on ESC. + if (config.hideOnEscape) + $window.on('keydown', function(event) { + + if (event.keyCode == 27) + $this._hide(event); + + }); + + return $this; + + }; + + /** + * Apply "placeholder" attribute polyfill to one or more forms. + * @return {jQuery} jQuery object. + */ + $.fn.placeholder = function() { + + // Browser natively supports placeholders? Bail. + if (typeof (document.createElement('input')).placeholder != 'undefined') + return $(this); + + // No elements? + if (this.length == 0) + return $this; + + // Multiple elements? + if (this.length > 1) { + + for (var i=0; i < this.length; i++) + $(this[i]).placeholder(); + + return $this; + + } + + // Vars. + var $this = $(this); + + // Text, TextArea. + $this.find('input[type=text],textarea') + .each(function() { + + var i = $(this); + + if (i.val() == '' + || i.val() == i.attr('placeholder')) + i + .addClass('polyfill-placeholder') + .val(i.attr('placeholder')); + + }) + .on('blur', function() { + + var i = $(this); + + if (i.attr('name').match(/-polyfill-field$/)) + return; + + if (i.val() == '') + i + .addClass('polyfill-placeholder') + .val(i.attr('placeholder')); + + }) + .on('focus', function() { + + var i = $(this); + + if (i.attr('name').match(/-polyfill-field$/)) + return; + + if (i.val() == i.attr('placeholder')) + i + .removeClass('polyfill-placeholder') + .val(''); + + }); + + // Password. + $this.find('input[type=password]') + .each(function() { + + var i = $(this); + var x = $( + $('
') + .append(i.clone()) + .remove() + .html() + .replace(/type="password"/i, 'type="text"') + .replace(/type=password/i, 'type=text') + ); + + if (i.attr('id') != '') + x.attr('id', i.attr('id') + '-polyfill-field'); + + if (i.attr('name') != '') + x.attr('name', i.attr('name') + '-polyfill-field'); + + x.addClass('polyfill-placeholder') + .val(x.attr('placeholder')).insertAfter(i); + + if (i.val() == '') + i.hide(); + else + x.hide(); + + i + .on('blur', function(event) { + + event.preventDefault(); + + var x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]'); + + if (i.val() == '') { + + i.hide(); + x.show(); + + } + + }); + + x + .on('focus', function(event) { + + event.preventDefault(); + + var i = x.parent().find('input[name=' + x.attr('name').replace('-polyfill-field', '') + ']'); + + x.hide(); + + i + .show() + .focus(); + + }) + .on('keypress', function(event) { + + event.preventDefault(); + x.val(''); + + }); + + }); + + // Events. + $this + .on('submit', function() { + + $this.find('input[type=text],input[type=password],textarea') + .each(function(event) { + + var i = $(this); + + if (i.attr('name').match(/-polyfill-field$/)) + i.attr('name', ''); + + if (i.val() == i.attr('placeholder')) { + + i.removeClass('polyfill-placeholder'); + i.val(''); + + } + + }); + + }) + .on('reset', function(event) { + + event.preventDefault(); + + $this.find('select') + .val($('option:first').val()); + + $this.find('input,textarea') + .each(function() { + + var i = $(this), + x; + + i.removeClass('polyfill-placeholder'); + + switch (this.type) { + + case 'submit': + case 'reset': + break; + + case 'password': + i.val(i.attr('defaultValue')); + + x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]'); + + if (i.val() == '') { + i.hide(); + x.show(); + } + else { + i.show(); + x.hide(); + } + + break; + + case 'checkbox': + case 'radio': + i.attr('checked', i.attr('defaultValue')); + break; + + case 'text': + case 'textarea': + i.val(i.attr('defaultValue')); + + if (i.val() == '') { + i.addClass('polyfill-placeholder'); + i.val(i.attr('placeholder')); + } + + break; + + default: + i.val(i.attr('defaultValue')); + break; + + } + }); + + }); + + return $this; + + }; + + /** + * Moves elements to/from the first positions of their respective parents. + * @param {jQuery} $elements Elements (or selector) to move. + * @param {bool} condition If true, moves elements to the top. Otherwise, moves elements back to their original locations. + */ + $.prioritize = function($elements, condition) { + + var key = '__prioritize'; + + // Expand $elements if it's not already a jQuery object. + if (typeof $elements != 'jQuery') + $elements = $($elements); + + // Step through elements. + $elements.each(function() { + + var $e = $(this), $p, + $parent = $e.parent(); + + // No parent? Bail. + if ($parent.length == 0) + return; + + // Not moved? Move it. + if (!$e.data(key)) { + + // Condition is false? Bail. + if (!condition) + return; + + // Get placeholder (which will serve as our point of reference for when this element needs to move back). + $p = $e.prev(); + + // Couldn't find anything? Means this element's already at the top, so bail. + if ($p.length == 0) + return; + + // Move element to top of parent. + $e.prependTo($parent); + + // Mark element as moved. + $e.data(key, $p); + + } + + // Moved already? + else { + + // Condition is true? Bail. + if (condition) + return; + + $p = $e.data(key); + + // Move element back to its original location (using our placeholder). + $e.insertAfter($p); + + // Unmark element as moved. + $e.removeData(key); + + } + + }); + + }; + +})(jQuery); \ No newline at end of file diff --git a/assetsIndex/sass/base/_page.scss b/assetsIndex/sass/base/_page.scss new file mode 100644 index 0000000..0212a5c --- /dev/null +++ b/assetsIndex/sass/base/_page.scss @@ -0,0 +1,42 @@ +/// +/// Dimension by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Basic */ + + // MSIE: Required for IEMobile. + @-ms-viewport { + width: device-width; + } + + // Ensures page width is always >=320px. + @include breakpoint('<=xsmall') { + html, body { + min-width: 320px; + } + } + + // Set box model to border-box. + // Based on css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice + html { + box-sizing: border-box; + } + + *, *:before, *:after { + box-sizing: inherit; + } + + body { + background: _palette(bg); + + // Stops initial animations until page loads. + &.is-preload { + *, *:before, *:after { + @include vendor('animation', 'none !important'); + @include vendor('transition', 'none !important'); + } + } + + } \ No newline at end of file diff --git a/assetsIndex/sass/base/_reset.scss b/assetsIndex/sass/base/_reset.scss new file mode 100644 index 0000000..3fd0038 --- /dev/null +++ b/assetsIndex/sass/base/_reset.scss @@ -0,0 +1,76 @@ +/// +/// Dimension by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +// Reset. +// Based on meyerweb.com/eric/tools/css/reset (v2.0 | 20110126 | License: public domain) + + html, body, div, span, applet, object, + iframe, h1, h2, h3, h4, h5, h6, p, blockquote, + pre, a, abbr, acronym, address, big, cite, + code, del, dfn, em, img, ins, kbd, q, s, samp, + small, strike, strong, sub, sup, tt, var, b, + u, i, center, dl, dt, dd, ol, ul, li, fieldset, + form, label, legend, table, caption, tbody, + tfoot, thead, tr, th, td, article, aside, + canvas, details, embed, figure, figcaption, + footer, header, hgroup, menu, nav, output, ruby, + section, summary, time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; + } + + article, aside, details, figcaption, figure, + footer, header, hgroup, menu, nav, section { + display: block; + } + + body { + line-height: 1; + } + + ol, ul { + list-style:none; + } + + blockquote, q { + quotes: none; + + &:before, + &:after { + content: ''; + content: none; + } + } + + table { + border-collapse: collapse; + border-spacing: 0; + } + + body { + -webkit-text-size-adjust: none; + } + + mark { + background-color: transparent; + color: inherit; + } + + input::-moz-focus-inner { + border: 0; + padding: 0; + } + + input, select, textarea { + -moz-appearance: none; + -webkit-appearance: none; + -ms-appearance: none; + appearance: none; + } \ No newline at end of file diff --git a/assetsIndex/sass/base/_typography.scss b/assetsIndex/sass/base/_typography.scss new file mode 100644 index 0000000..4425ec3 --- /dev/null +++ b/assetsIndex/sass/base/_typography.scss @@ -0,0 +1,183 @@ +/// +/// Dimension by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Type */ + + html { + font-size: 16pt; + + @include breakpoint('<=xlarge') { + font-size: 12pt; + } + + @include breakpoint('<=small') { + font-size: 11pt; + } + + @include breakpoint('<=xxsmall') { + font-size: 10pt; + } + } + + body, input, select, textarea { + color: _palette(fg); + font-family: _font(family); + font-weight: _font(weight); + font-size: 1rem; + line-height: 1.65; + } + + a { + @include vendor('transition', ( + 'color #{_duration(transition)} ease-in-out', + 'background-color #{_duration(transition)} ease-in-out', + 'border-bottom-color #{_duration(transition)} ease-in-out' + )); + border-bottom: dotted 1px _palette(fg-light); + text-decoration: none; + color: inherit; + + &:hover { + border-bottom-color: transparent; + } + } + + strong, b { + color: _palette(fg-bold); + font-weight: _font(weight-bold); + } + + em, i { + font-style: italic; + } + + p { + margin: 0 0 _size(element-margin) 0; + } + + h1, h2, h3, h4, h5, h6 { + color: _palette(fg-bold); + font-weight: _font(weight-bold); + line-height: 1.5; + margin: 0 0 (_size(element-margin) * 0.5) 0; + text-transform: uppercase; + letter-spacing: _font(letter-spacing); + + a { + color: inherit; + text-decoration: none; + } + + &.major { + border-bottom: solid _size(border-width) _palette(border); + width: -moz-max-content; + width: -webkit-max-content; + width: -ms-max-content; + width: max-content; + padding-bottom: 0.5rem; + margin: 0 0 (_size(element-margin) * 1) 0; + } + } + + h1 { + font-size: 2.25rem; + line-height: 1.3; + letter-spacing: _font(letter-spacing-heading); + } + + h2 { + font-size: 1.5rem; + line-height: 1.4; + letter-spacing: _font(letter-spacing-heading); + } + + h3 { + font-size: 1rem; + } + + h4 { + font-size: 0.8rem; + } + + h5 { + font-size: 0.7rem; + } + + h6 { + font-size: 0.6rem; + } + + @include breakpoint('<=small') { + h1 { + font-size: 1.75rem; + line-height: 1.4; + } + + h2 { + font-size: 1.25em; + line-height: 1.5; + } + } + + sub { + font-size: 0.8rem; + position: relative; + top: 0.5rem; + } + + sup { + font-size: 0.8rem; + position: relative; + top: -0.5rem; + } + + blockquote { + border-left: solid (_size(border-width) * 4) _palette(border); + font-style: italic; + margin: 0 0 _size(element-margin) 0; + padding: (_size(element-margin) / 4) 0 (_size(element-margin) / 4) _size(element-margin); + } + + code { + background: _palette(border-bg); + border-radius: _size(border-radius); + font-family: _font(family-fixed); + font-size: 0.9rem; + margin: 0 0.25rem; + padding: 0.25rem 0.65rem; + } + + pre { + -webkit-overflow-scrolling: touch; + font-family: _font(family-fixed); + font-size: 0.9rem; + margin: 0 0 _size(element-margin) 0; + + code { + display: block; + line-height: 1.75; + padding: 1rem 1.5rem; + overflow-x: auto; + } + } + + hr { + border: 0; + border-bottom: solid _size(border-width) _palette(border); + margin: (_size(element-margin) * 1.375) 0; + } + + .align-left { + text-align: left; + } + + .align-center { + text-align: center; + } + + .align-right { + text-align: right; + } \ No newline at end of file diff --git a/assetsIndex/sass/components/_actions.scss b/assetsIndex/sass/components/_actions.scss new file mode 100644 index 0000000..a5be697 --- /dev/null +++ b/assetsIndex/sass/components/_actions.scss @@ -0,0 +1,101 @@ +/// +/// Dimension by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Actions */ + + ul.actions { + @include vendor('display', 'flex'); + cursor: default; + list-style: none; + margin-left: (_size(element-margin) * -0.5); + padding-left: 0; + + li { + padding: 0 0 0 (_size(element-margin) * 0.5); + vertical-align: middle; + } + + &.special { + @include vendor('justify-content', 'center'); + width: 100%; + margin-left: 0; + + li { + &:first-child { + padding-left: 0; + } + } + } + + &.stacked { + @include vendor('flex-direction', 'column'); + margin-left: 0; + + li { + padding: (_size(element-margin) * 0.65) 0 0 0; + + &:first-child { + padding-top: 0; + } + } + } + + &.fit { + width: calc(100% + #{_size(element-margin) * 0.5}); + + li { + @include vendor('flex-grow', '1'); + @include vendor('flex-shrink', '1'); + width: 100%; + + > * { + width: 100%; + } + } + + &.stacked { + width: 100%; + } + } + + @include breakpoint('<=xsmall') { + &:not(.fixed) { + @include vendor('flex-direction', 'column'); + margin-left: 0; + width: 100% !important; + + li { + @include vendor('flex-grow', '1'); + @include vendor('flex-shrink', '1'); + padding: (_size(element-margin) * 0.5) 0 0 0; + text-align: center; + width: 100%; + + > * { + width: 100%; + } + + &:first-child { + padding-top: 0; + } + + input[type="submit"], + input[type="reset"], + input[type="button"], + button, + .button { + width: 100%; + + &.icon { + &:before { + margin-left: -0.5em; + } + } + } + } + } + } + } \ No newline at end of file diff --git a/assetsIndex/sass/components/_box.scss b/assetsIndex/sass/components/_box.scss new file mode 100644 index 0000000..9081e46 --- /dev/null +++ b/assetsIndex/sass/components/_box.scss @@ -0,0 +1,26 @@ +/// +/// Dimension by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Box */ + + .box { + border-radius: _size(border-radius); + border: solid _size(border-width) _palette(border); + margin-bottom: _size(element-margin); + padding: 1.5em; + + > :last-child, + > :last-child > :last-child, + > :last-child > :last-child > :last-child { + margin-bottom: 0; + } + + &.alt { + border: 0; + border-radius: 0; + padding: 0; + } + } \ No newline at end of file diff --git a/assetsIndex/sass/components/_button.scss b/assetsIndex/sass/components/_button.scss new file mode 100644 index 0000000..d76e75c --- /dev/null +++ b/assetsIndex/sass/components/_button.scss @@ -0,0 +1,84 @@ +/// +/// Dimension by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Button */ + + input[type="submit"], + input[type="reset"], + input[type="button"], + button, + .button { + @include vendor('appearance', 'none'); + @include vendor('transition', 'background-color #{_duration(transition)} ease-in-out, color #{_duration(transition)} ease-in-out'); + background-color: transparent; + border-radius: _size(border-radius); + border: 0; + box-shadow: inset 0 0 0 _size(border-width) _palette(border); + color: _palette(fg-bold) !important; + cursor: pointer; + display: inline-block; + font-size: 0.8rem; + font-weight: _font(weight); + height: _size(element-height); + letter-spacing: _font(letter-spacing); + line-height: _size(element-height); + outline: 0; + padding: 0 1.25rem 0 (1.25rem + (_font(letter-spacing) * 0.5)); + text-align: center; + text-decoration: none; + text-transform: uppercase; + white-space: nowrap; + + &:hover { + background-color: _palette(border-bg); + } + + &:active { + background-color: _palette(border-bg-alt); + } + + &.icon { + &:before { + margin-right: 0.5em; + } + } + + &.fit { + width: 100%; + } + + &.small { + font-size: 0.6rem; + height: (_size(element-height) * 0.75); + line-height: (_size(element-height) * 0.75); + } + + &.primary { + background-color: _palette(fg-bold); + color: _palette(bg) !important; + font-weight: _font(weight-bold); + + &:hover { + } + + &:active { + } + } + + &.disabled, + &:disabled { + @include vendor('pointer-events', 'none'); + cursor: default; + opacity: 0.25; + } + } + + input[type="submit"], + input[type="reset"], + input[type="button"], + button { + line-height: calc(#{_size(element-height)} - 2px); + } \ No newline at end of file diff --git a/assetsIndex/sass/components/_form.scss b/assetsIndex/sass/components/_form.scss new file mode 100644 index 0000000..b50c836 --- /dev/null +++ b/assetsIndex/sass/components/_form.scss @@ -0,0 +1,252 @@ +/// +/// Dimension by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Form */ + + form { + margin: 0 0 _size(element-margin) 0; + + > :last-child { + margin-bottom: 0; + } + + > .fields { + $gutter: (_size(element-margin) * 0.75); + + @include vendor('display', 'flex'); + @include vendor('flex-wrap', 'wrap'); + width: calc(100% + #{$gutter * 2}); + margin: ($gutter * -1) 0 _size(element-margin) ($gutter * -1); + + > .field { + @include vendor('flex-grow', '0'); + @include vendor('flex-shrink', '0'); + padding: $gutter 0 0 $gutter; + width: calc(100% - #{$gutter * 1}); + + &.half { + width: calc(50% - #{$gutter * 0.5}); + } + + &.third { + width: calc(#{100% / 3} - #{$gutter * (1 / 3)}); + } + + &.quarter { + width: calc(25% - #{$gutter * 0.25}); + } + } + } + + @include breakpoint('<=xsmall') { + > .fields { + $gutter: (_size(element-margin) * 0.75); + + width: calc(100% + #{$gutter * 2}); + margin: ($gutter * -1) 0 _size(element-margin) ($gutter * -1); + + > .field { + padding: $gutter 0 0 $gutter; + width: calc(100% - #{$gutter * 1}); + + &.half { + width: calc(100% - #{$gutter * 1}); + } + + &.third { + width: calc(100% - #{$gutter * 1}); + } + + &.quarter { + width: calc(100% - #{$gutter * 1}); + } + } + } + } + } + + label { + color: _palette(fg-bold); + display: block; + font-size: 0.8rem; + font-weight: _font(weight); + letter-spacing: _font(letter-spacing); + line-height: 1.5; + margin: 0 0 (_size(element-margin) * 0.5) 0; + text-transform: uppercase; + } + + input[type="text"], + input[type="password"], + input[type="email"], + input[type="tel"], + select, + textarea { + @include vendor('appearance', 'none'); + @include vendor('transition', ( + 'border-color #{_duration(transition)} ease-in-out', + 'box-shadow #{_duration(transition)} ease-in-out', + 'background-color #{_duration(transition)} ease-in-out' + )); + background-color: transparent; + border-radius: _size(border-radius); + border: solid _size(border-width) _palette(border); + color: inherit; + display: block; + outline: 0; + padding: 0 1rem; + text-decoration: none; + width: 100%; + + &:invalid { + box-shadow: none; + } + + &:focus { + background: _palette(border-bg); + border-color: _palette(fg-bold); + box-shadow: 0 0 0 _size(border-width) _palette(fg-bold); + } + } + + select { + background-image: svg-url(""); + background-size: 1.25rem; + background-repeat: no-repeat; + background-position: calc(100% - 1rem) center; + height: _size(element-height); + padding-right: _size(element-height); + text-overflow: ellipsis; + + option { + color: _palette(fg); + background: _palette(bg); + } + + &:focus { + &::-ms-value { + background-color: transparent; + } + } + + &::-ms-expand { + display: none; + } + } + + input[type="text"], + input[type="password"], + input[type="email"], + select { + height: _size(element-height); + } + + textarea { + padding: 0.75rem 1rem; + } + + input[type="checkbox"], + input[type="radio"], { + @include vendor('appearance', 'none'); + display: block; + float: left; + margin-right: -2rem; + opacity: 0; + width: 1rem; + z-index: -1; + + & + label { + @include icon(false, solid); + @include vendor('user-select', 'none'); + color: _palette(fg); + cursor: pointer; + display: inline-block; + font-size: 0.8rem; + font-weight: _font(weight); + margin: 0 0 (_size(element-margin) * 0.25) 0; + padding-left: (_size(element-height) * 0.6) + 1rem; + padding-right: 0.75rem; + position: relative; + + &:before { + @include vendor('transition', ( + 'border-color #{_duration(transition)} ease-in-out', + 'box-shadow #{_duration(transition)} ease-in-out', + 'background-color #{_duration(transition)} ease-in-out' + )); + border-radius: _size(border-radius); + border: solid _size(border-width) _palette(border); + content: ''; + display: inline-block; + height: (_size(element-height) * 0.6); + left: 0; + line-height: (_size(element-height) * 0.6); + //line-height: calc(#{_size(element-height) * 0.6} + 0em); + position: absolute; + text-align: center; + top: -0.15rem; + width: (_size(element-height) * 0.6); + } + } + + &:checked + label { + &:before { + background: _palette(fg-bold) !important; + border-color: _palette(fg-bold) !important; + color: _palette(bg); + content: '\f00c'; + } + } + + &:focus + label { + &:before { + background: _palette(border-bg); + border-color: _palette(fg-bold); + box-shadow: 0 0 0 _size(border-width) _palette(fg-bold); + } + } + } + + input[type="checkbox"] { + & + label { + &:before { + border-radius: _size(border-radius); + } + } + } + + input[type="radio"] { + & + label { + &:before { + border-radius: 100%; + } + } + } + + ::-webkit-input-placeholder { + color: _palette(fg-light) !important; + opacity: 1.0; + } + + :-moz-placeholder { + color: _palette(fg-light) !important; + opacity: 1.0; + } + + ::-moz-placeholder { + color: _palette(fg-light) !important; + opacity: 1.0; + } + + :-ms-input-placeholder { + color: _palette(fg-light) !important; + opacity: 1.0; + } + + .formerize-placeholder { + color: _palette(fg-light) !important; + opacity: 1.0; + } \ No newline at end of file diff --git a/assetsIndex/sass/components/_icon.scss b/assetsIndex/sass/components/_icon.scss new file mode 100644 index 0000000..c4712aa --- /dev/null +++ b/assetsIndex/sass/components/_icon.scss @@ -0,0 +1,33 @@ +/// +/// Dimension by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Icon */ + + .icon { + @include icon; + border-bottom: none; + position: relative; + + > .label { + display: none; + } + + &:before { + line-height: inherit; + } + + &.solid { + &:before { + font-weight: 900; + } + } + + &.brands { + &:before { + font-family: 'Font Awesome 5 Brands'; + } + } + } \ No newline at end of file diff --git a/assetsIndex/sass/components/_icons.scss b/assetsIndex/sass/components/_icons.scss new file mode 100644 index 0000000..f096a32 --- /dev/null +++ b/assetsIndex/sass/components/_icons.scss @@ -0,0 +1,40 @@ +/// +/// Dimension by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Icons */ + + ul.icons { + cursor: default; + list-style: none; + padding-left: 0; + + li { + display: inline-block; + padding: 0 0.75em 0 0; + + &:last-child { + padding-right: 0; + } + + a { + border-radius: 100%; + box-shadow: inset 0 0 0 _size(border-width) _palette(border); + display: inline-block; + height: 2.25rem; + line-height: 2.25rem; + text-align: center; + width: 2.25rem; + + &:hover { + background-color: _palette(border-bg); + } + + &:active { + background-color: _palette(border-bg-alt); + } + } + } + } \ No newline at end of file diff --git a/assetsIndex/sass/components/_image.scss b/assetsIndex/sass/components/_image.scss new file mode 100644 index 0000000..9a57d0f --- /dev/null +++ b/assetsIndex/sass/components/_image.scss @@ -0,0 +1,87 @@ +/// +/// Dimension by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Image */ + + .image { + border-radius: _size(border-radius); + border: 0; + display: inline-block; + position: relative; + + &:before { + @include vendor('pointer-events', 'none'); + background-image: url('../../images/overlay.png'); + background-color: _palette(bg-overlay); + border-radius: _size(border-radius); + content: ''; + display: block; + height: 100%; + left: 0; + opacity: 0.5; + position: absolute; + top: 0; + width: 100%; + } + + img { + border-radius: _size(border-radius); + display: block; + } + + &.left, + &.right { + max-width: 40%; + + img { + width: 100%; + } + } + + &.left { + float: left; + padding: 0 1.5em 1em 0; + top: 0.25em; + } + + &.right { + float: right; + padding: 0 0 1em 1.5em; + top: 0.25em; + } + + &.fit { + display: block; + margin: 0 0 _size(element-margin) 0; + width: 100%; + + img { + width: 100%; + } + } + + &.main { + display: block; + margin: (_size(element-margin) * 1.25) 0; + width: 100%; + + img { + width: 100%; + } + } + + @include breakpoint('<=small') { + &.main { + margin: (_size(element-margin) * 1) 0; + } + } + + @include breakpoint('<=xsmall') { + &.main { + margin: (_size(element-margin) * 0.75) 0; + } + } + } \ No newline at end of file diff --git a/assetsIndex/sass/components/_list.scss b/assetsIndex/sass/components/_list.scss new file mode 100644 index 0000000..5d9c364 --- /dev/null +++ b/assetsIndex/sass/components/_list.scss @@ -0,0 +1,56 @@ +/// +/// Dimension by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* List */ + + ol { + list-style: decimal; + margin: 0 0 _size(element-margin) 0; + padding-left: 1.25em; + + li { + padding-left: 0.25em; + } + } + + ul { + list-style: disc; + margin: 0 0 _size(element-margin) 0; + padding-left: 1em; + + li { + padding-left: 0.5em; + } + + &.alt { + list-style: none; + padding-left: 0; + + li { + border-top: solid _size(border-width) _palette(border); + padding: 0.5em 0; + + &:first-child { + border-top: 0; + padding-top: 0; + } + } + } + } + + dl { + margin: 0 0 _size(element-margin) 0; + + dt { + display: block; + font-weight: _font(weight-bold); + margin: 0 0 (_size(element-margin) * 0.5) 0; + } + + dd { + margin-left: _size(element-margin); + } + } \ No newline at end of file diff --git a/assetsIndex/sass/components/_table.scss b/assetsIndex/sass/components/_table.scss new file mode 100644 index 0000000..3fcb5bb --- /dev/null +++ b/assetsIndex/sass/components/_table.scss @@ -0,0 +1,81 @@ +/// +/// Dimension by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Table */ + + .table-wrapper { + -webkit-overflow-scrolling: touch; + overflow-x: auto; + } + + table { + margin: 0 0 _size(element-margin) 0; + width: 100%; + + tbody { + tr { + border: solid _size(border-width) _palette(border); + border-left: 0; + border-right: 0; + + &:nth-child(2n + 1) { + background-color: _palette(border-bg); + } + } + } + + td { + padding: 0.75em 0.75em; + } + + th { + color: _palette(fg-bold); + font-size: 0.9em; + font-weight: _font(weight-bold); + padding: 0 0.75em 0.75em 0.75em; + text-align: left; + } + + thead { + border-bottom: solid (_size(border-width) * 2) _palette(border); + } + + tfoot { + border-top: solid (_size(border-width) * 2) _palette(border); + } + + &.alt { + border-collapse: separate; + + tbody { + tr { + td { + border: solid _size(border-width) _palette(border); + border-left-width: 0; + border-top-width: 0; + + &:first-child { + border-left-width: _size(border-width); + } + } + + &:first-child { + td { + border-top-width: _size(border-width); + } + } + } + } + + thead { + border-bottom: 0; + } + + tfoot { + border-top: 0; + } + } + } \ No newline at end of file diff --git a/assetsIndex/sass/layout/_bg.scss b/assetsIndex/sass/layout/_bg.scss new file mode 100644 index 0000000..218df16 --- /dev/null +++ b/assetsIndex/sass/layout/_bg.scss @@ -0,0 +1,68 @@ +/// +/// Dimension by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* BG */ + + #bg { + @include vendor('transform', 'scale(1.0)'); + -webkit-backface-visibility: hidden; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100vh; + z-index: 1; + + &:before, &:after { + content: ''; + display: block; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + } + + &:before { + @include vendor('transition', 'background-color #{_duration(bg)} ease-in-out'); + @include vendor('transition-delay', '#{_duration(intro)}'); + background-image: linear-gradient(to top, #{_palette(bg-overlay)}, #{_palette(bg-overlay)}), + url('../../images/overlay.png'); + background-size: auto, + 256px 256px; + background-position: center, + center; + background-repeat: no-repeat, + repeat; + z-index: 2; + } + + &:after { + @include vendor('transform', 'scale(1.125)'); + @include vendor('transition', ( + 'transform #{_duration(article)} ease-in-out', + 'filter #{_duration(article)} ease-in-out' + )); + background-image: url('../../images/bg.jpg'); + background-position: center; + background-size: cover; + background-repeat: no-repeat; + z-index: 1; + } + + body.is-article-visible & { + &:after { + @include vendor('transform', 'scale(1.0825)'); + @include vendor('filter', 'blur(0.2rem)'); + } + } + + body.is-preload & { + &:before { + background-color: _palette(bg-alt); + } + } + } \ No newline at end of file diff --git a/assetsIndex/sass/layout/_footer.scss b/assetsIndex/sass/layout/_footer.scss new file mode 100644 index 0000000..e1eda7a --- /dev/null +++ b/assetsIndex/sass/layout/_footer.scss @@ -0,0 +1,37 @@ +/// +/// Dimension by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Footer */ + + #footer { + @include vendor('transition', ( + 'transform #{_duration(article)} ease-in-out', + 'filter #{_duration(article)} ease-in-out', + 'opacity #{_duration(article)} ease-in-out', + )); + width: 100%; + max-width: 100%; + margin-top: 2rem; + text-align: center; + + .copyright { + letter-spacing: _font(letter-spacing); + font-size: 0.6rem; + opacity: 0.75; + margin-bottom: 0; + text-transform: uppercase; + } + + body.is-article-visible & { + @include vendor('transform', 'scale(0.95)'); + @include vendor('filter', 'blur(0.1rem)'); + opacity: 0; + } + + body.is-preload & { + opacity: 0; + } + } \ No newline at end of file diff --git a/assetsIndex/sass/layout/_header.scss b/assetsIndex/sass/layout/_header.scss new file mode 100644 index 0000000..fcfec0a --- /dev/null +++ b/assetsIndex/sass/layout/_header.scss @@ -0,0 +1,261 @@ +/// +/// Dimension by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Header */ + + #header { + @include vendor('display', 'flex'); + @include vendor('flex-direction', 'column'); + @include vendor('align-items', 'center'); + @include vendor('transition', ( + 'transform #{_duration(article)} ease-in-out', + 'filter #{_duration(article)} ease-in-out', + 'opacity #{_duration(article)} ease-in-out', + )); + background-image: -moz-radial-gradient(rgba(0,0,0,0.25) 25%, rgba(0,0,0,0) 55%); + background-image: -webkit-radial-gradient(rgba(0,0,0,0.25) 25%, rgba(0,0,0,0) 55%); + background-image: -ms-radial-gradient(rgba(0,0,0,0.25) 25%, rgba(0,0,0,0) 55%); + background-image: radial-gradient(rgba(0,0,0,0.25) 25%, rgba(0,0,0,0) 55%); + max-width: 100%; + text-align: center; + + > * { + @include vendor('transition', 'opacity #{_duration(article)} ease-in-out'); + position: relative; + margin-top: 3.5rem; + + &:before { + content: ''; + display: block; + position: absolute; + top: calc(-3.5rem - 1px); + left: calc(50% - #{_size(border-width) * 1}); + width: _size(border-width); + height: calc(3.5rem + 1px); + background: _palette(border); + } + } + + > :first-child { + margin-top: 0; + + &:before { + display: none; + } + } + + .logo { + width: 5.5rem; + height: 5.5rem; + line-height: 5.5rem; + border: solid _size(border-width) _palette(border); + border-radius: 100%; + + .icon { + &:before { + font-size: 2rem; + } + } + } + + .content { + border-style: solid; + border-color: _palette(border); + border-top-width: _size(border-width); + border-bottom-width: _size(border-width); + max-width: 100%; + + .inner { + @include vendor('transition', ( + 'max-height #{_duration(intro)} ease', + 'padding #{_duration(intro)} ease', + 'opacity #{_duration(article)} ease-in-out' + )); + @include vendor('transition-delay', '0.25s'); + padding: 3rem 2rem; + max-height: 40rem; + overflow: hidden; + + > :last-child { + margin-bottom: 0; + } + } + + p { + text-transform: uppercase; + letter-spacing: _font(letter-spacing); + font-size: 0.8rem; + line-height: 2; + } + } + + nav { + ul { + @include vendor('display', 'flex'); + margin-bottom: 0; + list-style: none; + padding-left: 0; + border: solid _size(border-width) _palette(border); + border-radius: _size(border-radius); + + li { + padding-left: 0; + border-left: solid _size(border-width) _palette(border); + + &:first-child { + border-left: 0; + } + + a { + display: block; + min-width: 7.5rem; + height: 2.75rem; + line-height: 2.75rem; + padding: 0 1.25rem 0 (1.25rem + _font(letter-spacing)); + text-transform: uppercase; + letter-spacing: _font(letter-spacing); + font-size: 0.8rem; + border-bottom: 0; + + &:hover { + background-color: _palette(border-bg); + } + + &:active { + background-color: _palette(border-bg-alt); + } + } + } + } + + &.use-middle { + &:after { + content: ''; + display: block; + position: absolute; + top: 0; + left: calc(50% - #{_size(border-width) * 1}); + width: _size(border-width); + height: 100%; + background: _palette(border); + } + + ul { + li { + &.is-middle { + border-left: 0; + } + } + } + } + } + + body.is-article-visible & { + @include vendor('transform', 'scale(0.95)'); + @include vendor('filter', 'blur(0.1rem)'); + opacity: 0; + } + + body.is-preload & { + > * { + opacity: 0; + } + + @include vendor('filter', 'blur(0.125rem)'); + + .content { + .inner { + max-height: 0; + padding-top: 0; + padding-bottom: 0; + opacity: 0; + } + } + } + + @include breakpoint('<=medium') { + .content { + p { + br { + display: none; + } + } + } + } + + @include breakpoint('<=small') { + > * { + margin-top: 2rem; + + &:before { + top: calc(-2rem - 1px); + height: calc(2rem + 1px); + } + } + + .logo { + width: 4.75rem; + height: 4.75rem; + line-height: 4.75rem; + + .icon { + &:before { + font-size: 1.75rem; + } + } + } + + .content { + .inner { + padding: 2.5rem 1rem; + } + + p { + line-height: 1.875; + } + } + } + + @include breakpoint('<=xsmall') { + padding: 1.5rem 0; + + .content { + .inner { + padding: 2.5rem 0; + } + } + + nav { + ul { + @include vendor('flex-direction', 'column'); + min-width: 10rem; + max-width: 100%; + + li { + border-left: 0; + border-top: solid _size(border-width) _palette(border); + + &:first-child { + border-top: 0; + } + + a { + height: 3rem; + line-height: 3rem; + min-width: 0; + width: 100%; + } + } + } + + &.use-middle { + &:after { + display: none; + } + } + } + } + } \ No newline at end of file diff --git a/assetsIndex/sass/layout/_main.scss b/assetsIndex/sass/layout/_main.scss new file mode 100644 index 0000000..e41e702 --- /dev/null +++ b/assetsIndex/sass/layout/_main.scss @@ -0,0 +1,102 @@ +/// +/// Dimension by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Main */ + + #main { + @include vendor('flex-grow', '1'); + @include vendor('flex-shrink', '1'); + @include vendor('display', 'flex'); + @include vendor('align-items', 'center'); + @include vendor('justify-content', 'center'); + @include vendor('flex-direction', 'column'); + position: relative; + max-width: 100%; + z-index: 3; + + article { + @include vendor('transform', 'translateY(0.25rem)'); + @include vendor('transition', ( + 'opacity #{_duration(article)} ease-in-out', + 'transform #{_duration(article)} ease-in-out' + )); + @include padding(2.5rem, 2.5rem, (2rem, 0, 1rem, 0)); + position: relative; + width: 40rem; + max-width: 100%; + background-color: transparentize(_palette(bg), 0.15); + border-radius: _size(border-radius); + opacity: 0; + + &.active { + @include vendor('transform', 'translateY(0)'); + opacity: 1; + } + + .close { + display: block; + position: absolute; + top: 0; + right: 0; + width: 4rem; + height: 4rem; + cursor: pointer; + text-indent: 4rem; + overflow: hidden; + white-space: nowrap; + + &:before { + @include vendor('transition', 'background-color #{_duration(transition)} ease-in-out'); + content: ''; + display: block; + position: absolute; + top: 0.75rem; + left: 0.75rem; + width: 2.5rem; + height: 2.5rem; + border-radius: 100%; + background-position: center; + background-image: svg-url(''); + background-size: 20px 20px; + background-repeat: no-repeat; + } + + &:hover { + &:before { + background-color: _palette(border-bg); + } + } + + &:active { + &:before { + background-color: _palette(border-bg-alt); + } + } + } + } + + @include breakpoint('<=small') { + article { + @include padding(2rem, 2rem, (1.5rem, 0, 0.5rem, 0)); + + .close { + &:before { + top: 0.875rem; + left: 0.875rem; + width: 2.25rem; + height: 2.25rem; + background-size: 14px 14px; + } + } + } + } + + @include breakpoint('<=xsmall') { + article { + @include padding(2rem, 1.5rem, (1rem, 0, 0.5rem, 0)); + } + } + } \ No newline at end of file diff --git a/assetsIndex/sass/layout/_wrapper.scss b/assetsIndex/sass/layout/_wrapper.scss new file mode 100644 index 0000000..352ceea --- /dev/null +++ b/assetsIndex/sass/layout/_wrapper.scss @@ -0,0 +1,36 @@ +/// +/// Dimension by HTML5 UP +/// html5up.net | @ajlkn +/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +/// + +/* Wrapper */ + + #wrapper { + @include vendor('display', 'flex'); + @include vendor('flex-direction', 'column'); + @include vendor('align-items', 'center'); + @include vendor('justify-content', 'space-between'); + position: relative; + min-height: 100vh; + width: 100%; + padding: 4rem 2rem; + z-index: 3; + + &:before { + content: ''; + display: block; + } + + @include breakpoint('<=xlarge') { + padding: 3rem 2rem; + } + + @include breakpoint('<=small') { + padding: 2rem 1rem; + } + + @include breakpoint('<=xsmall') { + padding: 1rem; + } + } \ No newline at end of file diff --git a/assetsIndex/sass/libs/_breakpoints.scss b/assetsIndex/sass/libs/_breakpoints.scss new file mode 100644 index 0000000..c5301d8 --- /dev/null +++ b/assetsIndex/sass/libs/_breakpoints.scss @@ -0,0 +1,223 @@ +// breakpoints.scss v1.0 | @ajlkn | MIT licensed */ + +// Vars. + + /// Breakpoints. + /// @var {list} + $breakpoints: () !global; + +// Mixins. + + /// Sets breakpoints. + /// @param {map} $x Breakpoints. + @mixin breakpoints($x: ()) { + $breakpoints: $x !global; + } + + /// Wraps @content in a @media block targeting a specific orientation. + /// @param {string} $orientation Orientation. + @mixin orientation($orientation) { + @media screen and (orientation: #{$orientation}) { + @content; + } + } + + /// Wraps @content in a @media block using a given query. + /// @param {string} $query Query. + @mixin breakpoint($query: null) { + + $breakpoint: null; + $op: null; + $media: null; + + // Determine operator, breakpoint. + + // Greater than or equal. + @if (str-slice($query, 0, 2) == '>=') { + + $op: 'gte'; + $breakpoint: str-slice($query, 3); + + } + + // Less than or equal. + @elseif (str-slice($query, 0, 2) == '<=') { + + $op: 'lte'; + $breakpoint: str-slice($query, 3); + + } + + // Greater than. + @elseif (str-slice($query, 0, 1) == '>') { + + $op: 'gt'; + $breakpoint: str-slice($query, 2); + + } + + // Less than. + @elseif (str-slice($query, 0, 1) == '<') { + + $op: 'lt'; + $breakpoint: str-slice($query, 2); + + } + + // Not. + @elseif (str-slice($query, 0, 1) == '!') { + + $op: 'not'; + $breakpoint: str-slice($query, 2); + + } + + // Equal. + @else { + + $op: 'eq'; + $breakpoint: $query; + + } + + // Build media. + @if ($breakpoint and map-has-key($breakpoints, $breakpoint)) { + + $a: map-get($breakpoints, $breakpoint); + + // Range. + @if (type-of($a) == 'list') { + + $x: nth($a, 1); + $y: nth($a, 2); + + // Max only. + @if ($x == null) { + + // Greater than or equal (>= 0 / anything) + @if ($op == 'gte') { + $media: 'screen'; + } + + // Less than or equal (<= y) + @elseif ($op == 'lte') { + $media: 'screen and (max-width: ' + $y + ')'; + } + + // Greater than (> y) + @elseif ($op == 'gt') { + $media: 'screen and (min-width: ' + ($y + 1) + ')'; + } + + // Less than (< 0 / invalid) + @elseif ($op == 'lt') { + $media: 'screen and (max-width: -1px)'; + } + + // Not (> y) + @elseif ($op == 'not') { + $media: 'screen and (min-width: ' + ($y + 1) + ')'; + } + + // Equal (<= y) + @else { + $media: 'screen and (max-width: ' + $y + ')'; + } + + } + + // Min only. + @else if ($y == null) { + + // Greater than or equal (>= x) + @if ($op == 'gte') { + $media: 'screen and (min-width: ' + $x + ')'; + } + + // Less than or equal (<= inf / anything) + @elseif ($op == 'lte') { + $media: 'screen'; + } + + // Greater than (> inf / invalid) + @elseif ($op == 'gt') { + $media: 'screen and (max-width: -1px)'; + } + + // Less than (< x) + @elseif ($op == 'lt') { + $media: 'screen and (max-width: ' + ($x - 1) + ')'; + } + + // Not (< x) + @elseif ($op == 'not') { + $media: 'screen and (max-width: ' + ($x - 1) + ')'; + } + + // Equal (>= x) + @else { + $media: 'screen and (min-width: ' + $x + ')'; + } + + } + + // Min and max. + @else { + + // Greater than or equal (>= x) + @if ($op == 'gte') { + $media: 'screen and (min-width: ' + $x + ')'; + } + + // Less than or equal (<= y) + @elseif ($op == 'lte') { + $media: 'screen and (max-width: ' + $y + ')'; + } + + // Greater than (> y) + @elseif ($op == 'gt') { + $media: 'screen and (min-width: ' + ($y + 1) + ')'; + } + + // Less than (< x) + @elseif ($op == 'lt') { + $media: 'screen and (max-width: ' + ($x - 1) + ')'; + } + + // Not (< x and > y) + @elseif ($op == 'not') { + $media: 'screen and (max-width: ' + ($x - 1) + '), screen and (min-width: ' + ($y + 1) + ')'; + } + + // Equal (>= x and <= y) + @else { + $media: 'screen and (min-width: ' + $x + ') and (max-width: ' + $y + ')'; + } + + } + + } + + // String. + @else { + + // Missing a media type? Prefix with "screen". + @if (str-slice($a, 0, 1) == '(') { + $media: 'screen and ' + $a; + } + + // Otherwise, use as-is. + @else { + $media: $a; + } + + } + + } + + // Output. + @media #{$media} { + @content; + } + + } \ No newline at end of file diff --git a/assetsIndex/sass/libs/_functions.scss b/assetsIndex/sass/libs/_functions.scss new file mode 100644 index 0000000..b367524 --- /dev/null +++ b/assetsIndex/sass/libs/_functions.scss @@ -0,0 +1,90 @@ +/// Removes a specific item from a list. +/// @author Hugo Giraudel +/// @param {list} $list List. +/// @param {integer} $index Index. +/// @return {list} Updated list. +@function remove-nth($list, $index) { + + $result: null; + + @if type-of($index) != number { + @warn "$index: #{quote($index)} is not a number for `remove-nth`."; + } + @else if $index == 0 { + @warn "List index 0 must be a non-zero integer for `remove-nth`."; + } + @else if abs($index) > length($list) { + @warn "List index is #{$index} but list is only #{length($list)} item long for `remove-nth`."; + } + @else { + + $result: (); + $index: if($index < 0, length($list) + $index + 1, $index); + + @for $i from 1 through length($list) { + + @if $i != $index { + $result: append($result, nth($list, $i)); + } + + } + + } + + @return $result; + +} + +/// Gets a value from a map. +/// @author Hugo Giraudel +/// @param {map} $map Map. +/// @param {string} $keys Key(s). +/// @return {string} Value. +@function val($map, $keys...) { + + @if nth($keys, 1) == null { + $keys: remove-nth($keys, 1); + } + + @each $key in $keys { + $map: map-get($map, $key); + } + + @return $map; + +} + +/// Gets a duration value. +/// @param {string} $keys Key(s). +/// @return {string} Value. +@function _duration($keys...) { + @return val($duration, $keys...); +} + +/// Gets a font value. +/// @param {string} $keys Key(s). +/// @return {string} Value. +@function _font($keys...) { + @return val($font, $keys...); +} + +/// Gets a misc value. +/// @param {string} $keys Key(s). +/// @return {string} Value. +@function _misc($keys...) { + @return val($misc, $keys...); +} + +/// Gets a palette value. +/// @param {string} $keys Key(s). +/// @return {string} Value. +@function _palette($keys...) { + @return val($palette, $keys...); +} + +/// Gets a size value. +/// @param {string} $keys Key(s). +/// @return {string} Value. +@function _size($keys...) { + @return val($size, $keys...); +} \ No newline at end of file diff --git a/assetsIndex/sass/libs/_mixins.scss b/assetsIndex/sass/libs/_mixins.scss new file mode 100644 index 0000000..8187463 --- /dev/null +++ b/assetsIndex/sass/libs/_mixins.scss @@ -0,0 +1,78 @@ +/// Makes an element's :before pseudoelement a FontAwesome icon. +/// @param {string} $content Optional content value to use. +/// @param {string} $category Optional category to use. +/// @param {string} $where Optional pseudoelement to target (before or after). +@mixin icon($content: false, $category: regular, $where: before) { + + text-decoration: none; + + &:#{$where} { + + @if $content { + content: $content; + } + + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + display: inline-block; + font-style: normal; + font-variant: normal; + text-rendering: auto; + line-height: 1; + text-transform: none !important; + + @if ($category == brands) { + font-family: 'Font Awesome 5 Brands'; + } + @elseif ($category == solid) { + font-family: 'Font Awesome 5 Free'; + font-weight: 900; + } + @else { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; + } + + } + +} + +/// Applies padding to an element, taking the current element-margin value into account. +/// @param {mixed} $tb Top/bottom padding. +/// @param {mixed} $lr Left/right padding. +/// @param {list} $pad Optional extra padding (in the following order top, right, bottom, left) +/// @param {bool} $important If true, adds !important. +@mixin padding($tb, $lr, $pad: (0,0,0,0), $important: null) { + + @if $important { + $important: '!important'; + } + + $x: 0.1em; + + @if unit(_size(element-margin)) == 'rem' { + $x: 0.1rem; + } + + padding: ($tb + nth($pad,1)) ($lr + nth($pad,2)) max($x, $tb - _size(element-margin) + nth($pad,3)) ($lr + nth($pad,4)) #{$important}; + +} + +/// Encodes a SVG data URL so IE doesn't choke (via codepen.io/jakob-e/pen/YXXBrp). +/// @param {string} $svg SVG data URL. +/// @return {string} Encoded SVG data URL. +@function svg-url($svg) { + + $svg: str-replace($svg, '"', '\''); + $svg: str-replace($svg, '%', '%25'); + $svg: str-replace($svg, '<', '%3C'); + $svg: str-replace($svg, '>', '%3E'); + $svg: str-replace($svg, '&', '%26'); + $svg: str-replace($svg, '#', '%23'); + $svg: str-replace($svg, '{', '%7B'); + $svg: str-replace($svg, '}', '%7D'); + $svg: str-replace($svg, ';', '%3B'); + + @return url("data:image/svg+xml;charset=utf8,#{$svg}"); + +} \ No newline at end of file diff --git a/assetsIndex/sass/libs/_vars.scss b/assetsIndex/sass/libs/_vars.scss new file mode 100644 index 0000000..ba1d849 --- /dev/null +++ b/assetsIndex/sass/libs/_vars.scss @@ -0,0 +1,43 @@ +// Misc. + $misc: ( + z-index-base: 10000 + ); + +// Duration. + $duration: ( + transition: 0.2s, + bg: 2.5s, + intro: 0.75s, + article: 0.325s + ); + +// Size. + $size: ( + border-radius: 4px, + border-width: 1px, + element-height: 2.75rem, + element-margin: 2rem + ); + +// Font. + $font: ( + family: ('Source Sans Pro', sans-serif), + family-fixed: ('Courier New', monospace), + weight: 300, + weight-bold: 600, + letter-spacing: 0.2rem, + letter-spacing-heading: 0.5rem + ); + +// Palette. + $palette: ( + bg: #1b1f22, + bg-alt: #000000, + bg-overlay: rgba(19,21,25,0.5), + fg: #ffffff, + fg-bold: #ffffff, + fg-light: rgba(255,255,255,0.5), + border: #ffffff, + border-bg: rgba(255,255,255,0.075), + border-bg-alt: rgba(255,255,255,0.175) + ); \ No newline at end of file diff --git a/assetsIndex/sass/libs/_vendor.scss b/assetsIndex/sass/libs/_vendor.scss new file mode 100644 index 0000000..6599a3f --- /dev/null +++ b/assetsIndex/sass/libs/_vendor.scss @@ -0,0 +1,376 @@ +// vendor.scss v1.0 | @ajlkn | MIT licensed */ + +// Vars. + + /// Vendor prefixes. + /// @var {list} + $vendor-prefixes: ( + '-moz-', + '-webkit-', + '-ms-', + '' + ); + + /// Properties that should be vendorized. + /// Data via caniuse.com, github.com/postcss/autoprefixer, and developer.mozilla.org + /// @var {list} + $vendor-properties: ( + + // Animation. + 'animation', + 'animation-delay', + 'animation-direction', + 'animation-duration', + 'animation-fill-mode', + 'animation-iteration-count', + 'animation-name', + 'animation-play-state', + 'animation-timing-function', + + // Appearance. + 'appearance', + + // Backdrop filter. + 'backdrop-filter', + + // Background image options. + 'background-clip', + 'background-origin', + 'background-size', + + // Box sizing. + 'box-sizing', + + // Clip path. + 'clip-path', + + // Filter effects. + 'filter', + + // Flexbox. + 'align-content', + 'align-items', + 'align-self', + 'flex', + 'flex-basis', + 'flex-direction', + 'flex-flow', + 'flex-grow', + 'flex-shrink', + 'flex-wrap', + 'justify-content', + 'order', + + // Font feature. + 'font-feature-settings', + 'font-language-override', + 'font-variant-ligatures', + + // Font kerning. + 'font-kerning', + + // Fragmented borders and backgrounds. + 'box-decoration-break', + + // Grid layout. + 'grid-column', + 'grid-column-align', + 'grid-column-end', + 'grid-column-start', + 'grid-row', + 'grid-row-align', + 'grid-row-end', + 'grid-row-start', + 'grid-template-columns', + 'grid-template-rows', + + // Hyphens. + 'hyphens', + 'word-break', + + // Masks. + 'mask', + 'mask-border', + 'mask-border-outset', + 'mask-border-repeat', + 'mask-border-slice', + 'mask-border-source', + 'mask-border-width', + 'mask-clip', + 'mask-composite', + 'mask-image', + 'mask-origin', + 'mask-position', + 'mask-repeat', + 'mask-size', + + // Multicolumn. + 'break-after', + 'break-before', + 'break-inside', + 'column-count', + 'column-fill', + 'column-gap', + 'column-rule', + 'column-rule-color', + 'column-rule-style', + 'column-rule-width', + 'column-span', + 'column-width', + 'columns', + + // Object fit. + 'object-fit', + 'object-position', + + // Regions. + 'flow-from', + 'flow-into', + 'region-fragment', + + // Scroll snap points. + 'scroll-snap-coordinate', + 'scroll-snap-destination', + 'scroll-snap-points-x', + 'scroll-snap-points-y', + 'scroll-snap-type', + + // Shapes. + 'shape-image-threshold', + 'shape-margin', + 'shape-outside', + + // Tab size. + 'tab-size', + + // Text align last. + 'text-align-last', + + // Text decoration. + 'text-decoration-color', + 'text-decoration-line', + 'text-decoration-skip', + 'text-decoration-style', + + // Text emphasis. + 'text-emphasis', + 'text-emphasis-color', + 'text-emphasis-position', + 'text-emphasis-style', + + // Text size adjust. + 'text-size-adjust', + + // Text spacing. + 'text-spacing', + + // Transform. + 'transform', + 'transform-origin', + + // Transform 3D. + 'backface-visibility', + 'perspective', + 'perspective-origin', + 'transform-style', + + // Transition. + 'transition', + 'transition-delay', + 'transition-duration', + 'transition-property', + 'transition-timing-function', + + // Unicode bidi. + 'unicode-bidi', + + // User select. + 'user-select', + + // Writing mode. + 'writing-mode', + + ); + + /// Values that should be vendorized. + /// Data via caniuse.com, github.com/postcss/autoprefixer, and developer.mozilla.org + /// @var {list} + $vendor-values: ( + + // Cross fade. + 'cross-fade', + + // Element function. + 'element', + + // Filter function. + 'filter', + + // Flexbox. + 'flex', + 'inline-flex', + + // Grab cursors. + 'grab', + 'grabbing', + + // Gradients. + 'linear-gradient', + 'repeating-linear-gradient', + 'radial-gradient', + 'repeating-radial-gradient', + + // Grid layout. + 'grid', + 'inline-grid', + + // Image set. + 'image-set', + + // Intrinsic width. + 'max-content', + 'min-content', + 'fit-content', + 'fill', + 'fill-available', + 'stretch', + + // Sticky position. + 'sticky', + + // Transform. + 'transform', + + // Zoom cursors. + 'zoom-in', + 'zoom-out', + + ); + +// Functions. + + /// Removes a specific item from a list. + /// @author Hugo Giraudel + /// @param {list} $list List. + /// @param {integer} $index Index. + /// @return {list} Updated list. + @function remove-nth($list, $index) { + + $result: null; + + @if type-of($index) != number { + @warn "$index: #{quote($index)} is not a number for `remove-nth`."; + } + @else if $index == 0 { + @warn "List index 0 must be a non-zero integer for `remove-nth`."; + } + @else if abs($index) > length($list) { + @warn "List index is #{$index} but list is only #{length($list)} item long for `remove-nth`."; + } + @else { + + $result: (); + $index: if($index < 0, length($list) + $index + 1, $index); + + @for $i from 1 through length($list) { + + @if $i != $index { + $result: append($result, nth($list, $i)); + } + + } + + } + + @return $result; + + } + + /// Replaces a substring within another string. + /// @author Hugo Giraudel + /// @param {string} $string String. + /// @param {string} $search Substring. + /// @param {string} $replace Replacement. + /// @return {string} Updated string. + @function str-replace($string, $search, $replace: '') { + + $index: str-index($string, $search); + + @if $index { + @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace); + } + + @return $string; + + } + + /// Replaces a substring within each string in a list. + /// @param {list} $strings List of strings. + /// @param {string} $search Substring. + /// @param {string} $replace Replacement. + /// @return {list} Updated list of strings. + @function str-replace-all($strings, $search, $replace: '') { + + @each $string in $strings { + $strings: set-nth($strings, index($strings, $string), str-replace($string, $search, $replace)); + } + + @return $strings; + + } + +// Mixins. + + /// Wraps @content in vendorized keyframe blocks. + /// @param {string} $name Name. + @mixin keyframes($name) { + + @-moz-keyframes #{$name} { @content; } + @-webkit-keyframes #{$name} { @content; } + @-ms-keyframes #{$name} { @content; } + @keyframes #{$name} { @content; } + + } + + /// Vendorizes a declaration's property and/or value(s). + /// @param {string} $property Property. + /// @param {mixed} $value String/list of value(s). + @mixin vendor($property, $value) { + + // Determine if property should expand. + $expandProperty: index($vendor-properties, $property); + + // Determine if value should expand (and if so, add '-prefix-' placeholder). + $expandValue: false; + + @each $x in $value { + @each $y in $vendor-values { + @if $y == str-slice($x, 1, str-length($y)) { + + $value: set-nth($value, index($value, $x), '-prefix-' + $x); + $expandValue: true; + + } + } + } + + // Expand property? + @if $expandProperty { + @each $vendor in $vendor-prefixes { + #{$vendor}#{$property}: #{str-replace-all($value, '-prefix-', $vendor)}; + } + } + + // Expand just the value? + @elseif $expandValue { + @each $vendor in $vendor-prefixes { + #{$property}: #{str-replace-all($value, '-prefix-', $vendor)}; + } + } + + // Neither? Treat them as a normal declaration. + @else { + #{$property}: #{$value}; + } + + } \ No newline at end of file diff --git a/assetsIndex/sass/main.scss b/assetsIndex/sass/main.scss new file mode 100644 index 0000000..f98ebef --- /dev/null +++ b/assetsIndex/sass/main.scss @@ -0,0 +1,50 @@ +@import 'libs/vars'; +@import 'libs/functions'; +@import 'libs/mixins'; +@import 'libs/vendor'; +@import 'libs/breakpoints'; +@import 'fontawesome-all.min.css'; +@import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro:300italic,600italic,300,600'); + +/* + Dimension by HTML5 UP + html5up.net | @ajlkn + Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +*/ + +// Breakpoints. + + @include breakpoints(( + xlarge: ( 1281px, 1680px ), + large: ( 981px, 1280px ), + medium: ( 737px, 980px ), + small: ( 481px, 736px ), + xsmall: ( 361px, 480px ), + xxsmall: ( null, 360px ) + )); + +// Base. + + @import 'base/reset'; + @import 'base/page'; + @import 'base/typography'; + +// Component. + + @import 'components/form'; + @import 'components/box'; + @import 'components/icon'; + @import 'components/image'; + @import 'components/list'; + @import 'components/actions'; + @import 'components/icons'; + @import 'components/table'; + @import 'components/button'; + +// Layout. + + @import 'layout/bg'; + @import 'layout/wrapper'; + @import 'layout/header'; + @import 'layout/main'; + @import 'layout/footer'; \ No newline at end of file diff --git a/assetsIndex/sass/noscript.scss b/assetsIndex/sass/noscript.scss new file mode 100644 index 0000000..dbff806 --- /dev/null +++ b/assetsIndex/sass/noscript.scss @@ -0,0 +1,50 @@ +@import 'libs/vars'; +@import 'libs/functions'; +@import 'libs/mixins'; +@import 'libs/vendor'; +@import 'libs/breakpoints'; + +/* + Dimension by HTML5 UP + html5up.net | @ajlkn + Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +*/ + +/* BG */ + + #bg { + body.is-preload & { + &:before { + background-color: transparent; + } + } + } + +/* Header */ + + #header { + body.is-preload & { + > * { + opacity: 1; + } + + @include vendor('filter', 'none'); + + .content { + .inner { + max-height: none; + padding: 3rem 2rem; + opacity: 1; + } + } + } + } + +/* Main */ + + #main { + article { + opacity: 1; + margin: (_size(element-margin) * 2) 0 0 0; + } + } \ No newline at end of file diff --git a/assetsIndex/webfonts/fa-brands-400.eot b/assetsIndex/webfonts/fa-brands-400.eot new file mode 100644 index 0000000..cba6c6c Binary files /dev/null and b/assetsIndex/webfonts/fa-brands-400.eot differ diff --git a/assetsIndex/webfonts/fa-brands-400.svg b/assetsIndex/webfonts/fa-brands-400.svg new file mode 100644 index 0000000..b9881a4 --- /dev/null +++ b/assetsIndex/webfonts/fa-brands-400.svg @@ -0,0 +1,3717 @@ + + + + +Created by FontForge 20201107 at Wed Aug 4 12:25:29 2021 + By Robert Madole +Copyright (c) Font Awesome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assetsIndex/webfonts/fa-brands-400.ttf b/assetsIndex/webfonts/fa-brands-400.ttf new file mode 100644 index 0000000..8d75ded Binary files /dev/null and b/assetsIndex/webfonts/fa-brands-400.ttf differ diff --git a/assetsIndex/webfonts/fa-brands-400.woff b/assetsIndex/webfonts/fa-brands-400.woff new file mode 100644 index 0000000..3375bef Binary files /dev/null and b/assetsIndex/webfonts/fa-brands-400.woff differ diff --git a/assetsIndex/webfonts/fa-brands-400.woff2 b/assetsIndex/webfonts/fa-brands-400.woff2 new file mode 100644 index 0000000..402f81c Binary files /dev/null and b/assetsIndex/webfonts/fa-brands-400.woff2 differ diff --git a/assetsIndex/webfonts/fa-regular-400.eot b/assetsIndex/webfonts/fa-regular-400.eot new file mode 100644 index 0000000..a4e5989 Binary files /dev/null and b/assetsIndex/webfonts/fa-regular-400.eot differ diff --git a/assetsIndex/webfonts/fa-regular-400.svg b/assetsIndex/webfonts/fa-regular-400.svg new file mode 100644 index 0000000..463af27 --- /dev/null +++ b/assetsIndex/webfonts/fa-regular-400.svg @@ -0,0 +1,801 @@ + + + + +Created by FontForge 20201107 at Wed Aug 4 12:25:29 2021 + By Robert Madole +Copyright (c) Font Awesome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assetsIndex/webfonts/fa-regular-400.ttf b/assetsIndex/webfonts/fa-regular-400.ttf new file mode 100644 index 0000000..7157aaf Binary files /dev/null and b/assetsIndex/webfonts/fa-regular-400.ttf differ diff --git a/assetsIndex/webfonts/fa-regular-400.woff b/assetsIndex/webfonts/fa-regular-400.woff new file mode 100644 index 0000000..ad077c6 Binary files /dev/null and b/assetsIndex/webfonts/fa-regular-400.woff differ diff --git a/assetsIndex/webfonts/fa-regular-400.woff2 b/assetsIndex/webfonts/fa-regular-400.woff2 new file mode 100644 index 0000000..5632894 Binary files /dev/null and b/assetsIndex/webfonts/fa-regular-400.woff2 differ diff --git a/assetsIndex/webfonts/fa-solid-900.eot b/assetsIndex/webfonts/fa-solid-900.eot new file mode 100644 index 0000000..e994171 Binary files /dev/null and b/assetsIndex/webfonts/fa-solid-900.eot differ diff --git a/assetsIndex/webfonts/fa-solid-900.svg b/assetsIndex/webfonts/fa-solid-900.svg new file mode 100644 index 0000000..00296e9 --- /dev/null +++ b/assetsIndex/webfonts/fa-solid-900.svg @@ -0,0 +1,5034 @@ + + + + +Created by FontForge 20201107 at Wed Aug 4 12:25:29 2021 + By Robert Madole +Copyright (c) Font Awesome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assetsIndex/webfonts/fa-solid-900.ttf b/assetsIndex/webfonts/fa-solid-900.ttf new file mode 100644 index 0000000..25abf38 Binary files /dev/null and b/assetsIndex/webfonts/fa-solid-900.ttf differ diff --git a/assetsIndex/webfonts/fa-solid-900.woff b/assetsIndex/webfonts/fa-solid-900.woff new file mode 100644 index 0000000..23ee663 Binary files /dev/null and b/assetsIndex/webfonts/fa-solid-900.woff differ diff --git a/assetsIndex/webfonts/fa-solid-900.woff2 b/assetsIndex/webfonts/fa-solid-900.woff2 new file mode 100644 index 0000000..2217164 Binary files /dev/null and b/assetsIndex/webfonts/fa-solid-900.woff2 differ diff --git a/cabecera.php b/cabecera.php new file mode 100644 index 0000000..c85886b --- /dev/null +++ b/cabecera.php @@ -0,0 +1,165 @@ + +
+ + + + + + +
+ + + + + + \ No newline at end of file diff --git a/clases/claseApiJuego.php b/clases/claseApiJuego.php new file mode 100644 index 0000000..9b5ee93 --- /dev/null +++ b/clases/claseApiJuego.php @@ -0,0 +1,418 @@ +clientId = $_ENV['clientIdIGDB']; + $this->clientSecret = $_ENV['clientSecretIGDB']; + $this->accessToken = null; + } // Fin __construct() + + private function obtenerToken(){ + + // Comprobamos si tenemos un token guardado en sesión y si todavía no ha caducado. + if(isset($_SESSION['igdb_access_token']) && isset($_SESSION['igdb_token_expira']) && time() < $_SESSION['igdb_token_expira']){ + + $this->accessToken = $_SESSION['igdb_access_token']; + + return true; + } + + // No tenemos token o ha caducado. Pedimos uno nuevo a Twitch. + + $curl = curl_init(); + + curl_setopt($curl, CURLOPT_URL, 'https://id.twitch.tv/oauth2/token'); + curl_setopt($curl, CURLOPT_POST, true); + curl_setopt($curl,CURLOPT_RETURNTRANSFER,true); + curl_setopt($curl, CURLOPT_POSTFIELDS, + [ + 'client_id' => $this->clientId, + 'client_secret' => $this->clientSecret, + 'grant_type' => 'client_credentials' + ] + ); + + $respuesta = curl_exec($curl); + + if(curl_errno($curl)){ + + $error = curl_error($curl); + + curl_close($curl); + + return [ + 'error' => 'No se pudo obtener el token de IGDB.', + 'error_tecnico' => $error + ]; + } + + $codigoHTTP = curl_getinfo($curl, CURLINFO_HTTP_CODE); + + curl_close($curl); + + $resultado = json_decode( + $respuesta, + true + ); + + if($codigoHTTP < 200 || $codigoHTTP >= 300 || isset($resultado['error'])){ + + return [ + 'error' => 'No se pudo obtener el token de IGDB.', + 'error_tecnico' => $resultado + ]; + } + + // Guardamos el token en la sesión. + + $this->accessToken = $resultado['access_token']; + + $_SESSION['igdb_access_token'] = $resultado['access_token']; + + // Dejamos un margen de 60 segundos antes de considerar que el token ha caducado. + + $_SESSION['igdb_token_expira'] = time() + $resultado['expires_in'] - 60; + + return true; + } // Fin obtenerToken() + + private function peticion($endpoint, $consulta){ + + // Si no tenemos token, lo obtenemos + if($this->accessToken === null){ + + $resultado = $this->obtenerToken(); + + if(is_array($resultado)){ + return $resultado; + } + } + + + $curl = curl_init(); + + curl_setopt($curl, CURLOPT_URL, 'https://api.igdb.com/v4/'.$endpoint); + curl_setopt($curl, CURLOPT_POST, true); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + + curl_setopt($curl, CURLOPT_POSTFIELDS, $consulta); + + curl_setopt($curl, CURLOPT_HTTPHEADER, + [ + 'Client-ID: '.$this->clientId, + 'Authorization: Bearer '.$this->accessToken, + 'Content-Type: text/plain' + ] + ); + + $respuesta = curl_exec($curl); + + $codigoHTTP = curl_getinfo($curl, CURLINFO_HTTP_CODE); + + if(curl_errno($curl)){ + + $error = curl_error($curl); + + curl_close($curl); + + return [ + 'error' => $error + ]; + } + + curl_close($curl); + + // Si el token ha caducado o ha quedado invalidado, obtenemos otro + if($codigoHTTP == 401){ + + // Eliminamos el token almacenado. + unset($_SESSION['igdb_access_token']); + unset($_SESSION['igdb_token_expira']); + + $this->accessToken = null; + + // Obtenemos uno nuevo. + $resultado = $this->obtenerToken(); + + if(is_array($resultado)){ + return $resultado; + } + + // Reintentamos la misma petición. + return $this->peticion( + $endpoint, + $consulta + ); + } + + + $resultado = json_decode($respuesta, true); + + if($codigoHTTP < 200 || $codigoHTTP >= 300){ + + return [ + 'error' => 'IGDB devolvió un error.', + 'error_tecnico' => $resultado + ]; + } + + return $resultado; + + } // Fin peticion() + + public function buscar($nombre){ + + $nombre = addslashes($nombre); + + $consulta = ' + fields id,name,first_release_date,cover.image_id; + search "'.$nombre.'"; + limit 16; + '; + + $respuesta = $this->peticion('games', $consulta); + + return $respuesta; + } // Fin buscar() + + public function detalles($idApi){ + + $consulta = ' + fields + id, + name, + summary, + first_release_date, + cover.image_id, + rating, + genres.name, + platforms.name, + franchises.name, + expansions.name, + dlcs.name, + involved_companies.company.name, + involved_companies.developer, + involved_companies.publisher; + where id = '.$idApi.'; + '; + + $respuesta = $this->peticion('games', $consulta); + + if(isset($respuesta['error'])){ + return $respuesta; + } + + if(empty($respuesta)){ + return [ + 'error' => 'No se encontró el videojuego solicitado.' + ]; + } + + $juego = $respuesta[0]; + + // Duración estimada + $consultaDuracion = 'fields normally,hastily,completely; where game_id = '.$idApi.';'; + $duracion = $this->peticion('game_time_to_beats', $consultaDuracion); + + if(!isset($duracion['error']) && !empty($duracion)){ + $juego['time_to_beat'] = $duracion[0]; + } + + return $juego; + + } // Fin detalles() + + public function transformarDatos($resultado){ + + $juego = []; + + $juego['idApi'] = $resultado['id']; + + $juego['nombreJuego'] = $resultado['name']; + + if(isset($resultado['first_release_date'])){ + + $juego['anoJuego'] = date('Y', $resultado['first_release_date']); + + }else{ + $juego['anoJuego'] = ''; + } + + if(isset($resultado['rating'])){ + + $juego['ratingAvgJuego'] = number_format($resultado['rating'] / 20, 2); + }else{ + $juego['ratingAvgJuego'] = null; + } + + $juego['sinopsisJuego'] = $resultado['summary'] ?? ''; + + + // Poster + if(isset($resultado['cover']['image_id']) && !empty($resultado['cover']['image_id']) + ){ + $imageId = $resultado['cover']['image_id']; + $juego['posterJuego'] = 'https://images.igdb.com/igdb/image/upload/t_cover_big_2x/'.$imageId.'.jpg'; + + }else{ + $juego['posterJuego'] = ''; + } + + + // Géneros + $generos = []; + + if(isset($resultado['genres'])){ + + foreach($resultado['genres'] as $genero){ + + if(isset($genero['name'])){ + $generos[] = $genero['name']; + } + } + } + + $juego['generoJuego'] = implode(', ', $generos); + + + // Plataformas + $plataformas = []; + + if(isset($resultado['platforms'])){ + + foreach($resultado['platforms'] as $plataforma){ + + if(isset($plataforma['name'])){ + + $nombrePlataforma = $plataforma['name']; + + if($nombrePlataforma === 'PC (Microsoft Windows)'){ + $nombrePlataforma = 'PC'; + } + + $plataformas[] = $nombrePlataforma; + } + } + } + + $juego['plataformasJuego'] = implode(', ', $plataformas); + + // Metemos las plataformas como array, para usarlas en el select + $juego['opcionesPlataformasJuego'] = $plataformas; + + + // Desarrolladores y editores + $desarrolladores = []; + $editores = []; + + if(isset($resultado['involved_companies'])){ + + foreach($resultado['involved_companies'] as $empresa){ + + if( + !isset($empresa['company']) || + !isset($empresa['company']['name']) + ){ + continue; + } + + $nombreEmpresa = $empresa['company']['name']; + + if( + isset($empresa['developer']) && + $empresa['developer'] === true + ){ + $desarrolladores[] = $nombreEmpresa; + } + + if( + isset($empresa['publisher']) && + $empresa['publisher'] === true + ){ + $editores[] = $nombreEmpresa; + } + } + } + + $juego['desarrolladorJuego'] = implode(', ', array_unique($desarrolladores)); + + $juego['editorJuego'] = implode(', ', array_unique($editores)); + + + // Franquicias + $franquicias = []; + + if(isset($resultado['franchises'])){ + + foreach($resultado['franchises'] as $franquicia){ + + if(isset($franquicia['name'])){ + $franquicias[] = $franquicia['name']; + } + } + } + + $juego['franquiciaJuego'] = implode(', ', array_unique($franquicias)); + + + // Expansiones + $expansiones = []; + + if(isset($resultado['expansions'])){ + + foreach($resultado['expansions'] as $expansion){ + + if(isset($expansion['name'])){ + $expansiones[] = $expansion['name']; + } + } + } + + $juego['expansionJuego'] = implode(', ', array_unique($expansiones)); + + + // DLCs + $dlcs = []; + + if(isset($resultado['dlcs'])){ + + foreach($resultado['dlcs'] as $dlc){ + + if(isset($dlc['name'])){ + $dlcs[] = $dlc['name']; + } + } + } + + $juego['dlcJuego'] = implode(', ', array_unique($dlcs)); + + // Duración estimada + if( + isset($resultado['time_to_beat']) && + isset($resultado['time_to_beat']['normally']) + ){ + $horas = $resultado['time_to_beat']['normally'] / 3600; + + $juego['duracionJuego'] = round($horas, 1).' h'; + }else{ + $juego['duracionJuego'] = ''; + } + + + return $juego; + } // Fin transformarDatos() + +} // Fin clase ApiJuego + + + +?> \ No newline at end of file diff --git a/clases/claseApiLibro.php b/clases/claseApiLibro.php new file mode 100644 index 0000000..8bb2cb9 --- /dev/null +++ b/clases/claseApiLibro.php @@ -0,0 +1,592 @@ + 'No se pudo realizar la petición a Open Library.', + 'error_tecnico' => $error + ]; + } + + curl_close($curl); + + $resultado = json_decode($respuesta, true); + + if($codigoHTTP < 200 || $codigoHTTP >= 300){ + return [ + 'error' => 'Open Library devolvió un error.', + 'error_tecnico' => $resultado + ]; + } + + return $resultado; + } // Fin peticion() + + public function buscar($nombre){ + + $nombre = urlencode($nombre); + + $url = 'https://openlibrary.org/search.json' + . '?title='.$nombre + . '&fields=' + . 'key,' + . 'title,' + . 'author_name,' + . 'first_publish_year,' + . 'cover_i' + . '&limit=10'; + + $resultado = $this->peticion($url); + + if(isset($resultado['error'])){ + return $resultado; + } + + return $resultado['docs']; + + } // Fin buscar() + + public function detalles($idApi){ + + if(strpos($idApi, '/works/') !== 0){ + $idApi = '/works/'.$idApi; + } + + + /// Obtenemos la work + $urlWork = 'https://openlibrary.org'.$idApi.'.json'; + $resultado = $this->peticion($urlWork); + + if(isset($resultado['error'])){ + return $resultado; + } + + // Recuperamos datos bÔsicos que la Work no siempre tiene + $urlExtra = + 'https://openlibrary.org/search.json' + . '?q=key:'.urlencode($idApi) + . '&fields=' + . 'first_publish_year,' + . 'cover_i,' + . 'ratings_average,' + . 'number_of_pages_median,' + . 'language,' + . 'edition_count' + . '&limit=1'; + + + $extra = $this->peticion($urlExtra); + + if(!isset($extra['error']) && !empty($extra['docs'][0])){ + + $resultado['first_publish_year'] = $extra['docs'][0]['first_publish_year'] ?? null; + $resultado['cover_i'] = $extra['docs'][0]['cover_i'] ?? null; + $resultado['ratings_average'] = $extra['docs'][0]['ratings_average'] ?? null; + $resultado['number_of_pages_median'] = $extra['docs'][0]['number_of_pages_median'] ?? null; + $resultado['language'] = $extra['docs'][0]['language'] ?? []; + $resultado['edition_count'] = $extra['docs'][0]['edition_count'] ?? null; + } + + // Edición representativa + $urlEdiciones = 'https://openlibrary.org'.$idApi.'/editions.json?limit=1'; + $ediciones = $this->peticion($urlEdiciones); + + if(!isset($ediciones['error']) && !empty($ediciones['entries'])){ + + $resultado['edicionesLibro'] = $ediciones['entries']; + $resultado['edicionPrincipal'] = $ediciones['entries'][0]; + + foreach($ediciones['entries'] as $edicion){ + if(isset($edicion['number_of_pages']) || isset($edicion['publishers']) || isset($edicion['languages'])){ + + $resultado['edicionPrincipal'] = $edicion; + break; + } + } + } + + + return $resultado; + + } // Fin detalles() + + public function transformarDatos($resultado){ + + $libro = []; + + // Id + $libro['idApi'] = $resultado['key'] ?? ''; + + // Nombre + $libro['nombreLibro'] = $resultado['title'] ?? ''; + + // Autor + $autorLibro=''; + + if(!empty($resultado['author_name'])){ + + $autorLibro = $resultado['author_name'][0]; + + }elseif(isset($resultado['authors'][0]['author']['key'])){ + $autor = $this->peticion('https://openlibrary.org'.$resultado['authors'][0]['author']['key'].'.json'); + + if(!isset($autor['error']) && isset($autor['name'])){ + $autorLibro=$autor['name']; + } + } + + $libro['autorLibro']=$autorLibro; + + // Géneros + $generosPermitidos = [ + + 'fantasy', + 'fantasy fiction', + 'science fiction', + 'fiction', + 'romance', + 'mystery', + 'thriller', + 'horror', + 'adventure', + 'historical fiction', + 'historical', + 'crime', + 'drama', + 'comedy', + 'poetry', + 'biography', + 'autobiography', + 'memoir', + 'philosophy', + 'psychology', + 'self-help', + 'children', + 'young adult', + 'dystopian', + 'literary fiction', + 'graphic novel', + 'comics', + 'novel', + 'novels', + 'fiction novels', + 'literature', + 'classic literature', + 'classics', + 'modern fiction', + 'contemporary fiction', + 'suspense', + 'detective fiction', + 'police fiction', + 'espionage', + 'spy fiction', + 'war fiction', + 'political fiction', + 'satire', + 'humor', + 'tragedy', + 'romantic fiction', + 'erotic fiction', + 'gothic fiction', + 'dark fantasy', + 'urban fantasy', + 'epic fantasy', + 'high fantasy', + 'magical realism', + 'steampunk', + 'cyberpunk', + 'space opera', + 'alternate history', + 'apocalyptic fiction', + 'post apocalyptic fiction', + + 'history', + 'world history', + 'art', + 'music', + 'travel', + 'travel writing', + 'cooking', + 'cookbooks', + 'food', + 'crafts', + 'business', + 'finance', + 'economics', + 'education', + 'textbooks', + 'science', + 'popular science', + 'nature', + 'environment', + 'health', + 'fitness', + 'sports', + 'religion', + 'spirituality', + 'politics', + 'sociology', + 'anthropology', + + 'picture books', + 'fairy tales', + 'folk tales', + 'juvenile fiction', + 'juvenile literature', + 'middle grade', + 'school stories', + + 'essays', + 'short stories', + 'plays', + 'drama', + 'screenplays' + ]; + + $generos = []; + + if(isset($resultado['subjects'])){ + foreach($resultado['subjects'] as $subject){ + + $subjectNormalizado = strtolower(trim($subject)); + + if(in_array($subjectNormalizado, $generosPermitidos, true)){ + $generos[] = $subject; + } + } + } + + $libro['generoLibro'] = implode(', ',array_unique($generos)); + + // Temas + $temasPermitidos = [ + + 'marriage', + 'husbands', + 'wives', + 'siblings', + 'children', + 'parent and child', + 'friendship', + 'companionship', + 'rivalry', + 'conflict', + 'betrayal', + 'revenge', + 'love', + 'romance', + 'jealousy', + 'family', + 'community', + + 'magic', + 'sorcery', + 'witchcraft', + 'wizardry', + 'dragons', + 'elves', + 'dwarves', + 'vampires', + 'werewolves', + 'ghosts', + 'spirits', + 'monsters', + 'supernatural', + 'mythical creatures', + 'mythology', + 'legends', + 'prophecy', + 'quests', + 'enchanted places', + + 'murder', + 'crime', + 'criminals', + 'investigation', + 'mystery', + 'detectives', + 'police', + 'espionage', + 'secrets', + 'conspiracy', + 'kidnapping', + + 'racism', + 'prejudice', + 'social issues', + 'poverty', + 'wealth', + 'class differences', + 'political systems', + 'government', + 'revolution', + 'rebellion', + 'colonialism', + 'immigration', + + 'journeys', + 'travel', + 'exploration', + 'adventure', + 'survival', + 'wilderness', + 'expeditions', + 'islands', + 'oceans', + 'space', + 'planets', + + 'mental health', + 'trauma', + 'anxiety', + 'depression', + 'identity', + 'self discovery', + 'personal growth', + 'dreams', + 'nightmares', + 'memories', + + 'artificial intelligence', + 'robots', + 'computers', + 'technology', + 'space exploration', + 'astronomy', + 'genetics', + 'medicine', + + 'ancient history', + 'medieval history', + 'world war', + 'warfare', + 'military', + 'historical figures', + 'biographical subjects', + + 'storytelling', + 'writers', + 'authors', + 'books', + 'reading', + 'literary criticism', + 'fiction writing' + ]; + + $temas = []; + + if(isset($resultado['subjects'])){ + foreach($resultado['subjects'] as $subject){ + + $subjectNormalizado = strtolower(trim($subject)); + + if(in_array($subjectNormalizado, $temasPermitidos, true)){ + $temas[] = $subject; + } + } + } + + $libro['temaLibro'] =implode(', ',array_unique($temas)); + + // Año + $libro['anoLibro'] = ''; + + if(!empty($resultado['first_publish_year'])){ + $libro['anoLibro'] =$resultado['first_publish_year']; + }else{ + $edicion = $resultado['edicionPrincipal'] ?? []; + + if(!empty($edicion['publish_date'])){ + $fecha = date_create($edicion['publish_date']); + + if($fecha){ + $libro['anoLibro'] =$fecha->format('Y'); + } + } + } + + // Sinopsis + $descripcion = $resultado['description'] ?? ''; + $libro['sinopsisLibro'] = $this->limpiarSinopsis($descripcion); + + // Portada + $coverId = null; + + if(!empty($resultado['covers']) && isset($resultado['covers'][0])){ + $coverId = $resultado['covers'][0]; + + }elseif(!empty($edicion['covers']) && isset($edicion['covers'][0])){ + $coverId = $edicion['covers'][0]; + + }elseif(!empty($resultado['cover_i'])){ + $coverId = $resultado['cover_i']; + } + + if($coverId){ + $libro['posterLibro'] ='https://covers.openlibrary.org/b/id/'.$coverId.'-L.jpg'; + + }else{ + $libro['posterLibro']='images/noPoster.jpeg'; + } + + // Rating medio + $libro['ratingAvgLibro'] = isset($resultado['ratings_average']) ? number_format($resultado['ratings_average'], 2) : null; + + // Paginas + $libro['paginasLibro'] = $resultado['number_of_pages_median'] ?? null; + + // Idioma + $idiomas = []; + + if(!empty($resultado['language'])){ + foreach($resultado['language'] as $idioma){ + $idiomas[] = basename($idioma); + } + } + + $libro['idiomaLibro'] = implode(', ', array_unique($idiomas)); + + // Ediciones + $libro['edicionesLibro'] = $resultado['edition_count'] ?? null; + + return $libro; + + } // Fin transformarDatos() + + private function limpiarSinopsis($descripcion){ + + if(is_array($descripcion)){ + $descripcion = $descripcion['value'] ?? ''; + } + + if(empty($descripcion)){ + return ''; + } + + // Eliminar definiciones de enlaces: + // [1]: https://... + $descripcion = preg_replace('/\n?\s*\[\d+\]:\s*\S+/i','', $descripcion); + + // Convertir [texto][1] -> texto + $descripcion = preg_replace('/\[([^\]]+)\]\[\d+\]/','$1', $descripcion + ); + + // Eliminar secciones no deseadas: + $seccionesNoDeseadas = [ + 'Key characters', + 'Awards and recognition', + 'Awards & recognition' + ]; + + foreach($seccionesNoDeseadas as $seccion){ + $posicion = stripos($descripcion, $seccion); + + if($posicion !== false){ + $descripcion = substr($descripcion, 0, $posicion); + } + } + + // Eliminar enlaces Markdown restantes: + // [texto](url) -> texto + $descripcion = preg_replace('/\[([^\]]+)\]\([^)]+\)/','$1', $descripcion); + + // Negrita/cursiva: + // ***texto*** -> texto + // **texto** -> texto + // *texto* -> texto + $descripcion = preg_replace('/\*{1,3}([^*]+)\*{1,3}/','$1', $descripcion); + + // Limpiar espacios innecesarios + $descripcion = preg_replace("/[ \t]+/",' ', $descripcion); + $descripcion = preg_replace("/\n{3,}/","\n\n", $descripcion); + + return trim($descripcion); + + } // Fin limpiarSinopsis() + + public function descargarPortada($url){ + + if(empty($url)){ + return ''; + } + + $carpeta = $_SERVER['DOCUMENT_ROOT'].'/MyDiary/images/libros/'; + + // Creamos la carpeta si no existe. + if(!is_dir($carpeta)){ + + if(!mkdir($carpeta, 0755, true)){ + return ''; + } + } + + // Extraemos el id de la portada de Open Library + if(!preg_match('/\/id\/(\d+)-[SML]\.jpg/i', $url, $coincidencias)){ + return ''; + } + + $idPortada = $coincidencias[1]; + + // Nombre y ruta física del archivo. + $nombreArchivo = $idPortada.'.jpg'; + + $rutaFisica = $carpeta.$nombreArchivo; + + // Ruta que guardaremos en la Base de Datos. + $rutaBD = 'images/libros/'.$nombreArchivo; + + // Si ya existe, no descargamos nada. + if(file_exists($rutaFisica)){ + return $rutaBD; + } + + // Descargamos la imagen. + $ch = curl_init($url); + + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 15); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); + + $imagen = curl_exec($ch); + + $codigoHTTP = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + // Comprobamos que la descarga haya funcionado. + if($imagen === false || $codigoHTTP < 200 || $codigoHTTP >= 300 || empty($imagen)){ + return ''; + } + + // Guardamos la imagen físicamente. + if(file_put_contents($rutaFisica, $imagen) === false){ + return ''; + } + + return $rutaBD; + + } // Fin descargarPortada() + +} // Fin clase ApiLibro + +?> \ No newline at end of file diff --git a/clases/claseApiPelicula.php b/clases/claseApiPelicula.php new file mode 100644 index 0000000..16e9602 --- /dev/null +++ b/clases/claseApiPelicula.php @@ -0,0 +1,221 @@ +token = $_ENV['tokenTMDB']; + } // Fin __construct() + + private function peticion($url){ + $curl = curl_init(); + + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_TIMEOUT, 10); + curl_setopt($curl, CURLOPT_HTTPHEADER, ["Authorization: Bearer ".$this->token, "accept: application/json"]); + + $respuesta = curl_exec($curl); + + if(curl_errno($curl)){ + return [ + "error" => curl_error($curl) + ]; + } + + curl_close($curl); + + return $respuesta; + } // Fin peticion() + + public function buscar($nombre){ + + $nombre = urlencode($nombre); + + $url = "https://api.themoviedb.org/3/search/movie?query=".$nombre; + + $respuesta = $this->peticion($url); + + return json_decode($respuesta, true); + + } // Fin buscar() + + public function detalles($idApi){ + + /* + * Obtenemos los detalles y los créditos + * en una única petición. + */ + $url = "https://api.themoviedb.org/3/movie/" + . $idApi + . "?append_to_response=credits"; + + $datos = $this->peticion($url); + + $respuesta = json_decode($datos, true); + + if(isset($respuesta['status_code'])){ + return $respuesta; + } + + + /* + * Directores + */ + $directores = []; + + if(isset($respuesta['credits']['crew'])){ + + foreach($respuesta['credits']['crew'] as $persona){ + + if($persona['job'] == 'Director'){ + + $directores[] = $persona['name']; + + if(count($directores) >= 2){ + break; + } + } + } + } + + $respuesta['directores'] = + implode(', ', $directores); + + + /* + * Actores + */ + $actores = []; + + if(isset($respuesta['credits']['cast'])){ + + foreach($respuesta['credits']['cast'] as $actor){ + + if(count($actores) >= 6){ + break; + } + + $actores[] = $actor['name']; + } + } + + $respuesta['actores'] = + implode(', ', $actores); + + + /* + * Guionistas + */ + $guionistas = []; + + if(isset($respuesta['credits']['crew'])){ + + foreach($respuesta['credits']['crew'] as $persona){ + + if($persona['job'] == 'Screenplay'){ + + $guionistas[] = $persona['name']; + + if(count($guionistas) >= 3){ + break; + } + } + } + } + + $respuesta['guionistas'] = + implode(', ', $guionistas); + + + /* + * Eliminamos credits porque ya no necesitamos + * conservar toda esa información en la respuesta. + */ + unset($respuesta['credits']); + + + return $respuesta; + + } // Fin detalles() + + public function transformarDatos($resultado){ + + $pelicula = []; + $pelicula['idApi'] = $resultado['id']; + $pelicula['nombrePelicula'] = $resultado['title']; + $pelicula['anoPelicula'] = substr($resultado['release_date'],0,4); + $pelicula['posterPelicula'] = "https://image.tmdb.org/t/p/w500".$resultado['poster_path']; + $pelicula['ratingAvgPelicula'] = number_format($resultado['vote_average']/2, 2); + $pelicula['sinopsisPelicula'] = $resultado['overview']; + + if(isset($resultado['runtime'])){ + $pelicula['duracionPelicula'] = $resultado['runtime']; + } + if(isset($resultado['directores'])){ + $pelicula['directorPelicula'] = $resultado['directores']; + } + if(isset($resultado['actores'])){ + $pelicula['actorPelicula'] = $resultado['actores']; + } + if(isset($resultado['guionistas'])){ + if($resultado['guionistas']==''){ + $pelicula['guionistaPelicula'] = $resultado['directores']; + }else{ + $pelicula['guionistaPelicula'] = $resultado['guionistas']; + } + } + + // Géneros + if(isset($resultado['genres'])){ + $generos = []; + + foreach($resultado['genres'] as $genero){ + $generos[] = $genero['name']; + } + + $pelicula['generoPelicula'] = implode(', ', $generos); + } + + // Paises + if(isset($resultado['origin_country'])){ + $paises = []; + + foreach($resultado['origin_country'] as $pais){ + $paises[] = $pais; + } + + $pelicula['paisPelicula'] = implode(', ', $paises); + } + + // Compañías + if(isset($resultado['production_companies'])){ + $companias = []; + + foreach($resultado['production_companies'] as $compania){ + $companias[] = $compania['name']; + } + + $pelicula['companiaPelicula'] = implode(', ', $companias); + } + + // Idiomas + if(isset($resultado['spoken_languages'])){ + $idiomas = []; + + foreach($resultado['spoken_languages'] as $idioma){ + $idiomas[] = $idioma['name']; + } + + $pelicula['idiomaPelicula'] = implode(', ', $idiomas); + } + + return $pelicula; + + } // Fin transformarDatos() + +} // Fin clase ApiPelicula + +?> \ No newline at end of file diff --git a/clases/claseApiSerie.php b/clases/claseApiSerie.php new file mode 100644 index 0000000..31dfd7b --- /dev/null +++ b/clases/claseApiSerie.php @@ -0,0 +1,700 @@ +token = $_ENV['tokenTMDB']; + } // Fin __construct() + + private function peticion($url){ + + $curl = curl_init(); + + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_TIMEOUT, 10); + curl_setopt($curl, CURLOPT_HTTPHEADER,['Authorization: Bearer '.$this->token, 'Accept: application/json']); + + $respuesta = curl_exec($curl); + + $codigoHTTP = curl_getinfo($curl, CURLINFO_HTTP_CODE); + + if(curl_errno($curl)){ + $error = curl_error($curl); + curl_close($curl); + + return [ + 'error' => 'No se pudo realizar la petición a TMDB.', + 'error_tecnico' => $error + ]; + } + + curl_close($curl); + + $resultado =json_decode($respuesta,true); + + if($codigoHTTP < 200 || $codigoHTTP >= 300){ + + return [ + 'error' => 'TMDB devolvió un error.', + 'error_tecnico' => $resultado + ]; + } + + return $resultado; + + } // Fin peticion() + + public function buscar($nombre){ + + $nombre = urlencode($nombre); + + $url = 'https://api.themoviedb.org/3/search/tv'.'?query='.$nombre; + + $resultado = $this->peticion($url); + + if(isset($resultado['error'])){ + return $resultado; + } + + return $resultado['results']; + + } // Fin buscar() + + public function detalles($idApi){ + + $url = 'https://api.themoviedb.org/3/tv/'.$idApi.'?append_to_response=aggregate_credits,watch/providers'; + + $resultado = $this->peticion($url); + + if(isset($resultado['error'])){ + return $resultado; + } + + // Directores + $directores = []; + + if(isset($resultado['aggregate_credits']['crew'])){ + foreach($resultado['aggregate_credits']['crew'] as $persona){ + + if(!isset($persona['jobs'])){ + continue; + } + + foreach($persona['jobs'] as $trabajo){ + + if($trabajo['job'] === 'Director' && !in_array($persona['name'],$directores,true)){ + + $directores[] = $persona['name']; + break; + } + } + + if(count($directores) >= 2){ + break; + } + } + } + + $resultado['directores'] = implode(', ', $directores); + + // Actores + $actores = []; + + if(isset($resultado['aggregate_credits']['cast'])){ + foreach($resultado['aggregate_credits']['cast'] as $actor){ + + if(count($actores) >= 6){ + break; + } + + $actores[] = $actor['name']; + } + } + + $resultado['actores'] = implode(', ', $actores); + + + // Guionistas + $guionistas = []; + + if(isset($resultado['aggregate_credits']['crew'])){ + foreach($resultado['aggregate_credits']['crew'] as $persona){ + + if(!isset($persona['jobs'])){ + continue; + } + + foreach($persona['jobs'] as $trabajo){ + + if($trabajo['job'] === 'Writer' || $trabajo['job'] === 'Screenplay' || $trabajo['job'] === 'Teleplay'){ + + if(!in_array($persona['name'],$guionistas,true)){ + + $guionistas[] = $persona['name']; + } + + break; + } + } + + if(count($guionistas) >= 3){ + break; + } + } + } + + $resultado['guionistas'] = implode(', ', $guionistas); + + + unset($resultado['aggregate_credits']); + + return $resultado; + + } // Fin detalles() + + public function transformarDatos($resultado){ + + $serie = []; + + // Id + $serie['idApi'] = $resultado['id'] ?? ''; + + // Nombre + $serie['nombreSerie'] = $resultado['name'] ?? ''; + + // Creador + $creadores = []; + + if(!empty($resultado['created_by'])){ + foreach($resultado['created_by'] as $creador){ + if(isset($creador['name'])){ + $creadores[] =$creador['name']; + } + } + } + + $serie['creadorSerie'] = implode(', ',array_unique($creadores)); + + // Director + $serie['directorSerie'] = $resultado['directores'] ?? ''; + + // Actor + $serie['actorSerie'] = $resultado['actores'] ?? ''; + + // Guionista + $serie['guionistaSerie'] = $resultado['guionistas'] ?? ''; + + // Genero + $generos = []; + + if(!empty($resultado['genres'])){ + foreach($resultado['genres'] as $genero){ + if(isset($genero['name'])){ + $generos[] = $genero['name']; + } + } + } + + $serie['generoSerie'] = implode(', ',array_unique($generos)); + + // Año + $serie['anoSerie'] = !empty($resultado['first_air_date']) ? substr($resultado['first_air_date'],0,4) : ''; + + // Número temporadas + $serie['temporadasSerie'] = $resultado['number_of_seasons'] ?? 0; + + // Número episodios + $serie['episodiosSerie'] = $resultado['number_of_episodes'] ?? 0; + + // Rating medio + $serie['ratingAvgSerie'] = isset($resultado['vote_average']) ? number_format($resultado['vote_average'] / 2,2): null; + + // Compañia + $companias = []; + + if(!empty($resultado['production_companies'])){ + foreach($resultado['production_companies'] as $compania){ + if(isset($compania['name'])){ + $companias[] = $compania['name']; + } + } + } + + $serie['companiaSerie'] = implode(', ',array_unique($companias)); + + // País + $paises = []; + + if(!empty($resultado['production_countries'])){ + foreach($resultado['production_countries'] as $pais){ + if(isset($pais['name'])){ + $paises[] = $pais['name']; + } + } + } + + if(empty($paises) && !empty($resultado['origin_country'])){ + $paises = $resultado['origin_country']; + } + + $serie['paisSerie'] = implode(', ',array_unique($paises)); + + // Idioma + $idiomas = []; + + if(!empty($resultado['spoken_languages'])){ + foreach($resultado['spoken_languages'] as $idioma){ + if(isset($idioma['name'])){ + $idiomas[] = $idioma['name']; + } + } + } + + if(empty($idiomas) && !empty($resultado['original_language'])){ + $idiomas[] = $resultado['original_language']; + } + + $serie['idiomaSerie'] = implode(', ',array_unique($idiomas)); + + // Sinopsis + $serie['sinopsisSerie'] = $resultado['overview'] ?? ''; + + // Portada + if(!empty($resultado['poster_path'])){ + $serie['posterSerie'] = 'https://image.tmdb.org/t/p/w500'.$resultado['poster_path']; + }else{ + $serie['posterSerie'] = 'images/noPoster.jpeg'; + } + + // Temporadas. + // Mantenemos la información proporcionada directamente por TMDB para poder utilizarla mÔs adelante. + $serie['temporadas'] = $resultado['seasons'] ?? []; + + return $serie; + + } // Fin transformarDatos() + + public function temporada($idSerie, $numeroTemporada){ + + $url = 'https://api.themoviedb.org/3/tv/'.$idSerie.'/season/'.$numeroTemporada.'?append_to_response=aggregate_credits'; + + $datos = $this->peticion($url); + + if(is_array($datos)){ + return $datos; + } + + $respuesta = json_decode($datos, true); + + if(isset($respuesta['status_code'])){ + + return [ + 'error' => 'TMDB devolvió un error.', + 'error_tecnico' => $respuesta + ]; + } + + return $respuesta; + + } // Fin temporada() + + public function transformarDatosTemporada($resultado, $nombreSerie){ + + $temporada = []; + + // Id + $temporada['idApi'] = $resultado['id'] ?? ''; + + // ID de la serie a la que pertenece + // Lo dejamos preparado para que el controlador + // pueda asignarle después tu idSerie de la BD. + + $temporada['idSerie'] = null; + + // Nombre + $temporada['nombreTemporada'] = $resultado['name'] ? $nombreSerie.' - '.$resultado['name'] : ''; + + // Numero temporada + $temporada['numeroTemporada'] = $resultado['season_number'] ?? null; + + // Director + $directores = []; + + if(isset($resultado['aggregate_credits']['crew']) && is_array($resultado['aggregate_credits']['crew'])){ + foreach($resultado['aggregate_credits']['crew'] as $persona){ + + if(empty($persona['jobs'])){ + continue; + } + + foreach($persona['jobs'] as $trabajo){ + if(isset($trabajo['job']) && $trabajo['job'] === 'Director'){ + if(isset($persona['name']) && !in_array($persona['name'],$directores,true)){ + $directores[] = $persona['name']; + } + break; + } + } + if(count($directores) >= 2){ + break; + } + } + } + + $temporada['directorTemporada'] = implode(', ', $directores); + + // Guionista + $guionistas = []; + + if(isset($resultado['aggregate_credits']['crew']) && is_array($resultado['aggregate_credits']['crew'])){ + foreach($resultado['aggregate_credits']['crew'] as $persona){ + if(empty($persona['jobs'])){ + continue; + } + foreach($persona['jobs'] as $trabajo){ + if(isset($trabajo['job']) &&($trabajo['job'] === 'Writer' || $trabajo['job'] === 'Screenplay' ||$trabajo['job'] === 'Teleplay')){ + if(isset($persona['name']) && !in_array($persona['name'], $guionistas, true)){ + $guionistas[] = $persona['name']; + } + break; + } + } + if(count($guionistas) >= 3){ + break; + } + } + } + + $temporada['guionistaTemporada'] = implode(', ', $guionistas); + + // Actor + $actores = []; + + if(isset($resultado['aggregate_credits']['cast']) && is_array($resultado['aggregate_credits']['cast'])){ + foreach($resultado['aggregate_credits']['cast'] as $actor){ + if(count($actores) >= 6){ + break; + } + if(isset($actor['name'])){ + $actores[] = $actor['name']; + } + } + } + + $temporada['actorTemporada'] = implode(', ', $actores); + + // Numero episodios + $temporada['episodiosTemporada'] = count($resultado['episodes']) ?? 0; + + // Año + $temporada['anoTemporada'] = ''; + if(!empty($resultado['air_date'])){ + $temporada['anoTemporada'] =substr($resultado['air_date'],0,4); + } + + // Rating medio + $temporada['ratingAvgTemporada'] = isset($resultado['vote_average']) ? number_format($resultado['vote_average'] / 2, 2) : null; + + // Portada + if(!empty($resultado['poster_path'])){ + $temporada['posterTemporada'] = 'https://image.tmdb.org/t/p/w500'.$resultado['poster_path']; + }else{ + $temporada['posterTemporada'] = 'images/noPoster.jpeg'; + } + + // Sinopsis + $temporada['sinopsisTemporada'] = $resultado['overview'] ?? ''; + + // Episodios + $episodios = []; + + if(!empty($resultado['episodes'])){ + foreach($resultado['episodes'] as $episodio){ + + $episodios[] = [ + 'idApi' => $episodio['id'] ?? '', + 'nombreEpisodio' => $episodio['name'] ?? '', + 'numeroEpisodio' => $episodio['episode_number'] ?? null, + 'ratingAvgEpisodio' => isset($episodio['vote_average']) ? number_format($episodio['vote_average'] / 2, 2) : null, + 'posterEpisodio' => !empty($episodio['still_path']) ? 'https://image.tmdb.org/t/p/w300'.$episodio['still_path'] : 'images/noPoster.jpeg', + 'sinopsisEpisodio' => $episodio['overview'] ?? '', + 'anoEpisodio' => !empty($episodio['air_date']) ? substr($episodio['air_date'], 0, 4) : '' + ]; + } + } + + $temporada['episodios'] = $episodios; + + return $temporada; + + } // Fin transformarDatosTemporada() + + public function episodio($idSerie, $numeroTemporada, $numeroEpisodio){ + + $url = + 'https://api.themoviedb.org/3/tv/' + .$idSerie + .'/season/' + .$numeroTemporada + .'/episode/' + .$numeroEpisodio + .'?append_to_response=credits'; + + $datos = $this->peticion($url); + + if(is_array($datos)){ + return $datos; + } + + $respuesta = json_decode($datos, true); + + if(isset($respuesta['status_code'])){ + + return [ + 'error' => 'TMDB devolvió un error.', + 'error_tecnico' => $respuesta + ]; + } + + return $respuesta; + + } // Fin episodio() + + public function transformarDatosEpisodio($resultado, $numeroTemporada, $nombreSerie){ + + $episodio = []; + + + /* + * ID de TMDB + */ + $episodio['idApi'] = $resultado['id'] ?? ''; + + + /* + * ID de la temporada + * + * SerÔ el ID interno de tu BD cuando lo guardemos. + */ + $episodio['idTemporada'] = null; + + + /* + * Nombre + */ + if(strlen((string)$resultado['episode_number'])==1){ + $episodio['nombreEpisodio'] = $resultado['name'] ? $nombreSerie.' - '.$numeroTemporada.'x0'.$resultado['episode_number'].' ('.$resultado['name'].')' : ''; + }else{ + $episodio['nombreEpisodio'] = $resultado['name'] ? $nombreSerie.' - '.$numeroTemporada.'x'.$resultado['episode_number'].' ('.$resultado['name'].')' : ''; + } + + + /* + * Número de episodio + */ + $episodio['numeroEpisodio'] = $resultado['episode_number'] ?? null; + + + /* + * Director + */ + $directores = []; + + if( + !empty($resultado['credits']['crew']) && + is_array($resultado['credits']['crew']) + ){ + + foreach( + $resultado['credits']['crew'] + as $persona + ){ + + if( + isset($persona['job']) && + $persona['job'] === 'Director' && + isset($persona['name']) + ){ + + if(!in_array( + $persona['name'], + $directores, + true + )){ + + $directores[] = + $persona['name']; + } + + if(count($directores) >= 2){ + break; + } + } + } + } + + $episodio['directorEpisodio'] = + implode(', ', $directores); + + + /* + * Guionistas + */ + $guionistas = []; + + if( + !empty($resultado['credits']['crew']) && + is_array($resultado['credits']['crew']) + ){ + + foreach( + $resultado['credits']['crew'] + as $persona + ){ + + if( + !isset($persona['job']) || + !isset($persona['name']) + ){ + continue; + } + + if( + $persona['job'] === 'Writer' || + $persona['job'] === 'Screenplay' || + $persona['job'] === 'Teleplay' + ){ + + if(!in_array( + $persona['name'], + $guionistas, + true + )){ + + $guionistas[] = + $persona['name']; + } + + if(count($guionistas) >= 3){ + break; + } + } + } + } + + $episodio['guionistaEpisodio'] = + implode(', ', $guionistas); + + + /* + * Actores + */ + $actores = []; + + if( + !empty($resultado['credits']['cast']) && + is_array($resultado['credits']['cast']) + ){ + + foreach( + $resultado['credits']['cast'] + as $actor + ){ + + if(count($actores) >= 6){ + break; + } + + if(isset($actor['name'])){ + + $actores[] = + $actor['name']; + } + } + } + + $episodio['actorEpisodio'] = + implode(', ', array_unique($actores)); + + + /* + * Año + */ + $episodio['anoEpisodio'] = ''; + + if(!empty($resultado['air_date'])){ + + $episodio['anoEpisodio'] = + substr( + $resultado['air_date'], + 0, + 4 + ); + } + + + /* + * Valoración media + * + * TMDB: 0-10 + * Proyecto: 0-5 + */ + $episodio['ratingAvgEpisodio'] = + isset($resultado['vote_average']) + ? number_format( + $resultado['vote_average'] / 2, + 2 + ) + : null; + + + /* + * Portada / imagen + */ + if(!empty($resultado['still_path'])){ + + $episodio['posterEpisodio'] = + 'https://image.tmdb.org/t/p/w500' + .$resultado['still_path']; + + }else{ + + $episodio['posterEpisodio'] = + 'images/noPoster.jpeg'; + } + + + /* + * Sinopsis + */ + $episodio['sinopsisEpisodio'] = + $resultado['overview'] ?? ''; + + + /* + * Duración + * + * El episodio puede tener runtime aunque no + * lo hayamos guardado en la temporada. + */ + $episodio['duracionEpisodio'] = $resultado['runtime'] ? $resultado['runtime'].' min' : null; + + + return $episodio; + + } // Fin transformarDatosEpisodio() + +} // Fin clase ApiSerie +/* +$api = new ApiSerie(); +$resultado = $api->episodio(70523, 2, 6); + +echo ''; +print_r ($resultado); +echo ''; +*/ +?> \ No newline at end of file diff --git a/clases/claseEpisodio.php b/clases/claseEpisodio.php new file mode 100644 index 0000000..886d806 --- /dev/null +++ b/clases/claseEpisodio.php @@ -0,0 +1,148 @@ +idEpisodio = $idEpisodio; + $this->idApi = $idApi; + $this->idTemporada = $idTemporada; + $this->nombreEpisodio = $nombreEpisodio; + $this->directorEpisodio = $directorEpisodio; + $this->actorEpisodio = $actorEpisodio; + $this->guionistaEpisodio = $guionistaEpisodio; + $this->anoEpisodio = $anoEpisodio; + $this->duracionEpisodio = $duracionEpisodio; + $this->ratingAvgEpisodio = $ratingAvgEpisodio; + $this->posterEpisodio = $posterEpisodio; + $this->sinopsisEpisodio = $sinopsisEpisodio; + } // Fin __construct + + public function existe(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT idEpisodio FROM seriesepisodios WHERE idApi=:idApi"); + + $consulta->bindParam(':idApi', $this->idApi); + $consulta->execute(); + + $resultado = $consulta->fetch(PDO::FETCH_ASSOC); + + if($resultado){ + return $resultado['idEpisodio']; + }else{ + return false; + } + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al comprobar si existe el episodio en la Base de Datos.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin existe() + + public function agregar(){ + + // Miramos si existe + $idEpisodio = $this->existe($this->idApi); + + // Si no existe la creamos, y devolvemos el último idEpisodio insertado + // Si existe devolvemos el idEpisodio correspondiente + if(!$idEpisodio){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + + $consulta=$conexion->prepare("INSERT INTO seriesepisodios (idApi, idTemporada, nombreEpisodio, numeroEpisodio, directorEpisodio, actorEpisodio, guionistaEpisodio, anoEpisodio, duracionEpisodio, ratingAvgEpisodio, posterEpisodio, sinopsisEpisodio) VALUES (:idApi,:idTemporada,:nombre,:numero,:director,:actor,:guionista,:ano,:duracion,:ratingAvg,:poster,:sinopsis)"); + + $consulta->bindParam(':idApi',$this->idApi); + $consulta->bindParam(':idTemporada',$this->idTemporada); + $consulta->bindParam(':nombre',$this->nombreEpisodio); + $consulta->bindParam(':numero',$this->numeroEpisodio); + $consulta->bindParam(':director',$this->directorEpisodio); + $consulta->bindParam(':actor',$this->actorEpisodio); + $consulta->bindParam(':guionista',$this->guionistaEpisodio); + $consulta->bindParam(':ano',$this->anoEpisodio); + $consulta->bindParam(':duracion',$this->duracionEpisodio); + $consulta->bindParam(':ratingAvg',$this->ratingAvgEpisodio); + $consulta->bindParam(':poster',$this->posterEpisodio); + $consulta->bindParam(':sinopsis',$this->sinopsisEpisodio); + + $consulta->execute(); + + return $conexion->lastInsertId(); + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar el episodio.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + }else{ + return $idEpisodio; + } + + } // Fin agregar() + + public function comprobar(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT * FROM seriesepisodios WHERE idEpisodio= :idEpisodio"); + + $consulta->bindParam(':idEpisodio', $this->idEpisodio); + $consulta->execute(); + + return $consulta->fetchAll(PDO::FETCH_ASSOC); + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al recoger los datos del episodio seleccionado.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin comprobar() + +} // Fin clase Episodio + +?> \ No newline at end of file diff --git a/clases/claseHistorial.php b/clases/claseHistorial.php new file mode 100644 index 0000000..bbd0735 --- /dev/null +++ b/clases/claseHistorial.php @@ -0,0 +1,311 @@ +idHistorial = $idHistorial; + $this->idUsuario = $idUsuario; + $this->idUsuarioPelicula = $idUsuarioPelicula; + $this->idUsuarioSerie = $idUsuarioSerie; + $this->idUsuarioTemporada = $idUsuarioTemporada; + $this->idUsuarioEpisodio = $idUsuarioEpisodio; + $this->idUsuarioJuego = $idUsuarioJuego; + $this->idUsuarioLibro = $idUsuarioLibro; + $this->nombreHistorial = $nombreHistorial; + $this->accionHistorial = $accionHistorial; + $this->fechaHistorial = $fechaHistorial; + } // Fin __construct + + public function agregarPelicula(){ + + $conexion=conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta=$conexion->prepare("INSERT INTO historial (idUsuario, idUsuarioPelicula, nombreHistorial, accionHistorial) VALUES (:idUsuario, :idUsuarioPelicula, :nombre, :accion)"); + + $consulta->bindParam(':idUsuario',$this->idUsuario); + $consulta->bindParam(':idUsuarioPelicula',$this->idUsuarioPelicula); + $consulta->bindParam(':nombre',$this->nombreHistorial); + $consulta->bindParam(':accion',$this->accionHistorial); + + $consulta->execute(); + return $conexion->lastInsertId(); + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar la acción al historial de películas.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin agregarPelicula() + + public function listarPelicula(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT * FROM historial WHERE idUsuario = :idUsuario AND idUsuarioPelicula IS NOT NULL ORDER BY fechaHistorial DESC LIMIT 50"); + + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de historial de películas.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarPelicula() + + public function agregarSerie(){ + + $conexion=conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta=$conexion->prepare("INSERT INTO historial (idUsuario, idUsuarioSerie, nombreHistorial, accionHistorial) VALUES (:idUsuario, :idUsuarioSerie, :nombre, :accion)"); + + $consulta->bindParam(':idUsuario',$this->idUsuario); + $consulta->bindParam(':idUsuarioSerie',$this->idUsuarioSerie); + $consulta->bindParam(':nombre',$this->nombreHistorial); + $consulta->bindParam(':accion',$this->accionHistorial); + + $consulta->execute(); + return $conexion->lastInsertId(); + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar la acción al historial de series.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin agregarSerie() + + public function agregarTemporada(){ + + $conexion=conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta=$conexion->prepare("INSERT INTO historial (idUsuario, idUsuarioTemporada, nombreHistorial, accionHistorial) VALUES (:idUsuario, :idUsuarioTemporada, :nombre, :accion)"); + + $consulta->bindParam(':idUsuario',$this->idUsuario); + $consulta->bindParam(':idUsuarioTemporada',$this->idUsuarioTemporada); + $consulta->bindParam(':nombre',$this->nombreHistorial); + $consulta->bindParam(':accion',$this->accionHistorial); + + $consulta->execute(); + return $conexion->lastInsertId(); + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar la acción al historial de series.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin agregarTemporada() + + public function agregarEpisodio(){ + + $conexion=conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta=$conexion->prepare("INSERT INTO historial (idUsuario, idUsuarioEpisodio, nombreHistorial, accionHistorial) VALUES (:idUsuario, :idUsuarioEpisodio, :nombre, :accion)"); + + $consulta->bindParam(':idUsuario',$this->idUsuario); + $consulta->bindParam(':idUsuarioEpisodio',$this->idUsuarioEpisodio); + $consulta->bindParam(':nombre',$this->nombreHistorial); + $consulta->bindParam(':accion',$this->accionHistorial); + + $consulta->execute(); + return $conexion->lastInsertId(); + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar la acción al historial de series.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin agregarEpisodio() + + public function listarSerie(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT * FROM historial WHERE idUsuario = :idUsuario AND (idUsuarioSerie IS NOT NULL OR idUsuarioTemporada IS NOT NULL OR idUsuarioEpisodio IS NOT NULL) ORDER BY fechaHistorial DESC LIMIT 50"); + + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de historial para series.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarSerie() + + public function agregarJuego(){ + + $conexion=conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta=$conexion->prepare("INSERT INTO historial (idUsuario, idUsuarioJuego, nombreHistorial, accionHistorial) VALUES (:idUsuario, :idUsuarioJuego, :nombre, :accion)"); + + $consulta->bindParam(':idUsuario',$this->idUsuario); + $consulta->bindParam(':idUsuarioJuego',$this->idUsuarioJuego); + $consulta->bindParam(':nombre',$this->nombreHistorial); + $consulta->bindParam(':accion',$this->accionHistorial); + + $consulta->execute(); + return $conexion->lastInsertId(); + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar la acción al historial de videojuegos.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin agregarJuego() + + public function listarJuego(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT * FROM historial WHERE idUsuario = :idUsuario AND idUsuarioJuego IS NOT NULL ORDER BY fechaHistorial DESC LIMIT 50"); + + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de historial para videojuegos.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarJuego() + + public function agregarLibro(){ + + $conexion=conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta=$conexion->prepare("INSERT INTO historial (idUsuario, idUsuarioLibro, nombreHistorial, accionHistorial) VALUES (:idUsuario, :idUsuarioLibro, :nombre, :accion)"); + + $consulta->bindParam(':idUsuario',$this->idUsuario); + $consulta->bindParam(':idUsuarioLibro',$this->idUsuarioLibro); + $consulta->bindParam(':nombre',$this->nombreHistorial); + $consulta->bindParam(':accion',$this->accionHistorial); + + $consulta->execute(); + return $conexion->lastInsertId(); + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar la acción al historial de libros.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin agregarLibro() + + public function listarLibro(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT * FROM historial WHERE idUsuario = :idUsuario AND idUsuarioLibro IS NOT NULL ORDER BY fechaHistorial DESC LIMIT 50"); + + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de historial para libros.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarLibro() + +} // Fin clase Historial +?> \ No newline at end of file diff --git a/clases/claseJuego.php b/clases/claseJuego.php new file mode 100644 index 0000000..d39ae2c --- /dev/null +++ b/clases/claseJuego.php @@ -0,0 +1,156 @@ +idJuego = $idJuego; + $this->idApi = $idApi; + $this->nombreJuego = $nombreJuego; + $this->desarrolladorJuego = $desarrolladorJuego; + $this->editorJuego = $editorJuego; + $this->anoJuego = $anoJuego; + $this->franquiciaJuego = $franquiciaJuego; + $this->generoJuego = $generoJuego; + $this->plataformasJuego = $plataformasJuego; + $this->dlcJuego = $dlcJuego; + $this->expansionJuego = $expansionJuego; + $this->duracionJuego = $duracionJuego; + $this->ratingAvgJuego = $ratingAvgJuego; + $this->posterJuego = $posterJuego; + $this->sinopsisJuego = $sinopsisJuego; + } // Fin __construct + + public function existe(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT idJuego FROM juegos WHERE idApi=:idApi"); + + $consulta->bindParam(':idApi', $this->idApi); + $consulta->execute(); + + $resultado = $consulta->fetch(PDO::FETCH_ASSOC); + + if($resultado){ + return $resultado['idJuego']; + }else{ + return false; + } + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al comprobar si existe el videojuego en la Base de Datos.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin existe() + + public function agregar(){ + + // Miramos si existe + $idJuego = $this->existe($this->idApi); + + // Si no existe la creamos, y devolvemos el último idJuego insertado + // Si existe devolvemos el idJuego correspondiente + if(!$idJuego){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + + $consulta=$conexion->prepare("INSERT INTO juegos (idApi, nombreJuego, desarrolladorJuego, editorJuego, anoJuego, franquiciaJuego, generoJuego, plataformasJuego, dlcJuego, expansionJuego, duracionJuego, ratingAvgJuego, posterJuego, sinopsisJuego) VALUES (:idApi,:nombre,:desarrollador,:editor,:ano,:franquicia,:genero,:plat,:dlc,:expansion,:duracion,:ratingAvg,:poster,:sinopsis)"); + + $consulta->bindParam(':idApi',$this->idApi); + $consulta->bindParam(':nombre',$this->nombreJuego); + $consulta->bindParam(':desarrollador',$this->desarrolladorJuego); + $consulta->bindParam(':editor',$this->editorJuego); + $consulta->bindParam(':ano',$this->anoJuego); + $consulta->bindParam(':franquicia',$this->franquiciaJuego); + $consulta->bindParam(':genero',$this->generoJuego); + $consulta->bindParam(':plat',$this->plataformasJuego); + $consulta->bindParam(':dlc',$this->dlcJuego); + $consulta->bindParam(':expansion',$this->expansionJuego); + $consulta->bindParam(':duracion',$this->duracionJuego); + $consulta->bindParam(':ratingAvg',$this->ratingAvgJuego); + $consulta->bindParam(':poster',$this->posterJuego); + $consulta->bindParam(':sinopsis',$this->sinopsisJuego); + + $consulta->execute(); + + return $conexion->lastInsertId(); + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar el videojuego.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + }else{ + return $idJuego; + } + + } // Fin agregar() + + public function comprobar(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT * FROM juegos WHERE idJuego= :idJuego"); + + $consulta->bindParam(':idJuego', $this->idJuego); + $consulta->execute(); + + return $consulta->fetchAll(PDO::FETCH_ASSOC); + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al recoger los datos del videojuego seleccionado.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin comprobar() + +} // Fin clase Juego + + +?> \ No newline at end of file diff --git a/clases/claseLibro.php b/clases/claseLibro.php new file mode 100644 index 0000000..b9f1da7 --- /dev/null +++ b/clases/claseLibro.php @@ -0,0 +1,192 @@ +idLibro = $idLibro; + $this->idApi = $idApi; + $this->nombreLibro = $nombreLibro; + $this->autorLibro = $autorLibro; + $this->anoLibro = $anoLibro; + $this->generoLibro = $generoLibro; + $this->temaLibro = $temaLibro; + $this->paginasLibro = $paginasLibro; + $this->edicionesLibro = $edicionesLibro; + $this->idiomaLibro = $idiomaLibro; + $this->ratingAvgLibro = $ratingAvgLibro; + $this->posterLibro = $posterLibro; + $this->sinopsisLibro = $sinopsisLibro; + } // Fin __construct + + public function existe(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT idLibro FROM libros WHERE idApi=:idApi"); + + $consulta->bindParam(':idApi', $this->idApi); + $consulta->execute(); + + $resultado = $consulta->fetch(PDO::FETCH_ASSOC); + + if($resultado){ + return $resultado['idLibro']; + }else{ + return false; + } + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al comprobar si existe el libro en la Base de Datos.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin existe() + + public function agregar(){ + + // Miramos si existe + $idLibro = $this->existe($this->idApi); + + // Si no existe la creamos, y devolvemos el último idLibro insertado + // Si existe devolvemos el idLibro correspondiente + if(!$idLibro){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + + $consulta=$conexion->prepare("INSERT INTO libros (idApi, nombreLibro, autorLibro, anoLibro, generoLibro, temaLibro, paginasLibro, edicionesLibro, idiomaLibro, ratingAvgLibro, posterLibro, sinopsisLibro) VALUES (:idApi,:nombre,:autor,:ano,:genero,:tema,:paginas,:ediciones,:idioma,:ratingAvg,:poster,:sinopsis)"); + + $consulta->bindParam(':idApi',$this->idApi); + $consulta->bindParam(':nombre',$this->nombreLibro); + $consulta->bindParam(':autor',$this->autorLibro); + $consulta->bindParam(':ano',$this->anoLibro); + $consulta->bindParam(':genero',$this->generoLibro); + $consulta->bindParam(':tema',$this->temaLibro); + $consulta->bindParam(':paginas',$this->paginasLibro); + $consulta->bindParam(':ediciones',$this->edicionesLibro); + $consulta->bindParam(':idioma',$this->idiomaLibro); + $consulta->bindParam(':ratingAvg',$this->ratingAvgLibro); + $consulta->bindParam(':poster',$this->posterLibro); + $consulta->bindParam(':sinopsis',$this->sinopsisLibro); + + $consulta->execute(); + + return $conexion->lastInsertId(); + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar el libro a la tabla libros.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + }else{ + return $idLibro; + } + + } // Fin agregar() + + public function comprobar(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT * FROM libros WHERE idLibro= :idLibro"); + + $consulta->bindParam(':idLibro', $this->idLibro); + $consulta->execute(); + + return $consulta->fetchAll(PDO::FETCH_ASSOC); + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al recoger los datos del libro seleccionado.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin comprobar() + + public function actualizarPoster(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + } + + try{ + + $consulta = $conexion->prepare( + "UPDATE libros + SET posterLibro = :poster + WHERE idLibro = :idLibro" + ); + + $consulta->bindParam( + ':poster', + $this->posterLibro + ); + + $consulta->bindParam( + ':idLibro', + $this->idLibro + ); + + $consulta->execute(); + + return $this->posterLibro; + + }catch(PDOException $error){ + + $respuesta = [ + 'error' => 'La portada se descargó, pero no se pudo actualizar la Base de Datos.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin actualizarPoster() + +} // Fin clase Libro + + +?> \ No newline at end of file diff --git a/clases/clasePelicula.php b/clases/clasePelicula.php new file mode 100644 index 0000000..3f18465 --- /dev/null +++ b/clases/clasePelicula.php @@ -0,0 +1,244 @@ +idPelicula = $idPelicula; + $this->idApi = $idApi; + $this->nombrePelicula = $nombrePelicula; + $this->directorPelicula = $directorPelicula; + $this->actorPelicula = $actorPelicula; + $this->guionistaPelicula = $guionistaPelicula; + $this->generoPelicula = $generoPelicula; + $this->anoPelicula = $anoPelicula; + $this->companiaPelicula = $companiaPelicula; + $this->duracionPelicula = $duracionPelicula; + $this->ratingAvgPelicula = $ratingAvgPelicula; + $this->paisPelicula = $paisPelicula; + $this->idiomaPelicula = $idiomaPelicula; + $this->posterPelicula = $posterPelicula; + $this->sinopsisPelicula = $sinopsisPelicula; + } // Fin __construct + + public function existe(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT idPelicula FROM peliculas WHERE idApi=:idApi"); + + $consulta->bindParam(':idApi', $this->idApi); + $consulta->execute(); + + $resultado = $consulta->fetch(PDO::FETCH_ASSOC); + + if($resultado){ + return $resultado['idPelicula']; + }else{ + return false; + } + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al comprobar si existe la película en la Base de Datos.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin existe() + + public function agregar(){ + + // Miramos si existe + $idPelicula = $this->existe($this->idApi); + + // Si no existe la creamos, y devolvemos el último idPelicula insertado + // Si existe devolvemos el idPelicula correspondiente + if(!$idPelicula){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + + $consulta=$conexion->prepare("INSERT INTO peliculas (idApi,nombrePelicula,directorPelicula,actorPelicula,guionistaPelicula,generoPelicula,anoPelicula,companiaPelicula,duracionPelicula,posterPelicula,ratingAvgPelicula,paisPelicula,idiomaPelicula,sinopsisPelicula) VALUES (:idApi,:nombre,:director,:actor,:guionista,:genero,:ano,:compania,:duracion,:poster,:ratingAvg,:pais,:idioma,:sinopsis)"); + + $consulta->bindParam(':idApi',$this->idApi); + $consulta->bindParam(':nombre',$this->nombrePelicula); + $consulta->bindParam(':director',$this->directorPelicula); + $consulta->bindParam(':actor',$this->actorPelicula); + $consulta->bindParam(':guionista',$this->guionistaPelicula); + $consulta->bindParam(':genero',$this->generoPelicula); + $consulta->bindParam(':ano',$this->anoPelicula); + $consulta->bindParam(':compania',$this->companiaPelicula); + $consulta->bindParam(':duracion',$this->duracionPelicula); + $consulta->bindParam(':ratingAvg',$this->ratingAvgPelicula); + $consulta->bindParam(':pais',$this->paisPelicula); + $consulta->bindParam(':idioma',$this->idiomaPelicula); + $consulta->bindParam(':poster',$this->posterPelicula); + $consulta->bindParam(':sinopsis',$this->sinopsisPelicula); + + $consulta->execute(); + + return $conexion->lastInsertId(); + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar la película.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + }else{ + return $idPelicula; + } + + } // Fin agregar() + + public function comprobar(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT * FROM peliculas WHERE idPelicula= :idPelicula"); + + $consulta->bindParam(':idPelicula', $this->idPelicula); + $consulta->execute(); + + return $consulta->fetchAll(PDO::FETCH_ASSOC); + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al recoger los datos de la película seleccionada.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin comprobar() + + + // Métodos para actualizar detalles + + public function listarIdApi(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + + try{ + + $consulta = $conexion->prepare(" + SELECT idPelicula, idApi + FROM peliculas + WHERE idApi IS NOT NULL + AND idApi <> '' + "); + + $consulta->execute(); + + return $consulta->fetchAll(PDO::FETCH_ASSOC); + + }catch(PDOException $error){ + + $respuesta = [ + 'error' => 'Ocurrió un error al listar las películas.', + 'error_tecnico' => $error + ]; + + $conexion = null; + + return $respuesta; + } + } + + } // Fin listarIdApi() + + public function actualizarDetalles(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + + try{ + + $consulta = $conexion->prepare(" + UPDATE peliculas SET + actorPelicula = :actor, + guionistaPelicula = :guionista, + generoPelicula = :genero, + duracionPelicula = :duracion, + companiaPelicula = :compania, + paisPelicula = :pais, + idiomaPelicula = :idioma + WHERE idPelicula = :idPelicula + "); + + $consulta->bindParam(':actor', $this->actorPelicula); + $consulta->bindParam(':guionista', $this->guionistaPelicula); + $consulta->bindParam(':genero', $this->generoPelicula); + $consulta->bindParam(':duracion', $this->duracionPelicula); + $consulta->bindParam(':compania', $this->companiaPelicula); + $consulta->bindParam(':pais', $this->paisPelicula); + $consulta->bindParam(':idioma', $this->idiomaPelicula); + $consulta->bindParam(':idPelicula', $this->idPelicula); + + $consulta->execute(); + + return true; + + }catch(PDOException $error){ + + $respuesta = [ + 'error' => 'Ocurrió un error al actualizar los detalles de la película.', + 'error_tecnico' => $error + ]; + + $conexion = null; + + return $respuesta; + } + } + + } // Fin actualizarDetalles() + +} // Fin clase Pelicula + +?> \ No newline at end of file diff --git a/clases/claseSerie.php b/clases/claseSerie.php new file mode 100644 index 0000000..decffaf --- /dev/null +++ b/clases/claseSerie.php @@ -0,0 +1,161 @@ +idSerie = $idSerie; + $this->idApi = $idApi; + $this->nombreSerie = $nombreSerie; + $this->creadorSerie = $creadorSerie; + $this->directorSerie = $directorSerie; + $this->actorSerie = $actorSerie; + $this->guionistaSerie = $guionistaSerie; + $this->companiaSerie = $companiaSerie; + $this->generoSerie = $generoSerie; + $this->anoSerie = $anoSerie; + $this->temporadasSerie = $temporadasSerie; + $this->episodiosSerie = $episodiosSerie; + $this->ratingAvgSerie = $ratingAvgSerie; + $this->paisSerie = $paisSerie; + $this->idiomaSerie = $idiomaSerie; + $this->posterSerie = $posterSerie; + $this->sinopsisSerie = $sinopsisSerie; + } // Fin __construct + + public function existe(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT idSerie FROM series WHERE idApi=:idApi"); + + $consulta->bindParam(':idApi', $this->idApi); + $consulta->execute(); + + $resultado = $consulta->fetch(PDO::FETCH_ASSOC); + + if($resultado){ + return $resultado['idSerie']; + }else{ + return false; + } + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al comprobar si existe la serie en la Base de Datos.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin existe() + + public function agregar(){ + + // Miramos si existe + $idSerie = $this->existe($this->idApi); + + // Si no existe la creamos, y devolvemos el último idSerie insertado + // Si existe devolvemos el idSerie correspondiente + if(!$idSerie){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + + $consulta=$conexion->prepare("INSERT INTO series (idApi, nombreSerie, creadorSerie, directorSerie, actorSerie, guionistaSerie, companiaSerie, generoSerie, anoSerie, temporadasSerie, episodiosSerie, ratingAvgSerie, paisSerie, idiomaSerie, posterSerie, sinopsisSerie) VALUES (:idApi,:nombre,:creador,:director,:actor,:guionista,:compania,:genero,:ano,:temporadas,:episodios,:ratingAvg,:pais,:idioma,:poster,:sinopsis)"); + + $consulta->bindParam(':idApi',$this->idApi); + $consulta->bindParam(':nombre',$this->nombreSerie); + $consulta->bindParam(':creador',$this->creadorSerie); + $consulta->bindParam(':director',$this->directorSerie); + $consulta->bindParam(':actor',$this->actorSerie); + $consulta->bindParam(':guionista',$this->guionistaSerie); + $consulta->bindParam(':compania',$this->companiaSerie); + $consulta->bindParam(':genero',$this->generoSerie); + $consulta->bindParam(':ano',$this->anoSerie); + $consulta->bindParam(':temporadas',$this->temporadasSerie); + $consulta->bindParam(':episodios',$this->episodiosSerie); + $consulta->bindParam(':ratingAvg',$this->ratingAvgSerie); + $consulta->bindParam(':pais',$this->paisSerie); + $consulta->bindParam(':idioma',$this->idiomaSerie); + $consulta->bindParam(':poster',$this->posterSerie); + $consulta->bindParam(':sinopsis',$this->sinopsisSerie); + + $consulta->execute(); + + return $conexion->lastInsertId(); + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar la serie.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + }else{ + return $idSerie; + } + + } // Fin agregar() + + public function comprobar(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT * FROM series WHERE idSerie= :idSerie"); + + $consulta->bindParam(':idSerie', $this->idSerie); + $consulta->execute(); + + return $consulta->fetchAll(PDO::FETCH_ASSOC); + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al recoger los datos de la serie seleccionada.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin comprobar() + +} // Fin clase Serie + +?> \ No newline at end of file diff --git a/clases/claseTemporada.php b/clases/claseTemporada.php new file mode 100644 index 0000000..c426d1e --- /dev/null +++ b/clases/claseTemporada.php @@ -0,0 +1,150 @@ +idTemporada = $idTemporada; + $this->idApi = $idApi; + $this->idSerie = $idSerie; + $this->nombreTemporada = $nombreTemporada; + $this->numeroTemporada = $numeroTemporada; + $this->directorTemporada = $directorTemporada; + $this->guionistaTemporada = $guionistaTemporada; + $this->actorTemporada = $actorTemporada; + $this->episodiosTemporada = $episodiosTemporada; + $this->anoTemporada = $anoTemporada; + $this->ratingAvgTemporada = $ratingAvgTemporada; + $this->posterTemporada = $posterTemporada; + $this->sinopsisTemporada = $sinopsisTemporada; + } // Fin __construct + + public function existe(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT idTemporada FROM seriestemporadas WHERE idApi=:idApi"); + + $consulta->bindParam(':idApi', $this->idApi); + $consulta->execute(); + + $resultado = $consulta->fetch(PDO::FETCH_ASSOC); + + if($resultado){ + return $resultado['idTemporada']; + }else{ + return false; + } + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al comprobar si existe la temporada en la Base de Datos.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin existe() + + public function agregar(){ + + // Miramos si existe + $idTemporada = $this->existe($this->idApi); + + // Si no existe la creamos, y devolvemos el último idTemporada insertado + // Si existe devolvemos el idTemporada correspondiente + if(!$idTemporada){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + + $consulta=$conexion->prepare("INSERT INTO seriestemporadas (idApi, idSerie, nombreTemporada, numeroTemporada, directorTemporada, guionistaTemporada, actorTemporada, episodiosTemporada, anoTemporada, ratingAvgTemporada, posterTemporada, sinopsisTemporada) VALUES (:idApi,:idSerie,:nombre,:numero,:director,:guionista,:actor,:episodios,:ano,:ratingAvg,:poster,:sinopsis)"); + + $consulta->bindParam(':idApi',$this->idApi); + $consulta->bindParam(':idSerie',$this->idSerie); + $consulta->bindParam(':nombre',$this->nombreTemporada); + $consulta->bindParam(':numero',$this->numeroTemporada); + $consulta->bindParam(':director',$this->directorTemporada); + $consulta->bindParam(':guionista',$this->guionistaTemporada); + $consulta->bindParam(':actor',$this->actorTemporada); + $consulta->bindParam(':episodios',$this->episodiosTemporada); + $consulta->bindParam(':ano',$this->anoTemporada); + $consulta->bindParam(':ratingAvg',$this->ratingAvgTemporada); + $consulta->bindParam(':poster',$this->posterTemporada); + $consulta->bindParam(':sinopsis',$this->sinopsisTemporada); + + + $consulta->execute(); + + return $conexion->lastInsertId(); + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar la temporada.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + }else{ + return $idTemporada; + } + + } // Fin agregar() + + public function comprobar(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT * FROM seriestemporadas WHERE idTemporada= :idTemporada"); + + $consulta->bindParam(':idTemporada', $this->idTemporada); + $consulta->execute(); + + return $consulta->fetchAll(PDO::FETCH_ASSOC); + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al recoger los datos de la temporada seleccionada.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin comprobar() + +} // Fin clase Temporada + +?> \ No newline at end of file diff --git a/clases/claseUsuario.php b/clases/claseUsuario.php new file mode 100644 index 0000000..d99fd5b --- /dev/null +++ b/clases/claseUsuario.php @@ -0,0 +1,349 @@ +idUsuario = $idUsuario; + $this->username = $username; + $this->nombreUsuario = $nombreUsuario; + $this->email = $email; + $this->contrasena = $contrasena; + $this->avatar = $avatar; + $this->fechaRegistro = $fechaRegistro; + } // Fin __construct() + + public function insertar(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + // Comprobamos que el username esté libre + $consulta = $conexion->prepare("SELECT * FROM usuarios WHERE username= :username"); + $consulta->bindParam(':username', $this->username); + $consulta->execute(); + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + if(count($resultado)>0){ + $respuesta = [ + 'error' => 'Este nombre de usuario ya existe.', + 'caso' => 'username' + ]; + return $respuesta; + } + + // Comprobamos que el email esté libre + $consulta = $conexion->prepare("SELECT * FROM usuarios WHERE email= :email"); + $consulta->bindParam(':email', $this->email); + $consulta->execute(); + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + if(count($resultado)>0){ + $respuesta = [ + 'error' => 'Ya existe un usuario con este correo.', + 'caso' => 'email' + ]; + return $respuesta; + } + + $consulta = $conexion->prepare("INSERT INTO usuarios (idUsuario, username, nombreUsuario, email, contrasena, avatar, fechaRegistro) VALUES (:idUsuario, :username, :nombreUsuario, :email, :contrasena, :avatar, :fechaRegistro)"); + + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':username', $this->username); + $consulta->bindParam(':nombreUsuario', $this->nombreUsuario); + $consulta->bindParam(':email', $this->email); + $consulta->bindParam(':avatar', $this->avatar); + + $fechaRegistro=date('Y/m/d'); + $consulta->bindParam(':fechaRegistro', $fechaRegistro); + + // Ciframos la contraseña + $pass = password_hash($this->contrasena, PASSWORD_DEFAULT); + $consulta->bindParam(':contrasena', $pass); + + $consulta->execute(); + + // Inciamos la sesión al registrarse + $this->idUsuario = $conexion->lastInsertId(); + + $_SESSION['idUsuario'] = $this->idUsuario; + $_SESSION['username'] = $this->username; + + $respuesta = [ + 'exito' => 'El usuario se registró correctamente.', + 'id' => $conexion->lastInsertId() + ]; + + return $respuesta; + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al crear al usuario.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin insertar() + + public function validar(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + + $consulta = $conexion->prepare("SELECT * FROM usuarios WHERE username= :identificador OR email= :identificador"); + $consulta->bindParam(':identificador', $this->identificador); + $consulta->execute(); + + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + + // Si el usuario no existe + if(count($resultado)==0){ + $respuesta = ['error' => 'Usuario o contrasena incorrectos.']; + return $respuesta; + } + + $pass = $resultado[0]['contrasena']; + + if(password_verify($this->contrasena, $pass)){ + // La pass es correcta, el usuario estÔ validado + + // Actualizamos variables y también el objeto actual, para que se sepa qué usuario tiene sesión iniciado en cualquier pÔgina del proyecto + $_SESSION['idUsuario'] = $resultado[0]['idUsuario']; + $_SESSION['username'] = $resultado[0]['username']; + $_SESSION['nombreUsuario'] = $resultado[0]['nombreUsuario']; + $_SESSION['avatar'] = $resultado[0]['avatar']; + + $this->idUsuario = $resultado[0]['idUsuario']; + $this->username = $resultado[0]['username']; + $this->nombreUsuario = $resultado[0]['nombreUsuario']; + $this->email = $resultado[0]['email']; + $this->avatar = $resultado[0]['avatar']; + $this->fechaRegistro = $resultado[0]['fechaRegistro']; + + // Almacenamos datos que usaremos en la respuesta + $respuesta = [ + 'exito' => 'Usuario validado.', + 'nombreUsuario' => $resultado[0]['nombreUsuario'] + ]; + return $respuesta; + }else{ + // pass incorrecta + // Eliminamos los datos por si hubiera alguna sesión iniciado si alguien ha introducido mal la contraseña + unset($_SESSION['idUsuario']); + unset($_SESSION['nombreUsuario']); + unset($_SESSION['username']); + + $this->idUsuario = null; + $this->username = null; + $this->nombreUsuario = null; + $this->email = null; + $this->avatar = null; + $this->fechaRegistro = null; + + $respuesta = ['error' => 'Usuario o contrasena incorrectos.']; + return $respuesta; + } + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al validar al usuario.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin validar() + + public function editarNombre(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuarios SET nombreUsuario=:nombre WHERE idUsuario=:id"); + + $consulta->bindParam(':id', $this->idUsuario); + $consulta->bindParam(':nombre', $this->nombreUsuario); + + $consulta->execute(); + + $_SESSION['nombreUsuario'] = $this->nombreUsuario; + + $respuesta = [ + 'exito' => 'El nombre de usuario se editó correctamente.', + 'exito_tecnico' => $this->nombreUsuario + ]; + + return $respuesta; + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al editar el nombre del usuario.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin editarNombre() + + public function editarAvatar(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + } + try{ + if(!isset($_FILES['avatar']) || !isset($_FILES['avatar']['error'])){ + return [ + 'error' => 'No se recibió ninguna imagen.' + ]; + } + + if($_FILES['avatar']['error'] !== UPLOAD_ERR_OK){ + return [ + 'error' => 'No se pudo subir la imagen.' + ]; + } + + if($_FILES['avatar']['size'] > 5 * 1024 * 1024){ + return [ + 'error' => 'El avatar no puede superar los 5 MB.' + ]; + } + + $finfo = new finfo(FILEINFO_MIME_TYPE); + $tiposPermitidos = [ + 'image/jpeg' => 'jpg', + 'image/png' => 'png', + 'image/webp' => 'webp' + ]; + + $mime = $finfo->file( + $_FILES['avatar']['tmp_name'] + ); + + + if(!isset($tiposPermitidos[$mime])){ + return [ + 'error' => 'El archivo debe ser una imagen JPG, PNG o WEBP.' + ]; + } + + if(@getimagesize($_FILES['avatar']['tmp_name']) === false){ + return [ + 'error' => 'El archivo seleccionado no es una imagen vÔlida.' + ]; + } + + // Creamos la carpeta física + $carpeta = $_SERVER['DOCUMENT_ROOT'].'/MyDiary/images/avatars/'; + + if(!is_dir($carpeta)){ + if(!mkdir($carpeta, 0755, true)){ + return [ + 'error' => 'No se pudo crear la carpeta de avatares.' + ]; + } + } + + $extension = $tiposPermitidos[$mime]; + $nombreArchivo = $this->idUsuario.'.'.$extension; + $rutaFisica = $carpeta.$nombreArchivo; + + // Eliminamos posibles avatares anteriores de este usuario + $extensiones = ['jpg', 'png', 'webp']; + foreach($extensiones as $extensionAnterior){ + $archivoAnterior = $carpeta.$this->idUsuario.'.'.$extensionAnterior; + if(file_exists($archivoAnterior) && $archivoAnterior !== $rutaFisica){ + unlink($archivoAnterior); + } + } + + if(!move_uploaded_file($_FILES['avatar']['tmp_name'],$rutaFisica)){ + return [ + 'error' => 'No se pudo guardar el avatar.' + ]; + } + + $rutaBD ='images/avatars/'.$nombreArchivo; + + + // Actualizamos el usuario + $consulta = $conexion->prepare("UPDATE usuarios SET avatar = :avatar WHERE idUsuario = :idUsuario"); + + $consulta->bindParam(':avatar', $rutaBD); + $consulta->bindParam(':idUsuario',$this->idUsuario); + + $consulta->execute(); + + // Lo guardamos ya en la sesión actual + $_SESSION['avatar'] = $rutaBD; + + return [ + 'exito' => true, + 'avatar' => $rutaBD + ]; + + }catch(PDOException $error){ + return [ + 'error' => 'Ocurrió un error al actualizar el avatar.', + 'error_tecnico' => $error + ]; + } + + } // Fin editarAvatar() + + public function cerrarSesion(){ + + $_SESSION = []; + session_destroy(); + + $respuesta = [ + 'exito' => 'La sesión se ha cerrado correctamente' + ]; + + return $respuesta; + } // Fin cerrarSesion() + +} // Fin de la clase Usuario + + +/* +$usuario = new Usuario(); +$usuario->username = 'isaac'; +$usuario->nombreUsuario = 'Isaac'; +$usuario->email = 'isaac.espi@hotmail.es'; +$usuario->contrasena = '1234'; + +$resultado = $usuario->insertar(); +var_dump($resultado); + +echo '
'; + +$resultado = $usuario->validar(); +var_dump($resultado); +*/ + + +?> \ No newline at end of file diff --git a/clases/claseUsuarioxEpisodio.php b/clases/claseUsuarioxEpisodio.php new file mode 100644 index 0000000..5fec8e0 --- /dev/null +++ b/clases/claseUsuarioxEpisodio.php @@ -0,0 +1,514 @@ +idUsuarioEpisodio = $idUsuarioEpisodio; + $this->idUsuario = $idUsuario; + $this->idEpisodio = $idEpisodio; + $this->ratingEpisodio = $ratingEpisodio; + $this->favEpisodio = $favEpisodio; + $this->pendienteEpisodio = $pendienteEpisodio; + $this->fechaEpisodio = $fechaEpisodio; + $this->notasEpisodio = $notasEpisodio; + } // Fin __construct + + public function agregar(){ + + $conexion=conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta=$conexion->prepare("INSERT INTO usuariosxepisodios (idUsuario, idEpisodio, ratingEpisodio, favEpisodio, pendienteEpisodio, fechaEpisodio, notasEpisodio) VALUES (:idUsuario,:idEpisodio, :rating, :fav, :pend, :fecha, :notas)"); + + $consulta->bindParam(':idUsuario',$this->idUsuario); + $consulta->bindParam(':idEpisodio',$this->idEpisodio); + $consulta->bindParam(':rating',$this->ratingEpisodio); + $consulta->bindParam(':fav',$this->favEpisodio); + $pend=0; + $consulta->bindParam(':pend',$pend); + $consulta->bindParam(':fecha',$this->fechaEpisodio); + $consulta->bindParam(':notas',$this->notasEpisodio); + + $consulta->execute(); + return $conexion->lastInsertId(); + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar el episodio.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin agregar() + + public function existe(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT idUsuarioEpisodio FROM usuariosxepisodios WHERE idEpisodio=:idEpisodio AND idUsuario=:idUsuario"); + + $consulta->bindParam(':idEpisodio', $this->idEpisodio); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetch(PDO::FETCH_ASSOC); + + if($resultado){ + $respuesta = [ + 'error' => 'Ya has registrado este episodio', + 'error_tecnico' => $this->idEpisodio + ]; + $conexion = null; + return $respuesta; + }else{ + return false; + } + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al comprobar si existe el episodio en la Base de Datos.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin existe() + + public function listarTodo(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT p.idEpisodio, p.idApi, p.idTemporada, p.nombreEpisodio, p.numeroEpisodio, p.directorEpisodio, p.actorEpisodio, p.guionistaEpisodio, p.anoEpisodio, p.duracionEpisodio, p.ratingAvgEpisodio, p.posterEpisodio, p.sinopsisEpisodio, up.idUsuarioEpisodio, up.idUsuario, up.idEpisodio, up.ratingEpisodio, up.favEpisodio, up.pendienteEpisodio, up.fechaEpisodio, up.notasEpisodio FROM usuariosxepisodios up INNER JOIN seriesepisodios p ON up.idEpisodio = p.idEpisodio WHERE up.idUsuario = :idUsuario AND up.pendienteEpisodio = :pend ORDER BY up.fechaEpisodio DESC, up.idUsuarioEpisodio DESC"); + + $pend=0; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de episodios.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarTodo() + + public function listarEstrellas(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT p.idEpisodio, p.idApi, p.idTemporada, p.nombreEpisodio, p.numeroEpisodio, p.directorEpisodio, p.actorEpisodio, p.guionistaEpisodio, p.anoEpisodio, p.duracionEpisodio, p.ratingAvgEpisodio, p.posterEpisodio, p.sinopsisEpisodio, up.idUsuarioEpisodio, up.idUsuario, up.idEpisodio, up.ratingEpisodio, up.favEpisodio, up.pendienteEpisodio, up.fechaEpisodio, up.notasEpisodio FROM usuariosxepisodios up INNER JOIN seriesepisodios p ON up.idEpisodio = p.idEpisodio WHERE up.ratingEpisodio = :rating AND up.idUsuario = :idUsuario AND up.pendienteEpisodio = :pend ORDER BY up.fechaEpisodio DESC, up.idUsuarioEpisodio DESC"); + + $pend=0; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':rating', $this->ratingEpisodio); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de episodios con valoracion '.$this->ratingEpisodio, + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarEstrellas() + + public function listarFav(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT p.idEpisodio, p.idApi, p.idTemporada, p.nombreEpisodio, p.numeroEpisodio, p.directorEpisodio, p.actorEpisodio, p.guionistaEpisodio, p.anoEpisodio, p.duracionEpisodio, p.ratingAvgEpisodio, p.posterEpisodio, p.sinopsisEpisodio, up.idUsuarioEpisodio, up.idUsuario, up.idEpisodio, up.ratingEpisodio, up.favEpisodio, up.pendienteEpisodio, up.fechaEpisodio, up.notasEpisodio FROM usuariosxepisodios up INNER JOIN seriesepisodios p ON up.idEpisodio = p.idEpisodio WHERE up.favEpisodio = :fav AND up.idUsuario = :idUsuario AND up.pendienteEpisodio = :pend ORDER BY up.fechaEpisodio DESC, up.idUsuarioEpisodio DESC"); + + $fav = 1; + $consulta->bindParam(':fav', $fav); + $pend=0; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de episodios favoritos.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarFav() + + public function listarPendientes(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT p.idEpisodio, p.idApi, p.idTemporada, p.nombreEpisodio, p.numeroEpisodio, p.directorEpisodio, p.actorEpisodio, p.guionistaEpisodio, p.anoEpisodio, p.duracionEpisodio, p.ratingAvgEpisodio, p.posterEpisodio, p.sinopsisEpisodio, up.idUsuarioEpisodio, up.idUsuario, up.idEpisodio, up.ratingEpisodio, up.favEpisodio, up.pendienteEpisodio, up.fechaEpisodio, up.notasEpisodio FROM usuariosxepisodios up INNER JOIN seriesepisodios p ON up.idEpisodio = p.idEpisodio WHERE up.pendienteEpisodio = :pend AND up.idUsuario = :idUsuario"); + + $pend = 1; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':idUsuario', $this->idUsuario); + + $consulta->execute(); + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de episodios pendientes.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarPendientes() + + public function agregarPend(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("INSERT INTO usuariosxepisodios (idUsuario, idEpisodio, pendienteEpisodio) VALUES (:idUsuario, :idEpisodio, :pend)"); + + $pend = 1; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':idEpisodio', $this->idEpisodio); + + $consulta->execute(); + return $conexion->lastInsertId(); + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar el episodio como pendiente.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin agregarPend() + + public function buscar(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $busqueda = $_POST['busqueda']; + + if(is_numeric($busqueda)){ + + $consulta = $conexion->prepare("SELECT p.idEpisodio, p.idApi, p.idTemporada, p.nombreEpisodio, p.numeroEpisodio, p.directorEpisodio, p.actorEpisodio, p.guionistaEpisodio, p.anoEpisodio, p.duracionEpisodio, p.ratingAvgEpisodio, p.posterEpisodio, p.sinopsisEpisodio, up.idUsuarioEpisodio, up.idUsuario, up.idEpisodio, up.ratingEpisodio, up.favEpisodio, up.pendienteEpisodio, up.fechaEpisodio, up.notasEpisodio FROM usuariosxepisodios up INNER JOIN seriesepisodios p ON up.idEpisodio = p.idEpisodio WHERE p.anoEpisodio=:ano AND up.idUsuario=:idUsuario ORDER BY up.ratingEpisodio DESC, up.fechaEpisodio DESC, up.idUsuarioEpisodio DESC"); + + $consulta->bindParam(':ano', $busqueda); + $consulta->bindParam(':idUsuario', $this->idUsuario); + + }else{ + $busquedaParcial = "%" . $_POST['busqueda'] . "%"; + + $consulta = $conexion->prepare("SELECT p.idEpisodio, p.idApi, p.idTemporada, p.nombreEpisodio, p.numeroEpisodio, p.directorEpisodio, p.actorEpisodio, p.guionistaEpisodio, p.anoEpisodio, p.duracionEpisodio, p.ratingAvgEpisodio, p.posterEpisodio, p.sinopsisEpisodio, up.idUsuarioEpisodio, up.idUsuario, up.idEpisodio, up.ratingEpisodio, up.favEpisodio, up.pendienteEpisodio, up.fechaEpisodio, up.notasEpisodio FROM usuariosxepisodios up INNER JOIN seriesepisodios p ON up.idEpisodio = p.idEpisodio WHERE up.idUsuario=:idUsuario AND (p.nombreEpisodio LIKE :nombre OR p.directorEpisodio LIKE :director) ORDER BY up.ratingEpisodio DESC, up.fechaEpisodio DESC, up.idUsuarioEpisodio DESC"); + + $consulta->bindParam(':nombre', $busquedaParcial); + $consulta->bindParam(':director', $busquedaParcial); + $consulta->bindParam(':idUsuario', $this->idUsuario); + } + + $consulta->execute(); + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de episodios buscados.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin buscar() + + public function favorita(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxepisodios SET favEpisodio= :fav WHERE idUsuarioEpisodio = :idUsuarioEpisodio AND idUsuario=:idUsuario AND pendienteEpisodio=:pend"); + + $consulta->bindParam(':idUsuarioEpisodio', $this->idUsuarioEpisodio); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':fav', $this->favEpisodio); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + return [ + 'exito' => true, + 'idUsuarioEpisodio' => $this->idUsuarioEpisodio, + 'favEpisodio' => $this->favEpisodio + ]; + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al cambiar el estado favorita del episodio.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin favorita() + + public function comprobar(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT * FROM usuariosxepisodios WHERE idUsuarioEpisodio= :idUsuarioEpisodio AND idUsuario=:idUsuario"); + $consulta->bindParam(':idUsuarioEpisodio', $this->idUsuarioEpisodio); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + return $consulta->fetchAll(PDO::FETCH_ASSOC); + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al recoger los datos del episodio seleccionado.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin comprobar() + + function editarVal(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxepisodios SET ratingEpisodio=:rating WHERE idUsuarioEpisodio=:id AND idUsuario=:idUsuario AND pendienteEpisodio=:pend"); + + $consulta->bindParam(':rating', $this->ratingEpisodio); + $consulta->bindParam(':id', $this->idUsuarioEpisodio); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se editó correctamente la valoración del episodio.', + 'exito_tecnico' => $this->ratingEpisodio + ]; + return $respuesta; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al editar la valoración del episodio.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin editarVal() + + function editarFecha(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxepisodios SET fechaEpisodio=:fecha WHERE idUsuarioEpisodio= :id AND idUsuario=:idUsuario AND pendienteEpisodio=:pend"); + + $consulta->bindParam(':id', $this->idUsuarioEpisodio); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':fecha', $this->fechaEpisodio); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se editó correctamente la fecha de visualización del episodio.', + 'exito_tecnico' => $this->fechaEpisodio + ]; + return $respuesta; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al editar la fecha de visualización del episodio.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin editarFecha() + + function editarNotas(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxepisodios SET notasEpisodio=:notas WHERE idUsuarioEpisodio= :id AND idUsuario=:idUsuario AND pendienteEpisodio=:pend"); + + $consulta->bindParam(':id', $this->idUsuarioEpisodio); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':notas', $this->notasEpisodio); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se editó correctamente las notas del episodio.', + 'exito_tecnico' => $this->fechaEpisodio + ]; + return $respuesta; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al editar las notas del episodio.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin editarNotas() + + function agregarPendTabla(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxepisodios SET pendienteEpisodio=:pend, fechaEpisodio=:fecha, ratingEpisodio=:rating, favEpisodio=:fav, notasEpisodio=:notas WHERE idUsuarioEpisodio= :id AND idUsuario=:idUsuario"); + + $consulta->bindParam(':id', $this->idUsuarioEpisodio); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':fecha', $this->fechaEpisodio); + $consulta->bindParam(':rating', $this->ratingEpisodio); + $consulta->bindParam(':fav', $this->favEpisodio); + $consulta->bindParam(':notas', $this->notasEpisodio); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + return $this->idUsuarioEpisodio; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar el episodio pendiente.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin agregarPendTabla + + function eliminar(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + + $consulta = $conexion->prepare("DELETE FROM usuariosxepisodios WHERE idUsuarioEpisodio=:id AND idUsuario=:idUsuario"); + $consulta->bindParam(':id', $this->idUsuarioEpisodio); + $consulta->bindParam(':idUsuario', $this->idUsuario); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se eliminó correctamente el episodio.', + 'exito_tecnico' => $this->idUsuarioEpisodio, + ]; + return $respuesta; + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al eliminar el episodio.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin eliminar() + +} // Fin clase UsuarioxEpisodio + +?> \ No newline at end of file diff --git a/clases/claseUsuarioxJuego.php b/clases/claseUsuarioxJuego.php new file mode 100644 index 0000000..19677d1 --- /dev/null +++ b/clases/claseUsuarioxJuego.php @@ -0,0 +1,557 @@ +idUsuarioJuego = $idUsuarioJuego; + $this->idUsuario = $idUsuario; + $this->idJuego = $idJuego; + $this->ratingJuego = $ratingJuego; + $this->favJuego = $favJuego; + $this->pendienteJuego = $pendienteJuego; + $this->fechaInicioJuego = $fechaInicioJuego; + $this->fechaJuego = $fechaJuego; + $this->plataformaJuego = $plataformaJuego; + $this->notasJuego = $notasJuego; + } // Fin __construct + + public function agregar(){ + + $conexion=conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta=$conexion->prepare("INSERT INTO usuariosxjuegos (idUsuario, idJuego, ratingJuego, favJuego, pendienteJuego, fechaJuego, notasJuego, fechaInicioJuego, plataformaJuego) VALUES (:idUsuario,:idJuego, :rating, :fav, :pend, :fecha, :notas, :fechaInicio, :plat)"); + + $consulta->bindParam(':idUsuario',$this->idUsuario); + $consulta->bindParam(':idJuego',$this->idJuego); + $consulta->bindParam(':rating',$this->ratingJuego); + $consulta->bindParam(':fav',$this->favJuego); + $pend=0; + $consulta->bindParam(':pend',$pend); + $consulta->bindParam(':fecha',$this->fechaJuego); + $consulta->bindParam(':notas',$this->notasJuego); + $consulta->bindParam(':fechaInicio',$this->fechaInicioJuego); + $consulta->bindParam(':plat',$this->plataformaJuego); + + $consulta->execute(); + return $conexion->lastInsertId(); + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar el videojuego.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin agregar() + + public function existe(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT idUsuarioJuego FROM usuariosxjuegos WHERE idJuego=:idJuego AND idUsuario=:idUsuario"); + + $consulta->bindParam(':idJuego', $this->idJuego); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetch(PDO::FETCH_ASSOC); + + if($resultado){ + $respuesta = [ + 'error' => 'Ya has registrado este videojuego', + 'error_tecnico' => $this->idJuego + ]; + $conexion = null; + return $respuesta; + }else{ + return false; + } + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al comprobar si existe el videojuego en la Base de Datos.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin existe() + + public function listarTodo(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT p.idJuego, p.idApi, p.nombreJuego, p.desarrolladorJuego, p.editorJuego, p.anoJuego, p.franquiciaJuego, p.generoJuego, p.plataformasJuego, p.dlcJuego, p.expansionJuego, p.duracionJuego, p.ratingAvgJuego, p.posterJuego, p.sinopsisJuego, up.idUsuarioJuego, up.idUsuario, up.idJuego, up.fechaJuego, up.ratingJuego, up.favJuego, up.pendienteJuego, up.notasJuego, up.plataformaJuego, up.fechaInicioJuego FROM usuariosxjuegos up INNER JOIN juegos p ON up.idJuego = p.idJuego WHERE up.idUsuario = :idUsuario AND up.pendienteJuego = :pend ORDER BY up.fechaJuego DESC, up.idUsuarioJuego DESC"); + + $pend=0; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de videojuegos.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarTodo() + + public function listarEstrellas(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT p.idJuego, p.idApi, p.nombreJuego, p.desarrolladorJuego, p.editorJuego, p.anoJuego, p.franquiciaJuego, p.generoJuego, p.plataformasJuego, p.dlcJuego, p.expansionJuego, p.duracionJuego, p.ratingAvgJuego, p.posterJuego, p.sinopsisJuego, up.idUsuarioJuego, up.idUsuario, up.idJuego, up.fechaJuego, up.ratingJuego, up.favJuego, up.pendienteJuego, up.notasJuego, up.plataformaJuego, up.fechaInicioJuego FROM usuariosxjuegos up INNER JOIN juegos p ON up.idJuego = p.idJuego WHERE up.ratingJuego = :rating AND up.idUsuario = :idUsuario AND up.pendienteJuego = :pend ORDER BY up.fechaJuego DESC, up.idUsuarioJuego DESC"); + + $pend=0; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':rating', $this->ratingJuego); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de videojuegos con valoracion '.$this->ratingJuego, + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarEstrellas() + + public function listarFav(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT p.idJuego, p.idApi, p.nombreJuego, p.desarrolladorJuego, p.editorJuego, p.anoJuego, p.franquiciaJuego, p.generoJuego, p.plataformasJuego, p.dlcJuego, p.expansionJuego, p.duracionJuego, p.ratingAvgJuego, p.posterJuego, p.sinopsisJuego, up.idUsuarioJuego, up.idUsuario, up.idJuego, up.fechaJuego, up.ratingJuego, up.favJuego, up.pendienteJuego, up.notasJuego, up.plataformaJuego, up.fechaInicioJuego FROM usuariosxjuegos up INNER JOIN juegos p ON up.idJuego = p.idJuego WHERE up.favJuego = :fav AND up.idUsuario = :idUsuario AND up.pendienteJuego = :pend ORDER BY up.fechaJuego DESC, up.idUsuarioJuego DESC"); + + $fav = 1; + $consulta->bindParam(':fav', $fav); + $pend=0; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de videojuegos favoritos.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarFav() + + public function listarPendientes(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT p.idJuego, p.idApi, p.nombreJuego, p.desarrolladorJuego, p.editorJuego, p.anoJuego, p.franquiciaJuego, p.generoJuego, p.plataformasJuego, p.dlcJuego, p.expansionJuego, p.duracionJuego, p.ratingAvgJuego, p.posterJuego, p.sinopsisJuego, up.idUsuarioJuego, up.idUsuario, up.idJuego, up.fechaJuego, up.ratingJuego, up.favJuego, up.pendienteJuego, up.notasJuego, up.plataformaJuego, up.fechaInicioJuego FROM usuariosxjuegos up INNER JOIN juegos p ON up.idJuego = p.idJuego WHERE up.pendienteJuego = :pend AND up.idUsuario = :idUsuario"); + + $pend = 1; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':idUsuario', $this->idUsuario); + + $consulta->execute(); + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de videojuegos pendientes.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarPendientes() + + public function agregarPend(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("INSERT INTO usuariosxjuegos (idUsuario, idJuego, pendienteJuego) VALUES (:idUsuario, :idJuego, :pend)"); + + $pend = 1; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':idJuego', $this->idJuego); + + $consulta->execute(); + return $conexion->lastInsertId(); + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar el videojuego como pendiente.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin agregarPend() + + public function buscar(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $busqueda = $_POST['busqueda']; + + if(is_numeric($busqueda)){ + + $consulta = $conexion->prepare("SELECT p.idJuego, p.idApi, p.nombreJuego, p.desarrolladorJuego, p.editorJuego, p.anoJuego, p.franquiciaJuego, p.generoJuego, p.plataformasJuego, p.dlcJuego, p.expansionJuego, p.duracionJuego, p.ratingAvgJuego, p.posterJuego, p.sinopsisJuego, up.idUsuarioJuego, up.idUsuario, up.idJuego, up.fechaJuego, up.ratingJuego, up.favJuego, up.pendienteJuego, up.notasJuego, up.plataformaJuego, up.fechaInicioJuego FROM usuariosxjuegos up INNER JOIN juegos p ON up.idJuego = p.idJuego WHERE p.anoJuego=:ano AND up.idUsuario=:idUsuario ORDER BY up.ratingJuego DESC, up.fechaJuego DESC, up.idUsuarioJuego DESC"); + + $consulta->bindParam(':ano', $busqueda); + $consulta->bindParam(':idUsuario', $this->idUsuario); + + }else{ + $busquedaParcial = "%" . $_POST['busqueda'] . "%"; + + $consulta = $conexion->prepare("SELECT p.idJuego, p.idApi, p.nombreJuego, p.desarrolladorJuego, p.editorJuego, p.anoJuego, p.franquiciaJuego, p.generoJuego, p.plataformasJuego, p.dlcJuego, p.expansionJuego, p.duracionJuego, p.ratingAvgJuego, p.posterJuego, p.sinopsisJuego, up.idUsuarioJuego, up.idUsuario, up.idJuego, up.fechaJuego, up.ratingJuego, up.favJuego, up.pendienteJuego, up.notasJuego, up.plataformaJuego, up.fechaInicioJuego FROM usuariosxjuegos up INNER JOIN juegos p ON up.idJuego = p.idJuego WHERE up.idUsuario=:idUsuario AND (p.nombreJuego LIKE :nombre OR p.desarrolladorJuego LIKE :desarrollador) ORDER BY up.ratingJuego DESC, up.fechaJuego DESC, up.idUsuarioJuego DESC"); + + $consulta->bindParam(':nombre', $busquedaParcial); + $consulta->bindParam(':desarrollador', $busquedaParcial); + $consulta->bindParam(':idUsuario', $this->idUsuario); + } + + $consulta->execute(); + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de videojuegos buscados.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin buscar() + + public function favorita(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxjuegos SET favJuego= :fav WHERE idUsuarioJuego = :idUsuarioJuego AND idUsuario=:idUsuario AND pendienteJuego=:pend"); + + $consulta->bindParam(':idUsuarioJuego', $this->idUsuarioJuego); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':fav', $this->favJuego); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + return [ + 'exito' => true, + 'idUsuarioJuego' => $this->idUsuarioJuego, + 'favJuego' => $this->favJuego + ]; + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al cambiar el estado favorita del videojuego.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin favorita() + + public function comprobar(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT * FROM usuariosxjuegos WHERE idUsuarioJuego= :idUsuarioJuego AND idUsuario=:idUsuario"); + $consulta->bindParam(':idUsuarioJuego', $this->idUsuarioJuego); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + return $consulta->fetchAll(PDO::FETCH_ASSOC); + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al recoger los datos del videojuego seleccionado.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin comprobar() + + function editarVal(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxjuegos SET ratingJuego=:rating WHERE idUsuarioJuego=:id AND idUsuario=:idUsuario AND pendienteJuego=:pend"); + + $consulta->bindParam(':rating', $this->ratingJuego); + $consulta->bindParam(':id', $this->idUsuarioJuego); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se editó correctamente la valoración del videojuego.', + 'exito_tecnico' => $this->ratingJuego + ]; + return $respuesta; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al editar la valoración del videojuego.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin editarVal() + + function editarFecha(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxjuegos SET fechaJuego=:fecha, fechaInicioJuego=:fechaInicio WHERE idUsuarioJuego= :id AND idUsuario=:idUsuario AND pendienteJuego=:pend"); + + $consulta->bindParam(':id', $this->idUsuarioJuego); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':fecha', $this->fechaJuego); + $consulta->bindParam(':fechaInicio', $this->fechaInicioJuego); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se editó correctamente la fecha de visualización del videojuego.', + 'exito_tecnico' => $this->fechaJuego + ]; + return $respuesta; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al editar la fecha de visualización del videojuego.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin editarFecha() + + function editarPlataforma(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxjuegos SET plataformaJuego=:plat WHERE idUsuarioJuego=:id AND idUsuario=:idUsuario AND pendienteJuego=:pend"); + + $consulta->bindParam(':plat', $this->plataformaJuego); + $consulta->bindParam(':id', $this->idUsuarioJuego); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se editó correctamente la plataforma del videojuego.', + 'exito_tecnico' => $this->plataformaJuego + ]; + return $respuesta; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al editar la plataforma del videojuego.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin editarPlataforma() + + function editarNotas(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxjuegos SET notasJuego=:notas WHERE idUsuarioJuego= :id AND idUsuario=:idUsuario AND pendienteJuego=:pend"); + + $consulta->bindParam(':id', $this->idUsuarioJuego); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':notas', $this->notasJuego); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se editó correctamente las notas del videojuego.', + 'exito_tecnico' => $this->fechaJuego + ]; + return $respuesta; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al editar las notas del videojuego.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin editarNotas() + + function agregarPendTabla(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxjuegos SET pendienteJuego=:pend, fechaJuego=:fecha, fechaInicioJuego=:fechaInicio, ratingJuego=:rating, favJuego=:fav, notasJuego=:notas, plataformaJuego=:plat WHERE idUsuarioJuego= :id AND idUsuario=:idUsuario"); + + $consulta->bindParam(':id', $this->idUsuarioJuego); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':fecha', $this->fechaJuego); + $consulta->bindParam(':fechaInicio', $this->fechaInicioJuego); + $consulta->bindParam(':rating', $this->ratingJuego); + $consulta->bindParam(':fav', $this->favJuego); + $consulta->bindParam(':notas', $this->notasJuego); + $consulta->bindParam(':plat', $this->plataformaJuego); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + return $this->idUsuarioJuego; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar el videojuego pendiente.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin agregarPendTabla + + function eliminar(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + + $consulta = $conexion->prepare("DELETE FROM usuariosxjuegos WHERE idUsuarioJuego=:id AND idUsuario=:idUsuario"); + $consulta->bindParam(':id', $this->idUsuarioJuego); + $consulta->bindParam(':idUsuario', $this->idUsuario); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se eliminó correctamente el videojuego.', + 'exito_tecnico' => $this->idUsuarioJuego, + ]; + return $respuesta; + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al eliminar el videojuego.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin eliminar() + +} // Fin clase UsuarioxJuego + +?> \ No newline at end of file diff --git a/clases/claseUsuarioxLibro.php b/clases/claseUsuarioxLibro.php new file mode 100644 index 0000000..9e00b66 --- /dev/null +++ b/clases/claseUsuarioxLibro.php @@ -0,0 +1,520 @@ +idUsuarioLibro = $idUsuarioLibro; + $this->idUsuario = $idUsuario; + $this->idLibro = $idLibro; + $this->ratingLibro = $ratingLibro; + $this->favLibro = $favLibro; + $this->pendienteLibro = $pendienteLibro; + $this->fechaInicioLibro = $fechaInicioLibro; + $this->fechaLibro = $fechaLibro; + $this->notasLibro = $notasLibro; + } // Fin __construct + + public function agregar(){ + + $conexion=conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta=$conexion->prepare("INSERT INTO usuariosxlibros (idUsuario, idLibro, ratingLibro, favLibro, pendienteLibro, fechaLibro, notasLibro, fechaInicioLibro) VALUES (:idUsuario, :idLibro, :rating, :fav, :pend, :fecha, :notas, :fechaInicio)"); + + $consulta->bindParam(':idUsuario',$this->idUsuario); + $consulta->bindParam(':idLibro',$this->idLibro); + $consulta->bindParam(':rating',$this->ratingLibro); + $consulta->bindParam(':fav',$this->favLibro); + $pend=0; + $consulta->bindParam(':pend',$pend); + $consulta->bindParam(':fecha',$this->fechaLibro); + $consulta->bindParam(':notas',$this->notasLibro); + $consulta->bindParam(':fechaInicio',$this->fechaInicioLibro); + + $consulta->execute(); + return $conexion->lastInsertId(); + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar el libro.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin agregar() + + public function existe(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT idUsuarioLibro FROM usuariosxlibros WHERE idLibro=:idLibro AND idUsuario=:idUsuario"); + + $consulta->bindParam(':idLibro', $this->idLibro); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetch(PDO::FETCH_ASSOC); + + if($resultado){ + $respuesta = [ + 'error' => 'Ya has registrado este libro', + 'error_tecnico' => $this->idLibro + ]; + $conexion = null; + return $respuesta; + }else{ + return false; + } + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al comprobar si existe el libro en la Base de Datos.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin existe() + + public function listarTodo(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT p.idLibro, p.idApi, p.nombreLibro, p.autorLibro, p.anoLibro, p.generoLibro, p.temaLibro, p.paginasLibro, p.edicionesLibro, p.idiomaLibro, p.ratingAvgLibro, p.posterLibro, p.sinopsisLibro, up.idUsuarioLibro, up.idUsuario, up.idLibro, up.fechaLibro, up.ratingLibro, up.favLibro, up.pendienteLibro, up.notasLibro, up.fechaInicioLibro FROM usuariosxlibros up INNER JOIN libros p ON up.idLibro = p.idLibro WHERE up.idUsuario = :idUsuario AND up.pendienteLibro = :pend ORDER BY up.fechaLibro DESC, up.idUsuarioLibro DESC"); + + $pend=0; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de libros.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarTodo() + + public function listarEstrellas(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT p.idLibro, p.idApi, p.nombreLibro, p.autorLibro, p.anoLibro, p.generoLibro, p.temaLibro, p.paginasLibro, p.edicionesLibro, p.idiomaLibro, p.ratingAvgLibro, p.posterLibro, p.sinopsisLibro, up.idUsuarioLibro, up.idUsuario, up.idLibro, up.fechaLibro, up.ratingLibro, up.favLibro, up.pendienteLibro, up.notasLibro, up.fechaInicioLibro FROM usuariosxlibros up INNER JOIN libros p ON up.idLibro = p.idLibro WHERE up.ratingLibro = :rating AND up.idUsuario = :idUsuario AND up.pendienteLibro = :pend ORDER BY up.fechaLibro DESC, up.idUsuarioLibro DESC"); + + $pend=0; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':rating', $this->ratingLibro); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de libros con valoracion '.$this->ratingLibro, + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarEstrellas() + + public function listarFav(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT p.idLibro, p.idApi, p.nombreLibro, p.autorLibro, p.anoLibro, p.generoLibro, p.temaLibro, p.paginasLibro, p.edicionesLibro, p.idiomaLibro, p.ratingAvgLibro, p.posterLibro, p.sinopsisLibro, up.idUsuarioLibro, up.idUsuario, up.idLibro, up.fechaLibro, up.ratingLibro, up.favLibro, up.pendienteLibro, up.notasLibro, up.fechaInicioLibro FROM usuariosxlibros up INNER JOIN libros p ON up.idLibro = p.idLibro WHERE up.favLibro = :fav AND up.idUsuario = :idUsuario AND up.pendienteLibro = :pend ORDER BY up.fechaLibro DESC, up.idUsuarioLibro DESC"); + + $fav = 1; + $consulta->bindParam(':fav', $fav); + $pend=0; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de libros favoritos.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarFav() + + public function listarPendientes(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT p.idLibro, p.idApi, p.nombreLibro, p.autorLibro, p.anoLibro, p.generoLibro, p.temaLibro, p.paginasLibro, p.edicionesLibro, p.idiomaLibro, p.ratingAvgLibro, p.posterLibro, p.sinopsisLibro, up.idUsuarioLibro, up.idUsuario, up.idLibro, up.fechaLibro, up.ratingLibro, up.favLibro, up.pendienteLibro, up.notasLibro, up.fechaInicioLibro FROM usuariosxlibros up INNER JOIN libros p ON up.idLibro = p.idLibro WHERE up.pendienteLibro = :pend AND up.idUsuario = :idUsuario"); + + $pend = 1; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':idUsuario', $this->idUsuario); + + $consulta->execute(); + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de libros pendientes.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarPendientes() + + public function agregarPend(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("INSERT INTO usuariosxlibros (idUsuario, idLibro, pendienteLibro) VALUES (:idUsuario, :idLibro, :pend)"); + + $pend = 1; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':idLibro', $this->idLibro); + + $consulta->execute(); + return $conexion->lastInsertId(); + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar el libro como pendiente.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin agregarPend() + + public function buscar(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $busqueda = $_POST['busqueda']; + + if(is_numeric($busqueda)){ + + $consulta = $conexion->prepare("SELECT p.idLibro, p.idApi, p.nombreLibro, p.autorLibro, p.anoLibro, p.generoLibro, p.temaLibro, p.paginasLibro, p.edicionesLibro, p.idiomaLibro, p.ratingAvgLibro, p.posterLibro, p.sinopsisLibro, up.idUsuarioLibro, up.idUsuario, up.idLibro, up.fechaLibro, up.ratingLibro, up.favLibro, up.pendienteLibro, up.notasLibro, up.fechaInicioLibro FROM usuariosxlibros up INNER JOIN libros p ON up.idLibro = p.idLibro WHERE p.anoLibro=:ano AND up.idUsuario=:idUsuario ORDER BY up.ratingLibro DESC, up.fechaLibro DESC, up.idUsuarioLibro DESC"); + + $consulta->bindParam(':ano', $busqueda); + $consulta->bindParam(':idUsuario', $this->idUsuario); + + }else{ + $busquedaParcial = "%" . $_POST['busqueda'] . "%"; + + $consulta = $conexion->prepare("SELECT p.idLibro, p.idApi, p.nombreLibro, p.autorLibro, p.anoLibro, p.generoLibro, p.temaLibro, p.paginasLibro, p.edicionesLibro, p.idiomaLibro, p.ratingAvgLibro, p.posterLibro, p.sinopsisLibro, up.idUsuarioLibro, up.idUsuario, up.idLibro, up.fechaLibro, up.ratingLibro, up.favLibro, up.pendienteLibro, up.notasLibro, up.fechaInicioLibro FROM usuariosxlibros up INNER JOIN libros p ON up.idLibro = p.idLibro WHERE idUsuario=:idUsuario AND (p.nombreLibro LIKE :nombre OR p.autorLibro LIKE :autor) ORDER BY up.ratingLibro DESC, up.fechaLibro DESC, up.idUsuarioLibro DESC"); + + $consulta->bindParam(':nombre', $busquedaParcial); + $consulta->bindParam(':autor', $busquedaParcial); + $consulta->bindParam(':idUsuario', $this->idUsuario); + } + + $consulta->execute(); + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de libros buscados.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin buscar() + + public function favorita(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxlibros SET favLibro= :fav WHERE idUsuarioLibro = :idUsuarioLibro AND idUsuario=:idUsuario AND pendienteLibro=:pend"); + + $consulta->bindParam(':idUsuarioLibro', $this->idUsuarioLibro); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':fav', $this->favLibro); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + return [ + 'exito' => true, + 'idUsuarioLibro' => $this->idUsuarioLibro, + 'favLibro' => $this->favLibro + ]; + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al cambiar el estado favorita del libro.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin favorita() + + public function comprobar(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT * FROM usuariosxlibros WHERE idUsuarioLibro= :idUsuarioLibro AND idUsuario=:idUsuario"); + $consulta->bindParam(':idUsuarioLibro', $this->idUsuarioLibro); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + return $consulta->fetchAll(PDO::FETCH_ASSOC); + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al recoger los datos del libro seleccionado.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin comprobar() + + function editarVal(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxlibros SET ratingLibro=:rating WHERE idUsuarioLibro=:id AND idUsuario=:idUsuario AND pendienteLibro=:pend"); + + $consulta->bindParam(':rating', $this->ratingLibro); + $consulta->bindParam(':id', $this->idUsuarioLibro); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se editó correctamente la valoración del vlibro.', + 'exito_tecnico' => $this->ratingLibro + ]; + return $respuesta; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al editar la valoración del libro.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin editarVal() + + function editarFecha(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxlibros SET fechaLibro=:fecha, fechaInicioLibro=:fechaInicio WHERE idUsuarioLibro= :id AND idUsuario=:idUsuario AND pendienteLibro=:pend"); + + $consulta->bindParam(':id', $this->idUsuarioLibro); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':fecha', $this->fechaLibro); + $consulta->bindParam(':fechaInicio', $this->fechaInicioLibro); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se editó correctamente la fecha de visualización del libro.', + 'exito_tecnico' => $this->fechaLibro + ]; + return $respuesta; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al editar la fecha de visualización del libro.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin editarFecha() + + function editarNotas(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxlibros SET notasLibro=:notas WHERE idUsuarioLibro= :id AND idUsuario=:idUsuario AND pendienteLibro=:pend"); + + $consulta->bindParam(':id', $this->idUsuarioLibro); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':notas', $this->notasLibro); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se editó correctamente las notas del libro.', + 'exito_tecnico' => $this->fechaLibro + ]; + return $respuesta; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al editar las notas del libro.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin editarNotas() + + function agregarPendTabla(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxlibros SET pendienteLibro=:pend, fechaLibro=:fecha, fechaInicioLibro=:fechaInicio, ratingLibro=:rating, favLibro=:fav, notasLibro=:notas WHERE idUsuarioLibro= :id AND idUsuario=:idUsuario"); + + $consulta->bindParam(':id', $this->idUsuarioLibro); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':fecha', $this->fechaLibro); + $consulta->bindParam(':fechaInicio', $this->fechaInicioLibro); + $consulta->bindParam(':rating', $this->ratingLibro); + $consulta->bindParam(':fav', $this->favLibro); + $consulta->bindParam(':notas', $this->notasLibro); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + return $this->idUsuarioLibro; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar el libro pendiente.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin agregarPendTabla + + function eliminar(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + + $consulta = $conexion->prepare("DELETE FROM usuariosxlibros WHERE idUsuarioLibro=:id AND idUsuario=:idUsuario"); + $consulta->bindParam(':id', $this->idUsuarioLibro); + $consulta->bindParam(':idUsuario', $this->idUsuario); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se eliminó correctamente el libro.', + 'exito_tecnico' => $this->idUsuarioLibro, + ]; + return $respuesta; + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al eliminar el libro.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin eliminar() + +} // Fin clase UsuarioxLibro + +?> \ No newline at end of file diff --git a/clases/claseUsuarioxPelicula.php b/clases/claseUsuarioxPelicula.php new file mode 100644 index 0000000..3211389 --- /dev/null +++ b/clases/claseUsuarioxPelicula.php @@ -0,0 +1,512 @@ +idUsuarioPelicula = $idUsuarioPelicula; + $this->idUsuario = $idUsuario; + $this->idPelicula = $idPelicula; + $this->ratingPelicula = $ratingPelicula; + $this->favPelicula = $favPelicula; + $this->pendientePelicula = $pendientePelicula; + $this->fechaPelicula = $fechaPelicula; + $this->notasPelicula = $notasPelicula; + } // Fin __construct + + public function agregar(){ + + $conexion=conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta=$conexion->prepare("INSERT INTO usuariosxpeliculas (idUsuario, idPelicula, ratingPelicula, favPelicula, pendientePelicula, fechaPelicula, notasPelicula) VALUES (:idUsuario,:idPelicula, :rating, :fav, :pend, :fecha, :notas)"); + + $consulta->bindParam(':idUsuario',$this->idUsuario); + $consulta->bindParam(':idPelicula',$this->idPelicula); + $consulta->bindParam(':rating',$this->ratingPelicula); + $consulta->bindParam(':fav',$this->favPelicula); + $pend=0; + $consulta->bindParam(':pend',$pend); + $consulta->bindParam(':fecha',$this->fechaPelicula); + $consulta->bindParam(':notas',$this->notasPelicula); + + $consulta->execute(); + return $conexion->lastInsertId(); + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar la película.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin agregar() + + public function existe(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT idUsuarioPelicula FROM usuariosxpeliculas WHERE idPelicula=:idPelicula AND idUsuario=:idUsuario"); + + $consulta->bindParam(':idPelicula', $this->idPelicula); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetch(PDO::FETCH_ASSOC); + + if($resultado){ + $respuesta = [ + 'error' => 'Ya has registrado esta película', + 'error_tecnico' => $this->idPelicula + ]; + $conexion = null; + return $respuesta; + }else{ + return false; + } + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al comprobar si existe la película en la Base de Datos.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin existe() + + public function listarTodo(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT p.idPelicula, p.idApi, p.nombrePelicula, p.directorPelicula, p.actorPelicula, p.guionistaPelicula, p.generoPelicula, p.anoPelicula, p.companiaPelicula, p.duracionPelicula, p.posterPelicula, p.ratingAvgPelicula, p.paisPelicula, p.idiomaPelicula, p.sinopsisPelicula, up.idUsuarioPelicula, up.idUsuario, up.idPelicula, up.ratingPelicula, up.favPelicula, up.pendientePelicula, up.fechaPelicula, up.notasPelicula FROM usuariosxpeliculas up INNER JOIN peliculas p ON up.idPelicula = p.idPelicula WHERE up.idUsuario = :idUsuario AND up.pendientePelicula = :pend ORDER BY up.fechaPelicula DESC, up.idUsuarioPelicula DESC"); + + $pend=0; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de peliculas.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarTodo() + + public function listarEstrellas(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT p.idPelicula, p.idApi, p.nombrePelicula, p.directorPelicula, p.actorPelicula, p.guionistaPelicula, p.generoPelicula, p.anoPelicula, p.companiaPelicula, p.duracionPelicula, p.posterPelicula, p.ratingAvgPelicula, p.paisPelicula, p.idiomaPelicula, p.sinopsisPelicula, up.idUsuarioPelicula, up.idUsuario, up.idPelicula, up.ratingPelicula, up.favPelicula, up.pendientePelicula, up.fechaPelicula, up.notasPelicula FROM usuariosxpeliculas up INNER JOIN peliculas p ON up.idPelicula = p.idPelicula WHERE up.ratingPelicula = :rating AND up.idUsuario = :idUsuario AND up.pendientePelicula = :pend ORDER BY up.fechaPelicula DESC, up.idUsuarioPelicula DESC"); + + $pend=0; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':rating', $this->ratingPelicula); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de peliculas con valoracion '.$this->ratingPelicula, + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarEstrellas() + + public function listarFav(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT p.idPelicula, p.idApi, p.nombrePelicula, p.directorPelicula, p.actorPelicula, p.guionistaPelicula, p.generoPelicula, p.anoPelicula, p.companiaPelicula, p.duracionPelicula, p.posterPelicula, p.ratingAvgPelicula, p.paisPelicula, p.idiomaPelicula, p.sinopsisPelicula, up.idUsuarioPelicula, up.idUsuario, up.idPelicula, up.ratingPelicula, up.favPelicula, up.pendientePelicula, up.fechaPelicula, up.notasPelicula FROM usuariosxpeliculas up INNER JOIN peliculas p ON up.idPelicula = p.idPelicula WHERE up.favPelicula = :fav AND up.pendientePelicula= :pend AND up.idUsuario= :idUsuario ORDER BY up.fechaPelicula DESC, up.idUsuarioPelicula DESC"); + $fav = 1; + $consulta->bindParam(':fav', $fav); + $pend=0; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de peliculas favoritas.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarFav() + + public function listarPendientes(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT p.idPelicula, p.idApi, p.nombrePelicula, p.directorPelicula, p.actorPelicula, p.guionistaPelicula, p.generoPelicula, p.anoPelicula, p.companiaPelicula, p.duracionPelicula, p.posterPelicula, p.ratingAvgPelicula, p.paisPelicula, p.idiomaPelicula, p.sinopsisPelicula, up.idUsuarioPelicula, up.idUsuario, up.idPelicula, up.ratingPelicula, up.favPelicula, up.pendientePelicula, up.fechaPelicula, up.notasPelicula FROM usuariosxpeliculas up INNER JOIN peliculas p ON up.idPelicula = p.idPelicula WHERE up.pendientePelicula = :pend AND up.idUsuario=:idUsuario"); + $pend = 1; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':idUsuario', $this->idUsuario); + + $consulta->execute(); + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de peliculas pendientes.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarPendientes() + + public function agregarPend(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("INSERT INTO usuariosxpeliculas (idUsuario, idPelicula, pendientePelicula) VALUES (:idUsuario, :idPelicula, :pend)"); + + $pend = 1; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':idPelicula', $this->idPelicula); + + $consulta->execute(); + return $conexion->lastInsertId(); + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar la película como pendiente.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin agregarPend() + + public function buscar(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $busqueda = $_POST['busqueda']; + + if(is_numeric($busqueda)){ + + $consulta = $conexion->prepare("SELECT p.idPelicula, p.idApi, p.nombrePelicula, p.directorPelicula, p.actorPelicula, p.guionistaPelicula, p.generoPelicula, p.anoPelicula, p.companiaPelicula, p.duracionPelicula, p.posterPelicula, p.ratingAvgPelicula, p.paisPelicula, p.idiomaPelicula, p.sinopsisPelicula, up.idUsuarioPelicula, up.idUsuario, up.idPelicula, up.ratingPelicula, up.favPelicula, up.pendientePelicula, up.fechaPelicula, up.notasPelicula FROM usuariosxpeliculas up INNER JOIN peliculas p ON up.idPelicula = p.idPelicula WHERE p.anoPelicula=:ano AND up.idUsuario=:idUsuario ORDER BY up.ratingPelicula DESC, up.fechaPelicula DESC, up.idUsuarioPelicula DESC"); + + $consulta->bindParam(':ano', $busqueda); + $consulta->bindParam(':idUsuario', $this->idUsuario); + + }else{ + $busquedaParcial = "%" . $_POST['busqueda'] . "%"; + + $consulta = $conexion->prepare("SELECT p.idPelicula, p.idApi, p.nombrePelicula, p.directorPelicula, p.actorPelicula, p.guionistaPelicula, p.generoPelicula, p.anoPelicula, p.companiaPelicula, p.duracionPelicula, p.posterPelicula, p.ratingAvgPelicula, p.paisPelicula, p.idiomaPelicula, p.sinopsisPelicula, up.idUsuarioPelicula, up.idUsuario, up.idPelicula, up.ratingPelicula, up.favPelicula, up.pendientePelicula, up.fechaPelicula, up.notasPelicula FROM usuariosxpeliculas up INNER JOIN peliculas p ON up.idPelicula = p.idPelicula WHERE up.idUsuario=:idUsuario AND (p.nombrePelicula LIKE :nombre OR p.directorPelicula LIKE :director) ORDER BY up.ratingPelicula DESC, up.fechaPelicula DESC, up.idUsuarioPelicula DESC"); + + $consulta->bindParam(':nombre', $busquedaParcial); + $consulta->bindParam(':director', $busquedaParcial); + $consulta->bindParam(':idUsuario', $this->idUsuario); + } + + $consulta->execute(); + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de peliculas buscadas.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin buscar() + + public function favorita(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxpeliculas SET favPelicula= :favPelicula WHERE idUsuarioPelicula = :idUsuarioPelicula AND idUsuario=:idUsuario AND pendientePelicula=:pend"); + + $consulta->bindParam(':idUsuarioPelicula', $this->idUsuarioPelicula); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':favPelicula', $this->favPelicula); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + return [ + 'exito' => true, + 'idUsuarioPelicula' => $this->idUsuarioPelicula, + 'favPelicula' => $this->favPelicula + ]; + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al cambiar el estado favorita de la película.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin favorita() + + public function comprobar(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT * FROM usuariosxpeliculas WHERE idUsuarioPelicula= :idUsuarioPelicula AND idUsuario=:idUsuario"); + $consulta->bindParam(':idUsuarioPelicula', $this->idUsuarioPelicula); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + return $consulta->fetchAll(PDO::FETCH_ASSOC); + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al recoger los datos de la película seleccionada.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin comprobar() + + function editarVal(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxpeliculas SET ratingPelicula=:rating WHERE idUsuarioPelicula=:id AND idUsuario=:idUsuario AND pendientePelicula=:pend"); + + $consulta->bindParam(':rating', $this->ratingPelicula); + $consulta->bindParam(':id', $this->idUsuarioPelicula); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se editó correctamente la valoración de la película.', + 'exito_tecnico' => $this->ratingPelicula + ]; + return $respuesta; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al editar la valoración de la película.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin editarVal() + + function editarFecha(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxpeliculas SET fechaPelicula=:fecha WHERE idUsuarioPelicula= :id AND idUsuario=:idUsuario AND pendientePelicula=:pend"); + + $consulta->bindParam(':id', $this->idUsuarioPelicula); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':fecha', $this->fechaPelicula); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se editó correctamente la fecha de visualización de la película.', + 'exito_tecnico' => $this->fechaPelicula + ]; + return $respuesta; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al editar la fecha de visualización de la película.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin editarFecha() + + function editarNotas(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxpeliculas SET notasPelicula=:notas WHERE idUsuarioPelicula= :id AND idUsuario=:idUsuario AND pendientePelicula=:pend"); + + $consulta->bindParam(':id', $this->idUsuarioPelicula); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':notas', $this->notasPelicula); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se editó correctamente las notas de la película.', + 'exito_tecnico' => $this->fechaPelicula + ]; + return $respuesta; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al editar las notas de la película.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin editarNotas() + + function agregarPendTabla(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxpeliculas SET pendientePelicula=:pend, fechaPelicula=:fecha, ratingPelicula=:rating, favPelicula=:fav, notasPelicula=:notas WHERE idUsuarioPelicula= :id AND idUsuario=:idUsuario"); + + $consulta->bindParam(':id', $this->idUsuarioPelicula); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':fecha', $this->fechaPelicula); + $consulta->bindParam(':rating', $this->ratingPelicula); + $consulta->bindParam(':fav', $this->favPelicula); + $consulta->bindParam(':notas', $this->notasPelicula); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + return $this->idUsuarioPelicula; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar la película pendiente.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin agregarPendTabla + + function eliminar(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + + $consulta = $conexion->prepare("DELETE FROM usuariosxpeliculas WHERE idUsuarioPelicula=:id AND idUsuario=:idUsuario"); + $consulta->bindParam(':id', $this->idUsuarioPelicula); + $consulta->bindParam(':idUsuario', $this->idUsuario); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se eliminó correctamente la película.', + 'exito_tecnico' => $this->idUsuarioPelicula, + ]; + return $respuesta; + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al eliminar la película.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin eliminar() + +} // Fin clase UsuarioxPelicula + +?> \ No newline at end of file diff --git a/clases/claseUsuarioxSerie.php b/clases/claseUsuarioxSerie.php new file mode 100644 index 0000000..b1738fd --- /dev/null +++ b/clases/claseUsuarioxSerie.php @@ -0,0 +1,553 @@ +idUsuarioSerie = $idUsuarioSerie; + $this->idUsuario = $idUsuario; + $this->idSerie = $idSerie; + $this->ratingSerie = $ratingSerie; + $this->favSerie = $favSerie; + $this->pendienteSerie = $pendienteSerie; + $this->fechaSerie = $fechaSerie; + $this->estadoSerie = $estadoSerie; + $this->notasSerie = $notasSerie; + } // Fin __construct + + public function agregar(){ + + $conexion=conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta=$conexion->prepare("INSERT INTO usuariosxseries (idUsuario, idSerie, ratingSerie, favSerie, pendienteSerie, fechaSerie, notasSerie, estadoSerie) VALUES (:idUsuario,:idSerie, :rating, :fav, :pend, :fecha, :notas, :estado)"); + + $consulta->bindParam(':idUsuario',$this->idUsuario); + $consulta->bindParam(':idSerie',$this->idSerie); + $consulta->bindParam(':rating',$this->ratingSerie); + $consulta->bindParam(':fav',$this->favSerie); + $pend=0; + $consulta->bindParam(':pend',$pend); + $consulta->bindParam(':fecha',$this->fechaSerie); + $consulta->bindParam(':notas',$this->notasSerie); + $consulta->bindParam(':estado',$this->estadoSerie); + + $consulta->execute(); + return $conexion->lastInsertId(); + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar la serie.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin agregar() + + public function existe(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT idUsuarioSerie FROM usuariosxseries WHERE idSerie=:idSerie AND idUsuario=:idUsuario"); + + $consulta->bindParam(':idSerie', $this->idSerie); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetch(PDO::FETCH_ASSOC); + + if($resultado){ + $respuesta = [ + 'error' => 'Ya has registrado esta serie', + 'error_tecnico' => $this->idSerie + ]; + $conexion = null; + return $respuesta; + }else{ + return false; + } + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al comprobar si existe la serie en la Base de Datos.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin existe() + + public function listarTodo(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT p.idSerie, p.idApi, p.nombreSerie, p.creadorSerie, p.directorSerie, p.actorSerie, p.guionistaSerie, p.companiaSerie, p.generoSerie, p.anoSerie, p.temporadasSerie, p.episodiosSerie, p.ratingAvgSerie, p.paisSerie, p.idiomaSerie, p.posterSerie, p.sinopsisSerie, up.idUsuarioSerie, up.idUsuario, up.idSerie, up.ratingSerie, up.favSerie, up.pendienteSerie, up.fechaSerie, up.estadoSerie, up.notasSerie FROM usuariosxseries up INNER JOIN series p ON up.idSerie = p.idSerie WHERE up.idUsuario = :idUsuario AND up.pendienteSerie = :pend ORDER BY up.fechaSerie DESC, up.idUsuarioSerie DESC"); + + $pend=0; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de series.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarTodo() + + public function listarEstrellas(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT p.idSerie, p.idApi, p.nombreSerie, p.creadorSerie, p.directorSerie, p.actorSerie, p.guionistaSerie, p.companiaSerie, p.generoSerie, p.anoSerie, p.temporadasSerie, p.episodiosSerie, p.ratingAvgSerie, p.paisSerie, p.idiomaSerie, p.posterSerie, p.sinopsisSerie, up.idUsuarioSerie, up.idUsuario, up.idSerie, up.ratingSerie, up.favSerie, up.pendienteSerie, up.fechaSerie, up.estadoSerie, up.notasSerie FROM usuariosxseries up INNER JOIN series p ON up.idSerie = p.idSerie WHERE up.ratingSerie = :rating AND up.idUsuario = :idUsuario AND up.pendienteSerie = :pend ORDER BY up.fechaSerie DESC, up.idUsuarioSerie DESC"); + + $pend=0; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':rating', $this->ratingSerie); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de series con valoracion '.$this->ratingSerie, + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarEstrellas() + + public function listarFav(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT p.idSerie, p.idApi, p.nombreSerie, p.creadorSerie, p.directorSerie, p.actorSerie, p.guionistaSerie, p.companiaSerie, p.generoSerie, p.anoSerie, p.temporadasSerie, p.episodiosSerie, p.ratingAvgSerie, p.paisSerie, p.idiomaSerie, p.posterSerie, p.sinopsisSerie, up.idUsuarioSerie, up.idUsuario, up.idSerie, up.ratingSerie, up.favSerie, up.pendienteSerie, up.fechaSerie, up.estadoSerie, up.notasSerie FROM usuariosxseries up INNER JOIN series p ON up.idSerie = p.idSerie WHERE up.favSerie = :fav AND up.idUsuario = :idUsuario AND up.pendienteSerie = :pend ORDER BY up.fechaSerie DESC, up.idUsuarioSerie DESC"); + + $fav = 1; + $consulta->bindParam(':fav', $fav); + $pend=0; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de series favoritas.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarFav() + + public function listarPendientes(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT p.idSerie, p.idApi, p.nombreSerie, p.creadorSerie, p.directorSerie, p.actorSerie, p.guionistaSerie, p.companiaSerie, p.generoSerie, p.anoSerie, p.temporadasSerie, p.episodiosSerie, p.ratingAvgSerie, p.paisSerie, p.idiomaSerie, p.posterSerie, p.sinopsisSerie, up.idUsuarioSerie, up.idUsuario, up.idSerie, up.ratingSerie, up.favSerie, up.pendienteSerie, up.fechaSerie, up.estadoSerie, up.notasSerie FROM usuariosxseries up INNER JOIN series p ON up.idSerie = p.idSerie WHERE up.pendienteSerie = :pend AND up.idUsuario = :idUsuario"); + + $pend = 1; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':idUsuario', $this->idUsuario); + + $consulta->execute(); + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de series pendientes.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarPendientes() + + public function agregarPend(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("INSERT INTO usuariosxseries (idUsuario, idSerie, pendienteSerie) VALUES (:idUsuario, :idSerie, :pend)"); + + $pend = 1; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':idSerie', $this->idSerie); + + $consulta->execute(); + return $conexion->lastInsertId(); + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar la serie como pendiente.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin agregarPend() + + public function buscar(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $busqueda = $_POST['busqueda']; + + if(is_numeric($busqueda)){ + + $consulta = $conexion->prepare("SELECT p.idSerie, p.idApi, p.nombreSerie, p.creadorSerie, p.directorSerie, p.actorSerie, p.guionistaSerie, p.companiaSerie, p.generoSerie, p.anoSerie, p.temporadasSerie, p.episodiosSerie, p.ratingAvgSerie, p.paisSerie, p.idiomaSerie, p.posterSerie, p.sinopsisSerie, up.idUsuarioSerie, up.idUsuario, up.idSerie, up.ratingSerie, up.favSerie, up.pendienteSerie, up.fechaSerie, up.estadoSerie, up.notasSerie FROM usuariosxseries up INNER JOIN series p ON up.idSerie = p.idSerie WHERE p.anoSerie=:ano AND up.idUsuario=:idUsuario ORDER BY up.ratingSerie DESC, up.fechaSerie DESC, up.idUsuarioSerie DESC"); + + $consulta->bindParam(':ano', $busqueda); + $consulta->bindParam(':idUsuario', $this->idUsuario); + + }else{ + $busquedaParcial = "%" . $_POST['busqueda'] . "%"; + + $consulta = $conexion->prepare("SELECT p.idSerie, p.idApi, p.nombreSerie, p.creadorSerie, p.directorSerie, p.actorSerie, p.guionistaSerie, p.companiaSerie, p.generoSerie, p.anoSerie, p.temporadasSerie, p.episodiosSerie, p.ratingAvgSerie, p.paisSerie, p.idiomaSerie, p.posterSerie, p.sinopsisSerie, up.idUsuarioSerie, up.idUsuario, up.idSerie, up.ratingSerie, up.favSerie, up.pendienteSerie, up.fechaSerie, up.estadoSerie, up.notasSerie FROM usuariosxseries up INNER JOIN series p ON up.idSerie = p.idSerie WHERE up.idUsuario=:idUsuario AND (p.nombreSerie LIKE :nombre OR p.creadorSerie LIKE :creador OR p.directorSerie LIKE :director) ORDER BY up.ratingSerie DESC, up.fechaSerie DESC, up.idUsuarioSerie DESC"); + + $consulta->bindParam(':nombre', $busquedaParcial); + $consulta->bindParam(':creador', $busquedaParcial); + $consulta->bindParam(':director', $busquedaParcial); + $consulta->bindParam(':idUsuario', $this->idUsuario); + } + + $consulta->execute(); + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de series buscadas.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin buscar() + + public function favorita(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxseries SET favSerie= :fav WHERE idUsuarioSerie = :idUsuarioSerie AND idUsuario=:idUsuario AND pendienteSerie=:pend"); + + $consulta->bindParam(':idUsuarioSerie', $this->idUsuarioSerie); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':fav', $this->favSerie); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + return [ + 'exito' => true, + 'idUsuarioSerie' => $this->idUsuarioSerie, + 'favSerie' => $this->favSerie + ]; + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al cambiar el estado favorita de la serie.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin favorita() + + public function comprobar(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT * FROM usuariosxseries WHERE idUsuarioSerie= :idUsuarioSerie AND idUsuario=:idUsuario"); + $consulta->bindParam(':idUsuarioSerie', $this->idUsuarioSerie); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + return $consulta->fetchAll(PDO::FETCH_ASSOC); + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al recoger los datos de la serie seleccionada.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin comprobar() + + function editarVal(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxseries SET ratingSerie=:rating WHERE idUsuarioSerie=:id AND idUsuario=:idUsuario AND pendienteSerie=:pend"); + + $consulta->bindParam(':rating', $this->ratingSerie); + $consulta->bindParam(':id', $this->idUsuarioSerie); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se editó correctamente la valoración de la serie.', + 'exito_tecnico' => $this->ratingSerie + ]; + return $respuesta; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al editar la valoración de la serie.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin editarVal() + + function editarFecha(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxseries SET fechaSerie=:fecha WHERE idUsuarioSerie= :id AND idUsuario=:idUsuario AND pendienteSerie=:pend"); + + $consulta->bindParam(':id', $this->idUsuarioSerie); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':fecha', $this->fechaSerie); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se editó correctamente la fecha de visualización de la serie.', + 'exito_tecnico' => $this->fechaSerie + ]; + return $respuesta; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al editar la fecha de visualización de la serie.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin editarFecha() + + function editarEstado(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxseries SET estadoSerie=:estado WHERE idUsuarioSerie=:id AND idUsuario=:idUsuario AND pendienteSerie=:pend"); + + $consulta->bindParam(':estado', $this->estadoSerie); + $consulta->bindParam(':id', $this->idUsuarioSerie); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se editó correctamente el estado de la serie.', + 'exito_tecnico' => $this->estadoSerie + ]; + return $respuesta; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al editar el estado de la serie.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin editarEstado() + + function editarNotas(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxseries SET notasSerie=:notas WHERE idUsuarioSerie= :id AND idUsuario=:idUsuario AND pendienteSerie=:pend"); + + $consulta->bindParam(':id', $this->idUsuarioSerie); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':notas', $this->notasSerie); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se editó correctamente las notas de la serie.', + 'exito_tecnico' => $this->fechaSerie + ]; + return $respuesta; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al editar las notas de la serie.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin editarNotas() + + function agregarPendTabla(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxseries SET pendienteSerie=:pend, fechaSerie=:fecha, ratingSerie=:rating, favSerie=:fav, notasSerie=:notas, estadoSerie=:estado WHERE idUsuarioSerie= :id AND idUsuario=:idUsuario"); + + $consulta->bindParam(':id', $this->idUsuarioSerie); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':fecha', $this->fechaSerie); + $consulta->bindParam(':rating', $this->ratingSerie); + $consulta->bindParam(':fav', $this->favSerie); + $consulta->bindParam(':notas', $this->notasSerie); + $consulta->bindParam(':estado', $this->estadoSerie); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + return $this->idUsuarioSerie; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar la serie pendiente.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin agregarPendTabla + + function eliminar(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + + $consulta = $conexion->prepare("DELETE FROM usuariosxseries WHERE idUsuarioSerie=:id AND idUsuario=:idUsuario"); + $consulta->bindParam(':id', $this->idUsuarioSerie); + $consulta->bindParam(':idUsuario', $this->idUsuario); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se eliminó correctamente la serie.', + 'exito_tecnico' => $this->idUsuarioSerie, + ]; + return $respuesta; + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al eliminar la serie.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin eliminar() + +} // Fin clase UsuarioxSerie + +?> \ No newline at end of file diff --git a/clases/claseUsuarioxTemporada.php b/clases/claseUsuarioxTemporada.php new file mode 100644 index 0000000..2ccd094 --- /dev/null +++ b/clases/claseUsuarioxTemporada.php @@ -0,0 +1,529 @@ +idUsuarioTemporada = $idUsuarioTemporada; + $this->idUsuario = $idUsuario; + $this->idTemporada = $idTemporada; + $this->ratingTemporada = $ratingTemporada; + $this->favTemporada = $favTemporada; + $this->pendienteTemporada = $pendienteTemporada; + $this->fechaTemporada = $fechaTemporada; + $this->notasTemporada = $notasTemporada; + } // Fin __construct + + public function agregar(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("INSERT INTO usuariosxtemporadas (idUsuario, idTemporada, ratingTemporada, favTemporada, pendienteTemporada, fechaTemporada, notasTemporada) VALUES ( :idUsuario, :idTemporada, :rating, :fav, :pend, :fecha, :notas)"); + + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':idTemporada', $this->idTemporada); + $consulta->bindParam(':rating',$this->ratingTemporada); + $consulta->bindParam(':fav',$this->favTemporada); + $pend=0; + $consulta->bindParam(':pend',$pend); + $consulta->bindParam(':fecha',$this->fechaTemporada); + $consulta->bindParam(':notas',$this->notasTemporada); + + $consulta->execute(); + + return $conexion->lastInsertId(); + + }catch(PDOException $error){ + + $respuesta = [ + 'error' => 'Ocurrió un error al agregar la temporada.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } + + } // Fin agregar() + + public function existe(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT idUsuarioTemporada FROM usuariosxtemporadas WHERE idTemporada = :idTemporada AND idUsuario = :idUsuario"); + + $consulta->bindParam(':idTemporada',$this->idTemporada); + $consulta->bindParam(':idUsuario',$this->idUsuario); + + $consulta->execute(); + + $resultado = $consulta->fetch(PDO::FETCH_ASSOC); + + if($resultado){ + + $respuesta = [ + 'error' => 'Ya has registrado esta temporada.', + 'error_tecnico' => $this->idTemporada + ]; + + $conexion = null; + return $respuesta; + + }else{ + return false; + } + + }catch(PDOException $error){ + + $respuesta = [ + 'error' => 'Ocurrió un error al comprobar si existe la temporada en la Base de Datos.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } + + } // Fin existe() + + public function listarTodo(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT p.idTemporada, p.idApi, p.idSerie, p.nombreTemporada, p.numeroTemporada, p.directorTemporada, p.guionistaTemporada, p.actorTemporada, p.episodiosTemporada, p.anoTemporada, p.ratingAvgTemporada, p.posterTemporada, p.sinopsisTemporada, up.idUsuarioTemporada, up.idUsuario, up.idTemporada, up.ratingTemporada, up.favTemporada, up.pendienteTemporada, up.fechaTemporada, up.notasTemporada FROM usuariosxtemporadas up INNER JOIN seriestemporadas p ON up.idTemporada = p.idTemporada WHERE up.idUsuario = :idUsuario AND up.pendienteTemporada = :pend ORDER BY up.fechaTemporada DESC, up.idUsuarioTemporada DESC"); + + $pend = 0; + $consulta->bindParam(':pend',$pend); + $consulta->bindParam(':idUsuario',$this->idUsuario); + + $consulta->execute(); + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + + return $resultado; + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de temporadas.', + 'error_tecnico' => $error + ]; + $conexion = null; + + return $respuesta; + } + } + + } // Fin listarTodo() + + public function listarEstrellas(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT p.idTemporada, p.idApi, p.idSerie, p.nombreTemporada, p.numeroTemporada, p.directorTemporada, p.guionistaTemporada, p.actorTemporada, p.episodiosTemporada, p.anoTemporada, p.ratingAvgTemporada, p.posterTemporada, p.sinopsisTemporada, up.idUsuarioTemporada, up.idUsuario, up.idTemporada, up.ratingTemporada, up.favTemporada, up.pendienteTemporada, up.fechaTemporada, up.notasTemporada FROM usuariosxtemporadas up INNER JOIN seriestemporadas p ON up.idTemporada = p.idTemporada WHERE up.ratingTemporada = :rating AND up.idUsuario = :idUsuario AND up.pendienteTemporada = :pend ORDER BY up.fechaTemporada DESC, up.idUsuarioTemporada DESC"); + + $pend=0; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':rating', $this->ratingTemporada); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de temporadas con valoracion '.$this->ratingTemporada, + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarEstrellas() + + public function listarFav(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT p.idTemporada, p.idApi, p.idSerie, p.nombreTemporada, p.numeroTemporada, p.directorTemporada, p.guionistaTemporada, p.actorTemporada, p.episodiosTemporada, p.anoTemporada, p.ratingAvgTemporada, p.posterTemporada, p.sinopsisTemporada, up.idUsuarioTemporada, up.idUsuario, up.idTemporada, up.ratingTemporada, up.favTemporada, up.pendienteTemporada, up.fechaTemporada, up.notasTemporada FROM usuariosxtemporadas up INNER JOIN seriestemporadas p ON up.idTemporada = p.idTemporada WHERE up.favTemporada = :fav AND up.idUsuario = :idUsuario AND up.pendienteTemporada = :pend ORDER BY up.fechaTemporada DESC, up.idUsuarioTemporada DESC"); + + $fav = 1; + $consulta->bindParam(':fav', $fav); + $pend=0; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de temporadas favoritas.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarFav() + + public function listarPendientes(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT p.idTemporada, p.idApi, p.idSerie, p.nombreTemporada, p.numeroTemporada, p.directorTemporada, p.guionistaTemporada, p.actorTemporada, p.episodiosTemporada, p.anoTemporada, p.ratingAvgTemporada, p.posterTemporada, p.sinopsisTemporada, up.idUsuarioTemporada, up.idUsuario, up.idTemporada, up.ratingTemporada, up.favTemporada, up.pendienteTemporada, up.fechaTemporada, up.notasTemporada FROM usuariosxtemporadas up INNER JOIN seriestemporadas p ON up.idTemporada = p.idTemporada WHERE up.pendienteTemporada = :pend AND up.idUsuario = :idUsuario"); + + $pend = 1; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':idUsuario', $this->idUsuario); + + $consulta->execute(); + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de temporadas pendientes.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin listarPendientes() + + public function agregarPend(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("INSERT INTO usuariosxtemporadas (idUsuario, idTemporada, pendienteTemporada) VALUES (:idUsuario, :idTemporada, :pend)"); + + $pend = 1; + $consulta->bindParam(':pend', $pend); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':idTemporada', $this->idTemporada); + + $consulta->execute(); + return $conexion->lastInsertId(); + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar la temporada como pendiente.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin agregarPend() + + public function buscar(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $busqueda = $_POST['busqueda']; + + if(is_numeric($busqueda)){ + + $consulta = $conexion->prepare("SELECT p.idTemporada, p.idApi, p.idSerie, p.nombreTemporada, p.numeroTemporada, p.directorTemporada, p.guionistaTemporada, p.actorTemporada, p.episodiosTemporada, p.anoTemporada, p.ratingAvgTemporada, p.posterTemporada, p.sinopsisTemporada, up.idUsuarioTemporada, up.idUsuario, up.idTemporada, up.ratingTemporada, up.favTemporada, up.pendienteTemporada, up.fechaTemporada, up.notasTemporada FROM usuariosxtemporadas up INNER JOIN seriestemporadas p ON up.idTemporada = p.idTemporada WHERE p.anoTemporada=:ano AND up.idUsuario=:idUsuario ORDER BY up.ratingTemporada DESC, up.fechaTemporada DESC, up.idUsuarioTemporada DESC"); + + $consulta->bindParam(':ano', $busqueda); + $consulta->bindParam(':idUsuario', $this->idUsuario); + + }else{ + $busquedaParcial = "%" . $_POST['busqueda'] . "%"; + + $consulta = $conexion->prepare("SELECT p.idTemporada, p.idApi, p.idSerie, p.nombreTemporada, p.numeroTemporada, p.directorTemporada, p.guionistaTemporada, p.actorTemporada, p.episodiosTemporada, p.anoTemporada, p.ratingAvgTemporada, p.posterTemporada, p.sinopsisTemporada, up.idUsuarioTemporada, up.idUsuario, up.idTemporada, up.ratingTemporada, up.favTemporada, up.pendienteTemporada, up.fechaTemporada, up.notasTemporada FROM usuariosxtemporadas up INNER JOIN seriestemporadas p ON up.idTemporada = p.idTemporada WHERE up.idUsuario=:idUsuario AND (p.nombreTemporada LIKE :nombre OR p.directorTemporada LIKE :director) ORDER BY up.ratingTemporada DESC, up.fechaTemporada DESC, up.idUsuarioTemporada DESC"); + + $consulta->bindParam(':nombre', $busquedaParcial); + $consulta->bindParam(':director', $busquedaParcial); + $consulta->bindParam(':idUsuario', $this->idUsuario); + } + + $consulta->execute(); + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + return $resultado; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de temporadas buscadas.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin buscar() + + public function favorita(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxtemporadas SET favTemporada= :fav WHERE idUsuarioTemporada = :idUsuarioTemporada AND idUsuario=:idUsuario AND pendienteTemporada=:pend"); + + $consulta->bindParam(':idUsuarioTemporada', $this->idUsuarioTemporada); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':fav', $this->favTemporada); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + return [ + 'exito' => true, + 'idUsuarioSerie' => $this->idUsuarioTemporada, + 'favSerie' => $this->favTemporada + ]; + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al cambiar el estado favorita de la temporada.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin favorita() + + public function comprobar(){ + + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT * FROM usuariosxtemporadas WHERE idUsuarioTemporada= :idUsuarioTemporada AND idUsuario=:idUsuario"); + $consulta->bindParam(':idUsuarioTemporada', $this->idUsuarioTemporada); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->execute(); + + return $consulta->fetchAll(PDO::FETCH_ASSOC); + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al recoger los datos de la temporada seleccionada.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin comprobar() + + function editarVal(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxtemporadas SET ratingTemporada=:rating WHERE idUsuarioTemporada=:id AND idUsuario=:idUsuario AND pendienteTemporada=:pend"); + + $consulta->bindParam(':rating', $this->ratingTemporada); + $consulta->bindParam(':id', $this->idUsuarioTemporada); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se editó correctamente la valoración de la temporada.', + 'exito_tecnico' => $this->ratingTemporada + ]; + return $respuesta; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al editar la valoración de la temporada.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin editarVal() + + function editarFecha(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxtemporadas SET fechaTemporada=:fecha WHERE idUsuarioTemporada= :id AND idUsuario=:idUsuario AND pendienteTemporada=:pend"); + + $consulta->bindParam(':id', $this->idUsuarioTemporada); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':fecha', $this->fechaTemporada); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se editó correctamente la fecha de visualización de la temporada.', + 'exito_tecnico' => $this->fechaTemporada + ]; + return $respuesta; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al editar la fecha de visualización de la temporada.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin editarFecha() + + function editarNotas(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxtemporadas SET notasTemporada=:notas WHERE idUsuarioTemporada= :id AND idUsuario=:idUsuario AND pendienteTemporada=:pend"); + + $consulta->bindParam(':id', $this->idUsuarioTemporada); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':notas', $this->notasTemporada); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se editó correctamente las notas de la temporada.', + 'exito_tecnico' => $this->fechaTemporada + ]; + return $respuesta; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al editar las notas de la temporada.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin editarNotas() + + function agregarPendTabla(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE usuariosxtemporadas SET pendienteTemporada=:pend, fechaTemporada=:fecha, ratingTemporada=:rating, favTemporada=:fav, notasTemporada=:notas WHERE idUsuarioTemporada= :id AND idUsuario=:idUsuario"); + + $consulta->bindParam(':id', $this->idUsuarioTemporada); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':fecha', $this->fechaTemporada); + $consulta->bindParam(':rating', $this->ratingTemporada); + $consulta->bindParam(':fav', $this->favTemporada); + $consulta->bindParam(':notas', $this->notasTemporada); + $pend = 0; + $consulta->bindParam(':pend', $pend); + + $consulta->execute(); + + return $this->idUsuarioTemporada; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al agregar la temporada pendiente.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin agregarPendTabla + + function eliminar(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + + $consulta = $conexion->prepare("DELETE FROM usuariosxtemporadas WHERE idUsuarioTemporada=:id AND idUsuario=:idUsuario"); + $consulta->bindParam(':id', $this->idUsuarioTemporada); + $consulta->bindParam(':idUsuario', $this->idUsuario); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Se eliminó correctamente la temporada.', + 'exito_tecnico' => $this->idUsuarioTemporada, + ]; + return $respuesta; + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al eliminar la temporada.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } // Fin else + } // Fin eliminar() + +} // Fin clase UsuarioxTemporada + +?> \ No newline at end of file diff --git a/contenido.php b/contenido.php new file mode 100644 index 0000000..bd8bdbb --- /dev/null +++ b/contenido.php @@ -0,0 +1,446 @@ + + + + + + + + MyDiary + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+ + +
+
+
+
+
+ + +
+
+ + +
+
+
+ + + + + + + + + +
+ +
+
+
+
+
+ +
+

Búsqueda por valoración:

+
+ + + +
+ +
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+ +
+
+
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + diff --git a/controladores/controladorEpisodio.php b/controladores/controladorEpisodio.php new file mode 100644 index 0000000..766a47b --- /dev/null +++ b/controladores/controladorEpisodio.php @@ -0,0 +1,372 @@ +idApi = $_POST['idApiSerie']; + $serie->nombreSerie = empty($_POST['nombreSerie']) ? null : $_POST['nombreSerie']; + $serie->creadorSerie = empty($_POST['creadorSerie']) ? null : $_POST['creadorSerie']; + $serie->directorSerie = empty($_POST['directorSerie']) ? null : $_POST['directorSerie']; + $serie->actorSerie = empty($_POST['actorSerie']) ? null : $_POST['actorSerie']; + $serie->guionistaSerie = empty($_POST['guionistaSerie']) ? null : $_POST['guionistaSerie']; + $serie->companiaSerie = empty($_POST['companiaSerie']) ? null : $_POST['companiaSerie']; + $serie->generoSerie = empty($_POST['generoSerie']) ? null : $_POST['generoSerie']; + $serie->anoSerie = empty($_POST['anoSerie']) ? null : $_POST['anoSerie']; + $serie->temporadasSerie = empty($_POST['temporadasSerie']) ? null : $_POST['temporadasSerie']; + $serie->episodiosSerie = empty($_POST['episodiosSerie']) ? null : $_POST['episodiosSerie']; + $serie->ratingAvgSerie = empty($_POST['ratingAvgSerie']) ? null : $_POST['ratingAvgSerie']; + $serie->paisSerie = empty($_POST['paisSerie']) ? null : $_POST['paisSerie']; + $serie->idiomaSerie = empty($_POST['idiomaSerie']) ? null : $_POST['idiomaSerie']; + $serie->posterSerie = empty($_POST['posterSerie']) ? null : $_POST['posterSerie']; + $serie->sinopsisSerie = empty($_POST['sinopsisSerie']) ? null : $_POST['sinopsisSerie']; + + $idSerie = $serie->agregar(); + + if (isset($idSerie['error'])) { + echo json_encode($idSerie); + break; + } + + // Segundo metemos la temporada en seriestemporadas usando el $idSerie, y exista o no devolverÔ su idTemporada. + $temporada = new Temporada(); + + $temporada->idApi = $_POST['idApiTemporada']; + $temporada->idSerie = $idSerie; + $temporada->nombreTemporada = empty($_POST['nombreTemporada']) ? null : $_POST['nombreTemporada']; + $temporada->numeroTemporada = empty($_POST['numeroTemporada']) ? null : $_POST['numeroTemporada']; + $temporada->directorTemporada = empty($_POST['directorTemporada']) ? null : $_POST['directorTemporada']; + $temporada->actorTemporada = empty($_POST['actorTemporada']) ? null : $_POST['actorTemporada']; + $temporada->guionistaTemporada = empty($_POST['guionistaTemporada']) ? null : $_POST['guionistaTemporada']; + $temporada->episodiosTemporada = empty($_POST['episodiosTemporada']) ? null : $_POST['episodiosTemporada']; + $temporada->anoTemporada = empty($_POST['anoTemporada']) ? null : $_POST['anoTemporada']; + $temporada->ratingAvgTemporada = empty($_POST['ratingAvgTemporada']) ? null : $_POST['ratingAvgTemporada']; + $temporada->posterTemporada = empty($_POST['posterTemporada']) ? null : $_POST['posterTemporada']; + $temporada->sinopsisTemporada = empty($_POST['sinopsisTemporada']) ? null : $_POST['sinopsisTemporada']; + + $idTemporada = $temporada->agregar(); + + if (isset($idTemporada['error'])) { + echo json_encode($idTemporada); + break; + } + + // Tercero metemos el episodio en seriesepisodios usando el $idTemporada, y exista o no devolverÔ su idEpisodio. + $episodio = new Episodio(); + + $episodio->idApi = $_POST['idApiEpisodio']; + $episodio->idTemporada = $idTemporada; + $episodio->nombreEpisodio = empty($_POST['nombreEpisodio']) ? null : $_POST['nombreEpisodio']; + $episodio->numeroEpisodio = empty($_POST['numeroEpisodio']) ? null : $_POST['numeroEpisodio']; + $episodio->directorEpisodio = empty($_POST['directorEpisodio']) ? null : $_POST['directorEpisodio']; + $episodio->actorEpisodio = empty($_POST['actorEpisodio']) ? null : $_POST['actorEpisodio']; + $episodio->guionistaEpisodio = empty($_POST['guionistaEpisodio']) ? null : $_POST['guionistaEpisodio']; + $episodio->anoEpisodio = empty($_POST['anoEpisodio']) ? null : $_POST['anoEpisodio']; + $episodio->duracionEpisodio = empty($_POST['duracionEpisodio']) ? null : $_POST['duracionEpisodio']; + $episodio->ratingAvgEpisodio = empty($_POST['ratingAvgEpisodio']) ? null : $_POST['ratingAvgEpisodio']; + $episodio->posterEpisodio = empty($_POST['posterEpisodio']) ? null : $_POST['posterEpisodio']; + $episodio->sinopsisEpisodio = empty($_POST['sinopsisEpisodio']) ? null : $_POST['sinopsisEpisodio']; + + $idEpisodio = $episodio->agregar(); + + if (isset($idEpisodio['error'])) { + echo json_encode($idEpisodio); + break; + } + + // Usamos ese idEpisodio para agregarla a usuariosxepisodios + $usuarioxEpisodio = new UsuarioxEpisodio(); + $usuarioxEpisodio->idUsuario = $_SESSION['idUsuario']; + $usuarioxEpisodio->idEpisodio = $idEpisodio; + + // Comprobamos si ya estÔ registrada, si no se agrega + $resultado = $usuarioxEpisodio->existe(); + + if(!$resultado){ + $usuarioxEpisodio->fechaEpisodio = empty($_POST['fechaEpisodio']) ? null : $_POST['fechaEpisodio']; + $usuarioxEpisodio->ratingEpisodio = empty($_POST['ratingEpisodio']) ? null : $_POST['ratingEpisodio']; + $usuarioxEpisodio->notasEpisodio = empty($_POST['notasEpisodio']) ? null : $_POST['notasEpisodio']; + $usuarioxEpisodio->favEpisodio = $_POST['favEpisodio']; + $resultado = $usuarioxEpisodio->agregar(); + + echo json_encode([ + 'idEpisodio' => $idEpisodio, + 'idUsuarioEpisodio' => $resultado + ]); + }else{ + echo json_encode($resultado); + } + + break; + + case "buscarApi": + $api = new ApiSerie(); + $resultado = $api->buscar($_POST['nombreEpisodio']); + + $series = []; + foreach($resultado as $item){ + $series[] = $api->transformarDatos($item); + } + + echo json_encode($series); + break; + + case "detallesApi": + + $api = new ApiSerie(); + $resultado = $api->detalles($_POST["idApi"]); + + if(isset($resultado['error'])){ + echo json_encode($resultado); + break; + } + + $resultado = $api->transformarDatos($resultado); + + echo json_encode($resultado); + + break; + + case 'detallesApiTemporada': + $api = new ApiSerie(); + $resultado = $api->temporada($_POST['idApiSerie'],$_POST['numeroTemporada']); + + if(isset($resultado['error'])){ + echo json_encode($resultado); + break; + } + + $resultado = $api->transformarDatosTemporada($resultado, $_POST['nombreSerie']); + echo json_encode($resultado); + + break; + + case 'detallesApiEpisodio': + $api = new ApiSerie(); + $resultado = $api->episodio($_POST['idApiSerie'], $_POST['numeroTemporada'], $_POST['numeroEpisodio']); + + if(isset($resultado['error'])){ + echo json_encode($resultado); + break; + } + + $resultado = $api->transformarDatosEpisodio($resultado, $_POST['numeroTemporada'], $_POST['nombreSerie']); + echo json_encode($resultado); + + break; + + case 'listarTodo': + $usuarioxEpisodio = new UsuarioxEpisodio(); + $usuarioxEpisodio->idUsuario = $_SESSION['idUsuario']; + $lista = $usuarioxEpisodio->listarTodo(); + echo json_encode($lista); + break; + + case 'listarEstrellas': + $usuarioxEpisodio = new UsuarioxEpisodio(); + $usuarioxEpisodio->idUsuario = $_SESSION['idUsuario']; + $usuarioxEpisodio->ratingEpisodio = $_POST['i']; + $lista = $usuarioxEpisodio->listarEstrellas(); + echo json_encode($lista); + break; + + case 'listarFav': + $usuarioxEpisodio = new UsuarioxEpisodio(); + $usuarioxEpisodio->idUsuario = $_SESSION['idUsuario']; + $lista = $usuarioxEpisodio->listarFav(); + echo json_encode($lista); + break; + + case 'listarPendientes': + $usuarioxEpisodio = new UsuarioxEpisodio(); + $usuarioxEpisodio->idUsuario = $_SESSION['idUsuario']; + $lista = $usuarioxEpisodio->listarPendientes(); + echo json_encode($lista); + break; + + case 'agregarPend': + + // Primero metemos la serie completa en series, y exista o no devolverÔ su idSerie. + $serie = new Serie(); + $serie->idApi = $_POST['idApiSerie']; + $serie->nombreSerie = empty($_POST['nombreSerie']) ? null : $_POST['nombreSerie']; + $serie->creadorSerie = empty($_POST['creadorSerie']) ? null : $_POST['creadorSerie']; + $serie->directorSerie = empty($_POST['directorSerie']) ? null : $_POST['directorSerie']; + $serie->actorSerie = empty($_POST['actorSerie']) ? null : $_POST['actorSerie']; + $serie->guionistaSerie = empty($_POST['guionistaSerie']) ? null : $_POST['guionistaSerie']; + $serie->companiaSerie = empty($_POST['companiaSerie']) ? null : $_POST['companiaSerie']; + $serie->generoSerie = empty($_POST['generoSerie']) ? null : $_POST['generoSerie']; + $serie->anoSerie = empty($_POST['anoSerie']) ? null : $_POST['anoSerie']; + $serie->temporadasSerie = empty($_POST['temporadasSerie']) ? null : $_POST['temporadasSerie']; + $serie->episodiosSerie = empty($_POST['episodiosSerie']) ? null : $_POST['episodiosSerie']; + $serie->ratingAvgSerie = empty($_POST['ratingAvgSerie']) ? null : $_POST['ratingAvgSerie']; + $serie->paisSerie = empty($_POST['paisSerie']) ? null : $_POST['paisSerie']; + $serie->idiomaSerie = empty($_POST['idiomaSerie']) ? null : $_POST['idiomaSerie']; + $serie->posterSerie = empty($_POST['posterSerie']) ? null : $_POST['posterSerie']; + $serie->sinopsisSerie = empty($_POST['sinopsisSerie']) ? null : $_POST['sinopsisSerie']; + + $idSerie = $serie->agregar(); + + if (isset($idSerie['error'])) { + echo json_encode($idSerie); + break; + } + + // Segundo metemos la temporada en seriestemporadas usando el $idSerie, y exista o no devolverÔ su idTemporada. + $temporada = new Temporada(); + + $temporada->idApi = $_POST['idApiTemporada']; + $temporada->idSerie = $idSerie; + $temporada->nombreTemporada = empty($_POST['nombreTemporada']) ? null : $_POST['nombreTemporada']; + $temporada->numeroTemporada = empty($_POST['numeroTemporada']) ? null : $_POST['numeroTemporada']; + $temporada->directorTemporada = empty($_POST['directorTemporada']) ? null : $_POST['directorTemporada']; + $temporada->actorTemporada = empty($_POST['actorTemporada']) ? null : $_POST['actorTemporada']; + $temporada->guionistaTemporada = empty($_POST['guionistaTemporada']) ? null : $_POST['guionistaTemporada']; + $temporada->episodiosTemporada = empty($_POST['episodiosTemporada']) ? null : $_POST['episodiosTemporada']; + $temporada->anoTemporada = empty($_POST['anoTemporada']) ? null : $_POST['anoTemporada']; + $temporada->ratingAvgTemporada = empty($_POST['ratingAvgTemporada']) ? null : $_POST['ratingAvgTemporada']; + $temporada->posterTemporada = empty($_POST['posterTemporada']) ? null : $_POST['posterTemporada']; + $temporada->sinopsisTemporada = empty($_POST['sinopsisTemporada']) ? null : $_POST['sinopsisTemporada']; + + $idTemporada = $temporada->agregar(); + + if (isset($idTemporada['error'])) { + echo json_encode($idTemporada); + break; + } + + // Tercero metemos el episodio en seriesepisodios usando el $idTemporada, y exista o no devolverÔ su idEpisodio. + $episodio = new Episodio(); + + $episodio->idApi = $_POST['idApiEpisodio']; + $episodio->idTemporada = $idTemporada; + $episodio->nombreEpisodio = empty($_POST['nombreEpisodio']) ? null : $_POST['nombreEpisodio']; + $episodio->numeroEpisodio = empty($_POST['numeroEpisodio']) ? null : $_POST['numeroEpisodio']; + $episodio->directorEpisodio = empty($_POST['directorEpisodio']) ? null : $_POST['directorEpisodio']; + $episodio->actorEpisodio = empty($_POST['actorEpisodio']) ? null : $_POST['actorEpisodio']; + $episodio->guionistaEpisodio = empty($_POST['guionistaEpisodio']) ? null : $_POST['guionistaEpisodio']; + $episodio->anoEpisodio = empty($_POST['anoEpisodio']) ? null : $_POST['anoEpisodio']; + $episodio->duracionEpisodio = empty($_POST['duracionEpisodio']) ? null : $_POST['duracionEpisodio']; + $episodio->ratingAvgEpisodio = empty($_POST['ratingAvgEpisodio']) ? null : $_POST['ratingAvgEpisodio']; + $episodio->posterEpisodio = empty($_POST['posterEpisodio']) ? null : $_POST['posterEpisodio']; + $episodio->sinopsisEpisodio = empty($_POST['sinopsisEpisodio']) ? null : $_POST['sinopsisEpisodio']; + + $idEpisodio = $episodio->agregar(); + + if (isset($idEpisodio['error'])) { + echo json_encode($idEpisodio); + break; + } + + // Usamos ese idEpisodio para agregarla a usuariosxepisodios + $usuarioxEpisodio = new UsuarioxEpisodio(); + $usuarioxEpisodio->idUsuario = $_SESSION['idUsuario']; + $usuarioxEpisodio->idEpisodio = $idEpisodio; + + // Comprobamos si ya estÔ registrada, si no se agrega + $resultado = $usuarioxEpisodio->existe(); + + if(!$resultado){ + $resultado = $usuarioxEpisodio->agregarPend(); + + echo json_encode([ + 'idEpisodio' => $idEpisodio, + 'idUsuarioEpisodio' => $resultado + ]); + }else{ + echo json_encode($resultado); + } + + break; + + case 'buscar': + $usuarioxEpisodio = new UsuarioxEpisodio(); + $usuarioxEpisodio->idUsuario = $_SESSION['idUsuario']; + $lista = $usuarioxEpisodio->buscar(); + echo json_encode($lista); + break; + + case 'favorita': + $usuarioxEpisodio = new UsuarioxEpisodio(); + $usuarioxEpisodio->idUsuarioEpisodio = $_POST['idUsuarioEpisodio']; + $usuarioxEpisodio->idUsuario = $_SESSION['idUsuario']; + $usuarioxEpisodio->favEpisodio = $_POST['favEpisodio']; + $resultado = $usuarioxEpisodio -> favorita(); + echo json_encode($resultado); + break; + + case 'comprobar': + $usuarioxEpisodio = new UsuarioxEpisodio(); + $usuarioxEpisodio->idUsuarioEpisodio = $_POST['idUsuarioEpisodio']; + $usuarioxEpisodio->idUsuario = $_SESSION['idUsuario']; + $resultado = $usuarioxEpisodio -> comprobar(); + echo json_encode($resultado); + break; + + case 'comprobarContenido': + $Episodio = new Episodio(); + $Episodio->idEpisodio = $_POST['idEpisodio']; + + echo json_encode($Episodio -> comprobar()); + break; + + case 'editarVal': + $usuarioxEpisodio = new UsuarioxEpisodio(); + $usuarioxEpisodio->idUsuarioEpisodio = $_POST['idUsuarioEpisodio']; + $usuarioxEpisodio->idUsuario = $_SESSION['idUsuario']; + $usuarioxEpisodio->ratingEpisodio = $_POST['ratingEpisodio']; + echo json_encode($usuarioxEpisodio->editarVal()); + break; + + case 'editarFecha': + $usuarioxEpisodio = new UsuarioxEpisodio(); + $usuarioxEpisodio->idUsuarioEpisodio = $_POST['idUsuarioEpisodio']; + $usuarioxEpisodio->idUsuario = $_SESSION['idUsuario']; + $usuarioxEpisodio->fechaEpisodio = empty($_POST['fechaEpisodio']) ? null : $_POST['fechaEpisodio']; + + echo json_encode($usuarioxEpisodio->editarFecha()); + break; + + case 'editarNotas': + $usuarioxEpisodio = new UsuarioxEpisodio(); + $usuarioxEpisodio->idUsuarioEpisodio = $_POST['idUsuarioEpisodio']; + $usuarioxEpisodio->idUsuario = $_SESSION['idUsuario']; + $usuarioxEpisodio->notasEpisodio = empty($_POST['notasEpisodio']) ? null : $_POST['notasEpisodio']; + + echo json_encode($usuarioxEpisodio->editarNotas()); + break; + + case 'agregarPendTabla': + $usuarioxEpisodio = new UsuarioxEpisodio(); + $usuarioxEpisodio->idUsuarioEpisodio = $_POST['idUsuarioEpisodio']; + $usuarioxEpisodio->fechaEpisodio = empty($_POST['fechaEpisodio']) ? null : $_POST['fechaEpisodio']; + $usuarioxEpisodio->ratingEpisodio = empty($_POST['ratingEpisodio']) ? null : $_POST['ratingEpisodio']; + $usuarioxEpisodio->notasEpisodio = empty($_POST['notasEpisodio']) ? null : $_POST['notasEpisodio']; + $usuarioxEpisodio->favEpisodio = $_POST['favEpisodio']; + $usuarioxEpisodio->idUsuario = $_SESSION['idUsuario']; + + echo json_encode($usuarioxEpisodio->agregarPendTabla()); + break; + + case 'eliminar': + $usuarioxEpisodio = new UsuarioxEpisodio(); + $usuarioxEpisodio->idUsuarioEpisodio = $_POST['idUsuarioEpisodio']; + $usuarioxEpisodio->idUsuario = $_SESSION['idUsuario']; + echo json_encode($usuarioxEpisodio->eliminar()); + break; + +} // Fin de switch + + +?> \ No newline at end of file diff --git a/controladores/controladorHistorial.php b/controladores/controladorHistorial.php new file mode 100644 index 0000000..40c29d4 --- /dev/null +++ b/controladores/controladorHistorial.php @@ -0,0 +1,242 @@ +idUsuario = $_SESSION['idUsuario']; + $historial->accionHistorial = $_POST['accion']; + $historial->idUsuarioPelicula = empty($_POST['idUsuarioPelicula']) ? null : $_POST['idUsuarioPelicula']; + + $usuarioxPelicula = new UsuarioxPelicula(); + $usuarioxPelicula->idUsuarioPelicula = $_POST['idUsuarioPelicula']; + $usuarioxPelicula->idUsuario = $_SESSION['idUsuario']; + $resultado1 = $usuarioxPelicula->comprobar(); + + if(isset($resultado1['error'])){ + echo json_encode($resultado1); + break; + } + + $peli = new Pelicula(); + $peli->idPelicula = $resultado1[0]['idPelicula']; + $resultado2 = $peli->comprobar(); + + if(isset($resultado2['error'])){ + echo json_encode($resultado2); + break; + } + + $historial->nombreHistorial = $resultado2[0]['nombrePelicula']; + echo json_encode($historial->agregarPelicula()); + + break; + + case 'listarPelicula': + $historial = new Historial(); + $historial->idUsuario = $_SESSION['idUsuario']; + + echo json_encode($historial->listarPelicula()); + break; + + case 'agregarSerie': + + $historial = new Historial(); + $historial->idUsuario = $_SESSION['idUsuario']; + $historial->accionHistorial = $_POST['accion']; + $historial->idUsuarioSerie = empty($_POST['idUsuarioSerie']) ? null : $_POST['idUsuarioSerie']; + + $usuarioxSerie = new UsuarioxSerie(); + $usuarioxSerie->idUsuarioSerie = $_POST['idUsuarioSerie']; + $usuarioxSerie->idUsuario = $_SESSION['idUsuario']; + $resultado1 = $usuarioxSerie->comprobar(); + + if(isset($resultado1['error'])){ + echo json_encode($resultado1); + break; + } + + $serie = new Serie(); + $serie->idSerie = $resultado1[0]['idSerie']; + $resultado2 = $serie->comprobar(); + + if(isset($resultado2['error'])){ + echo json_encode($resultado2); + break; + } + + $historial->nombreHistorial = $resultado2[0]['nombreSerie']; + echo json_encode($historial->agregarSerie()); + + break; + + case 'agregarTemporada': + $historial = new Historial(); + $historial->idUsuario = $_SESSION['idUsuario']; + $historial->accionHistorial = $_POST['accion']; + $historial->idUsuarioTemporada = empty($_POST['idUsuarioTemporada']) ? null : $_POST['idUsuarioTemporada']; + + $usuarioxTemporada = new UsuarioxTemporada(); + $usuarioxTemporada->idUsuarioTemporada = $_POST['idUsuarioTemporada']; + $usuarioxTemporada->idUsuario = $_SESSION['idUsuario']; + $resultado1 = $usuarioxTemporada->comprobar(); + + if(isset($resultado1['error'])){ + echo json_encode($resultado1); + break; + } + + $temporada = new Temporada(); + $temporada->idTemporada = $resultado1[0]['idTemporada']; + $resultado2 = $temporada->comprobar(); + + if(isset($resultado2['error'])){ + echo json_encode($resultado2); + break; + } + + $historial->nombreHistorial = $resultado2[0]['nombreTemporada']; + echo json_encode($historial->agregarTemporada()); + + break; + + case 'agregarEpisodio': + $historial = new Historial(); + $historial->idUsuario = $_SESSION['idUsuario']; + $historial->accionHistorial = $_POST['accion']; + $historial->idUsuarioEpisodio = empty($_POST['idUsuarioEpisodio']) ? null : $_POST['idUsuarioEpisodio']; + + $usuarioxEpisodio = new UsuarioxEpisodio(); + $usuarioxEpisodio->idUsuarioEpisodio = $_POST['idUsuarioEpisodio']; + $usuarioxEpisodio->idUsuario = $_SESSION['idUsuario']; + $resultado1 = $usuarioxEpisodio->comprobar(); + + if(isset($resultado1['error'])){ + echo json_encode($resultado1); + break; + } + + $episodio = new Episodio(); + $episodio->idEpisodio = $resultado1[0]['idEpisodio']; + $resultado2 = $episodio->comprobar(); + + if(isset($resultado2['error'])){ + echo json_encode($resultado2); + break; + } + + $historial->nombreHistorial = $resultado2[0]['nombreEpisodio']; + echo json_encode($historial->agregarEpisodio()); + + break; + + case 'listarSerie': + $historial = new Historial(); + $historial->idUsuario = $_SESSION['idUsuario']; + + echo json_encode($historial->listarSerie()); + break; + + case 'agregarJuego': + $historial = new Historial(); + $historial->idUsuario = $_SESSION['idUsuario']; + $historial->accionHistorial = $_POST['accion']; + $historial->idUsuarioJuego = empty($_POST['idUsuarioJuego']) ? null : $_POST['idUsuarioJuego']; + + $usuarioxJuego = new UsuarioxJuego(); + $usuarioxJuego->idUsuarioJuego = $_POST['idUsuarioJuego']; + $usuarioxJuego->idUsuario = $_SESSION['idUsuario']; + $resultado1 = $usuarioxJuego->comprobar(); + + if(isset($resultado1['error'])){ + echo json_encode($resultado1); + break; + } + + $juego = new Juego(); + $juego->idJuego = $resultado1[0]['idJuego']; + $resultado2 = $juego->comprobar(); + + if(isset($resultado2['error'])){ + echo json_encode($resultado2); + break; + } + + $historial->nombreHistorial = $resultado2[0]['nombreJuego']; + echo json_encode($historial->agregarJuego()); + + break; + + case 'listarJuego': + $historial = new Historial(); + $historial->idUsuario = $_SESSION['idUsuario']; + + echo json_encode($historial->listarJuego()); + break; + + case 'agregarLibro': + $historial = new Historial(); + $historial->idUsuario = $_SESSION['idUsuario']; + $historial->accionHistorial = $_POST['accion']; + $historial->idUsuarioLibro = empty($_POST['idUsuarioLibro']) ? null : $_POST['idUsuarioLibro']; + + $usuarioxLibro = new UsuarioxLibro(); + $usuarioxLibro->idUsuarioLibro = $_POST['idUsuarioLibro']; + $usuarioxLibro->idUsuario = $_SESSION['idUsuario']; + $resultado1 = $usuarioxLibro->comprobar(); + + if(isset($resultado1['error'])){ + echo json_encode($resultado1); + break; + } + + $libro = new Libro(); + $libro->idLibro = $resultado1[0]['idLibro']; + $resultado2 = $libro->comprobar(); + + if(isset($resultado2['error'])){ + echo json_encode($resultado2); + break; + } + + $historial->nombreHistorial = $resultado2[0]['nombreLibro']; + echo json_encode($historial->agregarLibro()); + + break; + + case 'listarLibro': + $historial = new Historial(); + $historial->idUsuario = $_SESSION['idUsuario']; + + echo json_encode($historial->listarLibro()); + break; + +} // Fin de switch + + +?> \ No newline at end of file diff --git a/controladores/controladorJuego.php b/controladores/controladorJuego.php new file mode 100644 index 0000000..90a884a --- /dev/null +++ b/controladores/controladorJuego.php @@ -0,0 +1,259 @@ +idApi = $_POST['idApi']; + $juego->nombreJuego = empty($_POST['nombreJuego']) ? null : $_POST['nombreJuego']; + $juego->desarrolladorJuego = empty($_POST['desarrolladorJuego']) ? null : $_POST['desarrolladorJuego']; + $juego->editorJuego = empty($_POST['editorJuego']) ? null : $_POST['editorJuego']; + $juego->anoJuego = empty($_POST['anoJuego']) ? null : $_POST['anoJuego']; + $juego->franquiciaJuego = empty($_POST['franquiciaJuego']) ? null : $_POST['franquiciaJuego']; + $juego->generoJuego = empty($_POST['generoJuego']) ? null : $_POST['generoJuego']; + $juego->plataformasJuego = empty($_POST['plataformasJuego']) ? null : $_POST['plataformasJuego']; + $juego->dlcJuego = empty($_POST['dlcJuego']) ? null : $_POST['dlcJuego']; + $juego->expansionJuego = empty($_POST['expansionJuego']) ? null : $_POST['expansionJuego']; + $juego->duracionJuego = empty($_POST['duracionJuego']) ? null : $_POST['duracionJuego']; + $juego->ratingAvgJuego = empty($_POST['ratingAvgJuego']) ? null : $_POST['ratingAvgJuego']; + $juego->posterJuego = empty($_POST['posterJuego']) ? null : $_POST['posterJuego']; + $juego->sinopsisJuego = empty($_POST['sinopsisJuego']) ? null : $_POST['sinopsisJuego']; + + $idJuego = $juego->agregar(); + + if (isset($idJuego['error'])) { + echo json_encode($idJuego); + break; + } + + // Usamos ese idJuego para agregarla a la tabla usuariosxjuegos + $usuarioxJuego = new UsuarioxJuego(); + $usuarioxJuego->idUsuario = $_SESSION['idUsuario']; + $usuarioxJuego->idJuego = $idJuego; + + // Comprobamos si ya estÔ registrada, si no se agrega + $resultado = $usuarioxJuego->existe(); + + if(!$resultado){ + $usuarioxJuego->fechaJuego = empty($_POST['fechaJuego']) ? null : $_POST['fechaJuego']; + $usuarioxJuego->fechaInicioJuego = empty($_POST['fechaInicioJuego']) ? null : $_POST['fechaInicioJuego']; + $usuarioxJuego->plataformaJuego = empty($_POST['plataformaJuego']) ? null : $_POST['plataformaJuego']; + $usuarioxJuego->ratingJuego = empty($_POST['ratingJuego']) ? null : $_POST['ratingJuego']; + $usuarioxJuego->notasJuego = empty($_POST['notasJuego']) ? null : $_POST['notasJuego']; + $usuarioxJuego->favJuego = $_POST['favJuego']; + $resultado = $usuarioxJuego->agregar(); + + echo json_encode([ + 'idJuego' => $idJuego, + 'idUsuarioJuego' => $resultado + ]); + }else{ + echo json_encode($resultado); + } + + break; + + case "buscarApi": + $api = new ApiJuego(); + $resultado = $api->buscar($_POST['nombreJuego']); + + $juegos = []; + foreach($resultado as $item){ + $juegos[] = $api->transformarDatos($item); + } + + echo json_encode($juegos); + break; + + case "detallesApi": + + $api = new ApiJuego(); + $resultado = $api->detalles($_POST["idApi"]); + + if(isset($resultado['error'])){ + echo json_encode($resultado); + break; + } + + $resultado = $api->transformarDatos($resultado); + + echo json_encode($resultado); + + break; + + case 'listarTodo': + $usuarioxJuego = new UsuarioxJuego(); + $usuarioxJuego->idUsuario = $_SESSION['idUsuario']; + $lista = $usuarioxJuego->listarTodo(); + echo json_encode($lista); + break; + + case 'listarEstrellas': + $usuarioxJuego = new UsuarioxJuego(); + $usuarioxJuego->idUsuario = $_SESSION['idUsuario']; + $usuarioxJuego->ratingJuego = $_POST['i']; + $lista = $usuarioxJuego->listarEstrellas(); + echo json_encode($lista); + break; + + case 'listarFav': + $usuarioxJuego = new UsuarioxJuego(); + $usuarioxJuego->idUsuario = $_SESSION['idUsuario']; + $lista = $usuarioxJuego->listarFav(); + echo json_encode($lista); + break; + + case 'listarPendientes': + $usuarioxJuego = new UsuarioxJuego(); + $usuarioxJuego->idUsuario = $_SESSION['idUsuario']; + $lista = $usuarioxJuego->listarPendientes(); + echo json_encode($lista); + break; + + case 'agregarPend': + + // La metemos en la tabla juegos, exista o no, devolverÔ su idJuego. + $juego = new Juego(); + + $juego->idApi = $_POST['idApi']; + $juego->nombreJuego = empty($_POST['nombreJuego']) ? null : $_POST['nombreJuego']; + $juego->desarrolladorJuego = empty($_POST['desarrolladorJuego']) ? null : $_POST['desarrolladorJuego']; + $juego->editorJuego = empty($_POST['editorJuego']) ? null : $_POST['editorJuego']; + $juego->anoJuego = empty($_POST['anoJuego']) ? null : $_POST['anoJuego']; + $juego->franquiciaJuego = empty($_POST['franquiciaJuego']) ? null : $_POST['franquiciaJuego']; + $juego->generoJuego = empty($_POST['generoJuego']) ? null : $_POST['generoJuego']; + $juego->plataformasJuego = empty($_POST['plataformasJuego']) ? null : $_POST['plataformasJuego']; + $juego->dlcJuego = empty($_POST['dlcJuego']) ? null : $_POST['dlcJuego']; + $juego->expansionJuego = empty($_POST['expansionJuego']) ? null : $_POST['expansionJuego']; + $juego->duracionJuego = empty($_POST['duracionJuego']) ? null : $_POST['duracionJuego']; + $juego->ratingAvgJuego = empty($_POST['ratingAvgJuego']) ? null : $_POST['ratingAvgJuego']; + $juego->posterJuego = empty($_POST['posterJuego']) ? null : $_POST['posterJuego']; + $juego->sinopsisJuego = empty($_POST['sinopsisJuego']) ? null : $_POST['sinopsisJuego']; + + $idJuego = $juego->agregar(); + + if (isset($idJuego['error'])) { + echo json_encode($idJuego); + break; + } + + // Usamos ese idJuego para agregarla como pendiente a la tabla usuariosxjuegos + $usuarioxJuego = new UsuarioxJuego(); + $usuarioxJuego->idUsuario = $_SESSION['idUsuario']; + $usuarioxJuego->idJuego = $idJuego; + + // Comprobamos si ya estÔ registrada, si no se agrega + $resultado = $usuarioxJuego->existe(); + if(!$resultado){ + $resultado = $usuarioxJuego->agregarPend(); + + echo json_encode([ + 'idJuego' => $idJuego, + 'idUsuarioJuego' => $resultado + ]); + }else{ + echo json_encode($resultado); + } + break; + + case 'buscar': + $usuarioxJuego = new UsuarioxJuego(); + $usuarioxJuego->idUsuario = $_SESSION['idUsuario']; + $lista = $usuarioxJuego->buscar(); + echo json_encode($lista); + break; + + case 'favorita': + $usuarioxJuego = new UsuarioxJuego(); + $usuarioxJuego->idUsuarioJuego = $_POST['idUsuarioJuego']; + $usuarioxJuego->idUsuario = $_SESSION['idUsuario']; + $usuarioxJuego->favJuego = $_POST['favJuego']; + $resultado = $usuarioxJuego -> favorita(); + echo json_encode($resultado); + break; + + case 'comprobar': + $usuarioxJuego = new UsuarioxJuego(); + $usuarioxJuego->idUsuarioJuego = $_POST['idUsuarioJuego']; + $usuarioxJuego->idUsuario = $_SESSION['idUsuario']; + $resultado = $usuarioxJuego -> comprobar(); + echo json_encode($resultado); + break; + + case 'comprobarContenido': + $juego = new Juego(); + $juego->idJuego = $_POST['idJuego']; + + echo json_encode($juego -> comprobar()); + break; + + case 'editarVal': + $usuarioxJuego = new UsuarioxJuego(); + $usuarioxJuego->idUsuarioJuego = $_POST['idUsuarioJuego']; + $usuarioxJuego->idUsuario = $_SESSION['idUsuario']; + $usuarioxJuego->ratingJuego = $_POST['ratingJuego']; + echo json_encode($usuarioxJuego->editarVal()); + break; + + case 'editarFecha': + $usuarioxJuego = new UsuarioxJuego(); + $usuarioxJuego->idUsuarioJuego = $_POST['idUsuarioJuego']; + $usuarioxJuego->idUsuario = $_SESSION['idUsuario']; + $usuarioxJuego->fechaJuego = empty($_POST['fechaJuego']) ? null : $_POST['fechaJuego']; + $usuarioxJuego->fechaInicioJuego = empty($_POST['fechaInicioJuego']) ? null : $_POST['fechaInicioJuego']; + + echo json_encode($usuarioxJuego->editarFecha()); + break; + + case 'editarPlataforma': + $usuarioxJuego = new UsuarioxJuego(); + $usuarioxJuego->idUsuarioJuego = $_POST['idUsuarioJuego']; + $usuarioxJuego->idUsuario = $_SESSION['idUsuario']; + $usuarioxJuego->plataformaJuego = $_POST['plataformaJuego']; + echo json_encode($usuarioxJuego->editarPlataforma()); + break; + + case 'editarNotas': + $usuarioxJuego = new UsuarioxJuego(); + $usuarioxJuego->idUsuarioJuego = $_POST['idUsuarioJuego']; + $usuarioxJuego->idUsuario = $_SESSION['idUsuario']; + $usuarioxJuego->notasJuego = empty($_POST['notasJuego']) ? null : $_POST['notasJuego']; + + echo json_encode($usuarioxJuego->editarNotas()); + break; + + case 'agregarPendTabla': + $usuarioxJuego = new UsuarioxJuego(); + $usuarioxJuego->idUsuarioJuego = $_POST['idUsuarioJuego']; + $usuarioxJuego->fechaJuego = empty($_POST['fechaJuego']) ? null : $_POST['fechaJuego']; + $usuarioxJuego->fechaInicioJuego = empty($_POST['fechaInicioJuego']) ? null : $_POST['fechaInicioJuego']; + $usuarioxJuego->plataformaJuego = empty($_POST['plataformaJuego']) ? null : $_POST['plataformaJuego']; + $usuarioxJuego->ratingJuego = empty($_POST['ratingJuego']) ? null : $_POST['ratingJuego']; + $usuarioxJuego->notasJuego = empty($_POST['notasJuego']) ? null : $_POST['notasJuego']; + $usuarioxJuego->favJuego = $_POST['favJuego']; + $usuarioxJuego->idUsuario = $_SESSION['idUsuario']; + + echo json_encode($usuarioxJuego->agregarPendTabla()); + break; + + case 'eliminar': + $usuarioxJuego = new UsuarioxJuego(); + $usuarioxJuego->idUsuarioJuego = $_POST['idUsuarioJuego']; + $usuarioxJuego->idUsuario = $_SESSION['idUsuario']; + echo json_encode($usuarioxJuego->eliminar()); + break; + +} // Fin de switch + + +?> \ No newline at end of file diff --git a/controladores/controladorLibro.php b/controladores/controladorLibro.php new file mode 100644 index 0000000..f418344 --- /dev/null +++ b/controladores/controladorLibro.php @@ -0,0 +1,319 @@ +idApi = $_POST['idApi']; + $libro->nombreLibro = empty($_POST['nombreLibro']) ? null : $_POST['nombreLibro']; + $libro->autorLibro = empty($_POST['autorLibro']) ? null : $_POST['autorLibro']; + $libro->anoLibro = empty($_POST['anoLibro']) ? null : $_POST['anoLibro']; + $libro->generoLibro = empty($_POST['generoLibro']) ? null : $_POST['generoLibro']; + $libro->temaLibro = empty($_POST['temaLibro']) ? null : $_POST['temaLibro']; + $libro->paginasLibro = empty($_POST['paginasLibro']) ? null : $_POST['paginasLibro']; + $libro->edicionesLibro = empty($_POST['edicionesLibro']) ? null : $_POST['edicionesLibro']; + $libro->idiomaLibro = empty($_POST['idiomaLibro']) ? null : $_POST['idiomaLibro']; + $libro->ratingAvgLibro = empty($_POST['ratingAvgLibro']) ? null : $_POST['ratingAvgLibro']; + $libro->posterLibro = empty($_POST['posterLibro']) ? null : $_POST['posterLibro']; + $libro->sinopsisLibro = empty($_POST['sinopsisLibro']) ? null : $_POST['sinopsisLibro']; + + // Exista o no, agregar() devolverÔ su idLibro + $idLibro = $libro->agregar(); + + if (isset($idLibro['error'])) { + echo json_encode($idLibro); + break; + } + + // Usamos ese idLibro para agregarlo a la tabla usuariosxlibros + $usuarioxLibro = new UsuarioxLibro(); + $usuarioxLibro->idUsuario = $_SESSION['idUsuario']; + $usuarioxLibro->idLibro = $idLibro; + + // Comprobamos si ya estÔ registrado, si no se agrega + $resultado = $usuarioxLibro->existe(); + + if(!$resultado){ + $usuarioxLibro->fechaLibro = empty($_POST['fechaLibro']) ? null : $_POST['fechaLibro']; + $usuarioxLibro->fechaInicioLibro = empty($_POST['fechaInicioLibro']) ? null : $_POST['fechaInicioLibro']; + $usuarioxLibro->ratingLibro = empty($_POST['ratingLibro']) ? null : $_POST['ratingLibro']; + $usuarioxLibro->notasLibro = empty($_POST['notasLibro']) ? null : $_POST['notasLibro']; + $usuarioxLibro->favLibro = $_POST['favLibro']; + $resultado = $usuarioxLibro->agregar(); + + echo json_encode([ + 'idLibro' => $idLibro, + 'idUsuarioLibro' => $resultado + ]); + + }else{ + echo json_encode($resultado); + } + + break; + + case 'descargarPoster': + + $libro = new Libro(); + $api = new ApiLibro(); + + $libro->idLibro = $_POST['idLibro']; + + $url = $_POST['posterLibro'] ?? ''; + + /* + * Descargamos la portada desde Open Library. + */ + $posterLocal = $api->descargarPortada($url); + + if(empty($posterLocal)){ + echo json_encode([ + 'error' => 'No se pudo descargar la portada del libro.' + ]); + break; + } + + $libro->posterLibro = $posterLocal; + $resultado = $libro->actualizarPoster(); + echo json_encode($resultado); + + break; + + case "buscarApi": + + $api = new ApiLibro(); + + $resultado = $api->buscar($_POST['nombreLibro']); + + $libros = []; + foreach($resultado as $item){ + $libros[] = $api->transformarDatos($item); + } + + echo json_encode($libros); + + break; + + case "detallesApi": + + $api = new ApiLibro(); + + $resultado = $api->detalles($_POST["idApi"]); + + if(isset($resultado['error'])){ + echo json_encode($resultado); + break; + } + + $resultado = $api->transformarDatos($resultado); + + echo json_encode($resultado); + + break; + + case 'listarTodo': + + $usuarioxLibro = new UsuarioxLibro(); + $usuarioxLibro->idUsuario = $_SESSION['idUsuario']; + $lista = $usuarioxLibro->listarTodo(); + + echo json_encode($lista); + + break; + + case 'listarEstrellas': + + $usuarioxLibro = new UsuarioxLibro(); + $usuarioxLibro->idUsuario = $_SESSION['idUsuario']; + $usuarioxLibro->ratingLibro = $_POST['i']; + $lista = $usuarioxLibro->listarEstrellas(); + + echo json_encode($lista); + + break; + + case 'listarFav': + + $usuarioxLibro = new UsuarioxLibro(); + $usuarioxLibro->idUsuario = $_SESSION['idUsuario']; + $lista = $usuarioxLibro->listarFav(); + + echo json_encode($lista); + + break; + + case 'listarPendientes': + + $usuarioxLibro = new UsuarioxLibro(); + $usuarioxLibro->idUsuario = $_SESSION['idUsuario']; + $lista = $usuarioxLibro->listarPendientes(); + + echo json_encode($lista); + + break; + + case 'agregarPend': + + // La metemos en la tabla libros, exista o no, devolverÔ su idLibro. + $libro = new Libro(); + + $libro->idApi = $_POST['idApi']; + $libro->nombreLibro = empty($_POST['nombreLibro']) ? null : $_POST['nombreLibro']; + $libro->autorLibro = empty($_POST['autorLibro']) ? null : $_POST['autorLibro']; + $libro->anoLibro = empty($_POST['anoLibro']) ? null : $_POST['anoLibro']; + $libro->generoLibro = empty($_POST['generoLibro']) ? null : $_POST['generoLibro']; + $libro->temaLibro = empty($_POST['temaLibro']) ? null : $_POST['temaLibro']; + $libro->paginasLibro = empty($_POST['paginasLibro']) ? null : $_POST['paginasLibro']; + $libro->edicionesLibro = empty($_POST['edicionesLibro']) ? null : $_POST['edicionesLibro']; + $libro->idiomaLibro = empty($_POST['idiomaLibro']) ? null : $_POST['idiomaLibro']; + $libro->ratingAvgLibro = empty($_POST['ratingAvgLibro']) ? null : $_POST['ratingAvgLibro']; + $libro->posterLibro = empty($_POST['posterLibro']) ? null : $_POST['posterLibro']; + $libro->sinopsisLibro = empty($_POST['sinopsisLibro']) ? null : $_POST['sinopsisLibro']; + + $idLibro = $libro->agregar(); + + if (isset($idLibro['error'])) { + echo json_encode($idLibro); + break; + } + + // Usamos ese idLibro para agregarlo como pendiente a la tabla usuariosxlibros + $usuarioxLibro = new UsuarioxLibro(); + + $usuarioxLibro->idUsuario = $_SESSION['idUsuario']; + $usuarioxLibro->idLibro = $idLibro; + + // Comprobamos si ya estÔ registrado, si no se agrega + $resultado = $usuarioxLibro->existe(); + + if(!$resultado){ + $resultado = $usuarioxLibro->agregarPend(); + + echo json_encode([ + 'idLibro' => $idLibro, + 'idUsuarioLibro' => $resultado + ]); + + }else{ + echo json_encode($resultado); + } + + break; + + case 'buscar': + + $usuarioxLibro = new UsuarioxLibro(); + $usuarioxLibro->idUsuario = $_SESSION['idUsuario']; + $lista = $usuarioxLibro->buscar(); + + echo json_encode($lista); + + break; + + case 'favorita': + + $usuarioxLibro = new UsuarioxLibro(); + $usuarioxLibro->idUsuarioLibro = $_POST['idUsuarioLibro']; + $usuarioxLibro->idUsuario = $_SESSION['idUsuario']; + $usuarioxLibro->favLibro = $_POST['favLibro']; + $resultado = $usuarioxLibro->favorita(); + + echo json_encode($resultado); + + break; + + case 'comprobar': + + $usuarioxLibro = new UsuarioxLibro(); + $usuarioxLibro->idUsuarioLibro = $_POST['idUsuarioLibro']; + $usuarioxLibro->idUsuario = $_SESSION['idUsuario']; + $resultado = $usuarioxLibro->comprobar(); + + echo json_encode($resultado); + + break; + + case 'comprobarContenido': + + $libro = new Libro(); + $libro->idLibro = $_POST['idLibro']; + + echo json_encode($libro->comprobar()); + + break; + + case 'editarVal': + + $usuarioxLibro = new UsuarioxLibro(); + $usuarioxLibro->idUsuarioLibro = $_POST['idUsuarioLibro']; + $usuarioxLibro->idUsuario = $_SESSION['idUsuario']; + $usuarioxLibro->ratingLibro = $_POST['ratingLibro']; + + echo json_encode($usuarioxLibro->editarVal()); + + break; + + case 'editarFecha': + + $usuarioxLibro = new UsuarioxLibro(); + $usuarioxLibro->idUsuarioLibro = $_POST['idUsuarioLibro']; + $usuarioxLibro->idUsuario = $_SESSION['idUsuario']; + $usuarioxLibro->fechaLibro = empty($_POST['fechaLibro']) ? null : $_POST['fechaLibro']; + $usuarioxLibro->fechaInicioLibro = empty($_POST['fechaInicioLibro']) ? null : $_POST['fechaInicioLibro']; + + echo json_encode($usuarioxLibro->editarFecha()); + + break; + + case 'editarNotas': + + $usuarioxLibro = new UsuarioxLibro(); + $usuarioxLibro->idUsuarioLibro = $_POST['idUsuarioLibro']; + $usuarioxLibro->idUsuario = $_SESSION['idUsuario']; + $usuarioxLibro->notasLibro = empty($_POST['notasLibro']) ? null : $_POST['notasLibro']; + + echo json_encode($usuarioxLibro->editarNotas()); + + break; + + case 'agregarPendTabla': + + $usuarioxLibro = new UsuarioxLibro(); + $usuarioxLibro->idUsuarioLibro = $_POST['idUsuarioLibro']; + $usuarioxLibro->fechaLibro = empty($_POST['fechaLibro']) ? null : $_POST['fechaLibro']; + $usuarioxLibro->fechaInicioLibro = empty($_POST['fechaInicioLibro']) ? null : $_POST['fechaInicioLibro']; + $usuarioxLibro->ratingLibro = empty($_POST['ratingLibro']) ? null : $_POST['ratingLibro']; + $usuarioxLibro->notasLibro = empty($_POST['notasLibro']) ? null : $_POST['notasLibro']; + $usuarioxLibro->favLibro = $_POST['favLibro']; + $usuarioxLibro->idUsuario = $_SESSION['idUsuario']; + + echo json_encode($usuarioxLibro->agregarPendTabla()); + + break; + + case 'eliminar': + + $usuarioxLibro = new UsuarioxLibro(); + $usuarioxLibro->idUsuarioLibro = $_POST['idUsuarioLibro']; + $usuarioxLibro->idUsuario = $_SESSION['idUsuario']; + + echo json_encode($usuarioxLibro->eliminar()); + + break; + +} // Fin de switch + + +?> \ No newline at end of file diff --git a/controladores/controladorPelicula.php b/controladores/controladorPelicula.php new file mode 100644 index 0000000..c39a8af --- /dev/null +++ b/controladores/controladorPelicula.php @@ -0,0 +1,326 @@ +idApi = $_POST['idApi']; + $pelicula->nombrePelicula = empty($_POST['nombrePelicula']) ? null : $_POST['nombrePelicula']; + $pelicula->directorPelicula = empty($_POST['directorPelicula']) ? null : $_POST['directorPelicula']; + $pelicula->actorPelicula = empty($_POST['actorPelicula']) ? null : $_POST['actorPelicula']; + $pelicula->guionistaPelicula = empty($_POST['guionistaPelicula']) ? null : $_POST['guionistaPelicula']; + $pelicula->generoPelicula = empty($_POST['generoPelicula']) ? null : $_POST['generoPelicula']; + $pelicula->anoPelicula = empty($_POST['anoPelicula']) ? null : $_POST['anoPelicula']; + $pelicula->companiaPelicula = empty($_POST['companiaPelicula']) ? null : $_POST['companiaPelicula']; + $pelicula->duracionPelicula = empty($_POST['duracionPelicula']) ? null : $_POST['duracionPelicula']; + $pelicula->ratingAvgPelicula = empty($_POST['ratingAvgPelicula']) ? null : $_POST['ratingAvgPelicula']; + $pelicula->paisPelicula = empty($_POST['paisPelicula']) ? null : $_POST['paisPelicula']; + $pelicula->idiomaPelicula = empty($_POST['idiomaPelicula']) ? null : $_POST['idiomaPelicula']; + $pelicula->posterPelicula = empty($_POST['posterPelicula']) ? null : $_POST['posterPelicula']; + $pelicula->sinopsisPelicula = empty($_POST['sinopsisPelicula']) ? null : $_POST['sinopsisPelicula']; + + $idPelicula = $pelicula->agregar(); + + if (isset($idPelicula['error'])) { + echo json_encode($idPelicula); + break; + } + + // Usamos ese idPelicula para agregarla a la tabla usuariosxpeliculas + $usuarioxPelicula = new UsuarioxPelicula(); + $usuarioxPelicula->idUsuario = $_SESSION['idUsuario']; + $usuarioxPelicula->idPelicula = $idPelicula; + + // Comprobamos si ya estÔ registrada, si no se agrega + $resultado = $usuarioxPelicula->existe(); + if(!$resultado){ + $usuarioxPelicula->fechaPelicula = empty($_POST['fechaPelicula']) ? null : $_POST['fechaPelicula']; + $usuarioxPelicula->ratingPelicula = empty($_POST['ratingPelicula']) ? null : $_POST['ratingPelicula']; + $usuarioxPelicula->notasPelicula = empty($_POST['notasPelicula']) ? null : $_POST['notasPelicula']; + $usuarioxPelicula->favPelicula = $_POST['favPelicula']; + $resultado = $usuarioxPelicula->agregar(); + + echo json_encode([ + 'idPelicula' => $idPelicula, + 'idUsuarioPelicula' => $resultado + ]); + }else{ + echo json_encode($resultado); + } + break; + + case "buscarApi": + $api = new ApiPelicula(); + $resultado = $api->buscar($_POST['nombrePelicula']); + + $peliculas = []; + foreach($resultado["results"] as $item){ + $peliculas[] = $api->transformarDatos($item); + } + + echo json_encode($peliculas); + break; + + case "detallesApi": + + $api = new ApiPelicula(); + $resultado = $api->detalles($_POST["idApi"]); + $resultado = $api->transformarDatos($resultado); + + echo json_encode($resultado); + + break; + + case 'listarTodo': + $usuarioxPelicula = new UsuarioxPelicula(); + $usuarioxPelicula->idUsuario = $_SESSION['idUsuario']; + $lista = $usuarioxPelicula->listarTodo(); + echo json_encode($lista); + break; + + case 'listarEstrellas': + $usuarioxPelicula = new UsuarioxPelicula(); + $usuarioxPelicula->idUsuario = $_SESSION['idUsuario']; + $usuarioxPelicula->ratingPelicula = $_POST['i']; + $lista = $usuarioxPelicula->listarEstrellas(); + echo json_encode($lista); + break; + + case 'listarFav': + $usuarioxPelicula = new UsuarioxPelicula(); + $usuarioxPelicula->idUsuario = $_SESSION['idUsuario']; + $lista = $usuarioxPelicula->listarFav(); + echo json_encode($lista); + break; + + case 'listarPendientes': + $usuarioxPelicula = new UsuarioxPelicula(); + $usuarioxPelicula->idUsuario = $_SESSION['idUsuario']; + $lista = $usuarioxPelicula->listarPendientes(); + echo json_encode($lista); + break; + + case 'agregarPend': + + // La metemos en la tabla películas, exista o no, devolverÔ su idPelicula. + $pelicula = new Pelicula(); + + $pelicula->idApi = $_POST['idApi']; + $pelicula->nombrePelicula = empty($_POST['nombrePelicula']) ? null : $_POST['nombrePelicula']; + $pelicula->directorPelicula = empty($_POST['directorPelicula']) ? null : $_POST['directorPelicula']; + $pelicula->actorPelicula = empty($_POST['actorPelicula']) ? null : $_POST['actorPelicula']; + $pelicula->guionistaPelicula = empty($_POST['guionistaPelicula']) ? null : $_POST['guionistaPelicula']; + $pelicula->generoPelicula = empty($_POST['generoPelicula']) ? null : $_POST['generoPelicula']; + $pelicula->anoPelicula = empty($_POST['anoPelicula']) ? null : $_POST['anoPelicula']; + $pelicula->companiaPelicula = empty($_POST['companiaPelicula']) ? null : $_POST['companiaPelicula']; + $pelicula->duracionPelicula = empty($_POST['duracionPelicula']) ? null : $_POST['duracionPelicula']; + $pelicula->ratingAvgPelicula = empty($_POST['ratingAvgPelicula']) ? null : $_POST['ratingAvgPelicula']; + $pelicula->paisPelicula = empty($_POST['paisPelicula']) ? null : $_POST['paisPelicula']; + $pelicula->idiomaPelicula = empty($_POST['idiomaPelicula']) ? null : $_POST['idiomaPelicula']; + $pelicula->posterPelicula = empty($_POST['posterPelicula']) ? null : $_POST['posterPelicula']; + $pelicula->sinopsisPelicula = empty($_POST['sinopsisPelicula']) ? null : $_POST['sinopsisPelicula']; + + $idPelicula = $pelicula->agregar(); + + if (isset($idPelicula['error'])) { + echo json_encode($idPelicula); + break; + } + + // Usamos ese idPelicula para agregarla como pendiente a la tabla usuariosxpeliculas + $usuarioxPelicula = new UsuarioxPelicula(); + $usuarioxPelicula->idUsuario = $_SESSION['idUsuario']; + $usuarioxPelicula->idPelicula = $idPelicula; + + // Comprobamos si ya estÔ registrada, si no se agrega + $resultado = $usuarioxPelicula->existe(); + if(!$resultado){ + $resultado = $usuarioxPelicula->agregarPend(); + + echo json_encode([ + 'idPelicula' => $idPelicula, + 'idUsuarioPelicula' => $resultado + ]); + }else{ + echo json_encode($resultado); + } + break; + + case 'buscar': + $usuarioxPelicula = new UsuarioxPelicula(); + $usuarioxPelicula->idUsuario = $_SESSION['idUsuario']; + $lista = $usuarioxPelicula->buscar(); + echo json_encode($lista); + break; + + case 'favorita': + $usuarioxPelicula = new UsuarioxPelicula(); + $usuarioxPelicula->idUsuarioPelicula = $_POST['idUsuarioPelicula']; + $usuarioxPelicula->idUsuario = $_SESSION['idUsuario']; + $usuarioxPelicula->favPelicula = $_POST['favPelicula']; + $resultado = $usuarioxPelicula -> favorita(); + echo json_encode($resultado); + break; + + case 'comprobar': + $usuarioxPelicula = new UsuarioxPelicula(); + $usuarioxPelicula->idUsuarioPelicula = $_POST['idUsuarioPelicula']; + $usuarioxPelicula->idUsuario = $_SESSION['idUsuario']; + $resultado = $usuarioxPelicula -> comprobar(); + echo json_encode($resultado); + break; + + case 'comprobarContenido': + $pelicula = new Pelicula(); + $pelicula->idPelicula = $_POST['idPelicula']; + + echo json_encode($pelicula -> comprobar()); + break; + + case 'editarVal': + $usuarioxPelicula = new UsuarioxPelicula(); + $usuarioxPelicula->idUsuarioPelicula = $_POST['idUsuarioPelicula']; + $usuarioxPelicula->idUsuario = $_SESSION['idUsuario']; + $usuarioxPelicula->ratingPelicula = $_POST['ratingPelicula']; + echo json_encode($usuarioxPelicula->editarVal()); + break; + + case 'editarFecha': + $usuarioxPelicula = new UsuarioxPelicula(); + $usuarioxPelicula->idUsuarioPelicula = $_POST['idUsuarioPelicula']; + $usuarioxPelicula->idUsuario = $_SESSION['idUsuario']; + $usuarioxPelicula->fechaPelicula = empty($_POST['fechaPelicula']) ? null : $_POST['fechaPelicula']; + + echo json_encode($usuarioxPelicula->editarFecha()); + break; + + case 'editarNotas': + $usuarioxPelicula = new UsuarioxPelicula(); + $usuarioxPelicula->idUsuarioPelicula = $_POST['idUsuarioPelicula']; + $usuarioxPelicula->idUsuario = $_SESSION['idUsuario']; + $usuarioxPelicula->notasPelicula = empty($_POST['notasPelicula']) ? null : $_POST['notasPelicula']; + + echo json_encode($usuarioxPelicula->editarNotas()); + break; + + case 'agregarPendTabla': + $usuarioxPelicula = new UsuarioxPelicula(); + $usuarioxPelicula->idUsuarioPelicula = $_POST['idUsuarioPelicula']; + $usuarioxPelicula->fechaPelicula = empty($_POST['fechaPelicula']) ? null : $_POST['fechaPelicula']; + $usuarioxPelicula->ratingPelicula = empty($_POST['ratingPelicula']) ? null : $_POST['ratingPelicula']; + $usuarioxPelicula->notasPelicula = empty($_POST['notasPelicula']) ? null : $_POST['notasPelicula']; + $usuarioxPelicula->favPelicula = $_POST['favPelicula']; + $usuarioxPelicula->idUsuario = $_SESSION['idUsuario']; + + echo json_encode($usuarioxPelicula->agregarPendTabla()); + break; + + case 'eliminar': + $usuarioxPelicula = new UsuarioxPelicula(); + $usuarioxPelicula->idUsuarioPelicula = $_POST['idUsuarioPelicula']; + $usuarioxPelicula->idUsuario = $_SESSION['idUsuario']; + echo json_encode($usuarioxPelicula->eliminar()); + break; + + case 'actualizarDetalles': + + $pelicula = new Pelicula(); + + $peliculas = $pelicula->listarIdApi(); + + if(isset($peliculas['error'])){ + echo json_encode($peliculas); + break; + } + + $api = new ApiPelicula(); + + $actualizadas = 0; + $errores = 0; + + foreach($peliculas as $fila){ + + /* + * Obtenemos los detalles de TMDB + */ + $resultado = $api->detalles($fila['idApi']); + + if(isset($resultado['status_code'])){ + + $errores++; + continue; + } + + + /* + * Transformamos los datos + */ + $datos = $api->transformarDatos($resultado); + + + /* + * Preparamos la película + */ + $pelicula->idPelicula = $fila['idPelicula']; + + $pelicula->actorPelicula = + $datos['actorPelicula'] ?? ''; + + $pelicula->guionistaPelicula = + $datos['guionistaPelicula'] ?? ''; + + $pelicula->generoPelicula = + $datos['generoPelicula'] ?? ''; + + $pelicula->duracionPelicula = + $datos['duracionPelicula'] ?? null; + + $pelicula->companiaPelicula = + $datos['companiaPelicula'] ?? ''; + + $pelicula->paisPelicula = + $datos['paisPelicula'] ?? ''; + + $pelicula->idiomaPelicula = + $datos['idiomaPelicula'] ?? ''; + + + /* + * Actualizamos la BD + */ + $resultadoUpdate = + $pelicula->actualizarDetalles(); + + if($resultadoUpdate === true){ + + $actualizadas++; + + }else{ + + $errores++; + } + } + + + echo json_encode([ + 'actualizadas' => $actualizadas, + 'errores' => $errores, + 'total' => count($peliculas) + ]); + + break; + +} // Fin de switch + + +?> \ No newline at end of file diff --git a/controladores/controladorSerie.php b/controladores/controladorSerie.php new file mode 100644 index 0000000..a1ed794 --- /dev/null +++ b/controladores/controladorSerie.php @@ -0,0 +1,302 @@ +idApi = $_POST['idApi']; + $serie->nombreSerie = empty($_POST['nombreSerie']) ? null : $_POST['nombreSerie']; + $serie->creadorSerie = empty($_POST['creadorSerie']) ? null : $_POST['creadorSerie']; + $serie->directorSerie = empty($_POST['directorSerie']) ? null : $_POST['directorSerie']; + $serie->actorSerie = empty($_POST['actorSerie']) ? null : $_POST['actorSerie']; + $serie->guionistaSerie = empty($_POST['guionistaSerie']) ? null : $_POST['guionistaSerie']; + $serie->companiaSerie = empty($_POST['companiaSerie']) ? null : $_POST['companiaSerie']; + $serie->generoSerie = empty($_POST['generoSerie']) ? null : $_POST['generoSerie']; + $serie->anoSerie = empty($_POST['anoSerie']) ? null : $_POST['anoSerie']; + $serie->temporadasSerie = empty($_POST['temporadasSerie']) ? null : $_POST['temporadasSerie']; + $serie->episodiosSerie = empty($_POST['episodiosSerie']) ? null : $_POST['episodiosSerie']; + $serie->ratingAvgSerie = empty($_POST['ratingAvgSerie']) ? null : $_POST['ratingAvgSerie']; + $serie->paisSerie = empty($_POST['paisSerie']) ? null : $_POST['paisSerie']; + $serie->idiomaSerie = empty($_POST['idiomaSerie']) ? null : $_POST['idiomaSerie']; + $serie->posterSerie = empty($_POST['posterSerie']) ? null : $_POST['posterSerie']; + $serie->sinopsisSerie = empty($_POST['sinopsisSerie']) ? null : $_POST['sinopsisSerie']; + + $idSerie = $serie->agregar(); + + if (isset($idSerie['error'])) { + echo json_encode($idSerie); + break; + } + + // Usamos ese idSerie para agregarla a la tabla usuariosxseries + $usuarioxSerie = new UsuarioxSerie(); + $usuarioxSerie->idUsuario = $_SESSION['idUsuario']; + $usuarioxSerie->idSerie = $idSerie; + + // Comprobamos si ya estÔ registrada, si no se agrega + $resultado = $usuarioxSerie->existe(); + + if(!$resultado){ + $usuarioxSerie->fechaSerie = empty($_POST['fechaSerie']) ? null : $_POST['fechaSerie']; + $usuarioxSerie->estadoSerie = empty($_POST['estadoSerie']) ? null : $_POST['estadoSerie']; + $usuarioxSerie->ratingSerie = empty($_POST['ratingSerie']) ? null : $_POST['ratingSerie']; + $usuarioxSerie->notasSerie = empty($_POST['notasSerie']) ? null : $_POST['notasSerie']; + $usuarioxSerie->favSerie = $_POST['favSerie']; + $resultado = $usuarioxSerie->agregar(); + + echo json_encode([ + 'idSerie' => $idSerie, + 'idUsuarioSerie' => $resultado + ]); + }else{ + echo json_encode($resultado); + } + + break; + + case "buscarApi": + $api = new ApiSerie(); + $resultado = $api->buscar($_POST['nombreSerie']); + + $series = []; + foreach($resultado as $item){ + $series[] = $api->transformarDatos($item); + } + + echo json_encode($series); + break; + + case "detallesApi": + + $api = new ApiSerie(); + $resultado = $api->detalles($_POST["idApi"]); + + if(isset($resultado['error'])){ + echo json_encode($resultado); + break; + } + + $resultado = $api->transformarDatos($resultado); + + echo json_encode($resultado); + + break; + + case 'detallesApiTemporada': + $api = new ApiSerie(); + $resultado = $api->temporada($_POST['idApiSerie'],$_POST['numeroTemporada']); + + if(isset($resultado['error'])){ + echo json_encode($resultado); + break; + } + + $resultado = $api->transformarDatosTemporada($resultado, $_POST['nombreSerie']); + echo json_encode($resultado); + + break; + + case 'detallesApiEpisodio': + $api = new ApiSerie(); + $resultado = $api->episodio($_POST['idApiSerie'], $_POST['numeroTemporada'], $_POST['numeroEpisodio']); + + if(isset($resultado['error'])){ + echo json_encode($resultado); + break; + } + + $resultado = $api->transformarDatosEpisodio($resultado, $_POST['numeroTemporada'], $_POST['nombreSerie']); + echo json_encode($resultado); + + break; + + case 'listarTodo': + $usuarioxSerie = new UsuarioxSerie(); + $usuarioxSerie->idUsuario = $_SESSION['idUsuario']; + $lista = $usuarioxSerie->listarTodo(); + echo json_encode($lista); + break; + + case 'listarEstrellas': + $usuarioxSerie = new UsuarioxSerie(); + $usuarioxSerie->idUsuario = $_SESSION['idUsuario']; + $usuarioxSerie->ratingSerie = $_POST['i']; + $lista = $usuarioxSerie->listarEstrellas(); + echo json_encode($lista); + break; + + case 'listarFav': + $usuarioxSerie = new UsuarioxSerie(); + $usuarioxSerie->idUsuario = $_SESSION['idUsuario']; + $lista = $usuarioxSerie->listarFav(); + echo json_encode($lista); + break; + + case 'listarPendientes': + $usuarioxSerie = new UsuarioxSerie(); + $usuarioxSerie->idUsuario = $_SESSION['idUsuario']; + $lista = $usuarioxSerie->listarPendientes(); + echo json_encode($lista); + break; + + case 'agregarPend': + + // La metemos en la tabla series, exista o no, devolverÔ su idSerie. + $serie = new Serie(); + + $serie->idApi = $_POST['idApi']; + $serie->nombreSerie = empty($_POST['nombreSerie']) ? null : $_POST['nombreSerie']; + $serie->creadorSerie = empty($_POST['creadorSerie']) ? null : $_POST['creadorSerie']; + $serie->directorSerie = empty($_POST['directorSerie']) ? null : $_POST['directorSerie']; + $serie->actorSerie = empty($_POST['actorSerie']) ? null : $_POST['actorSerie']; + $serie->guionistaSerie = empty($_POST['guionistaSerie']) ? null : $_POST['guionistaSerie']; + $serie->companiaSerie = empty($_POST['companiaSerie']) ? null : $_POST['companiaSerie']; + $serie->generoSerie = empty($_POST['generoSerie']) ? null : $_POST['generoSerie']; + $serie->anoSerie = empty($_POST['anoSerie']) ? null : $_POST['anoSerie']; + $serie->temporadasSerie = empty($_POST['temporadasSerie']) ? null : $_POST['temporadasSerie']; + $serie->episodiosSerie = empty($_POST['episodiosSerie']) ? null : $_POST['episodiosSerie']; + $serie->ratingAvgSerie = empty($_POST['ratingAvgSerie']) ? null : $_POST['ratingAvgSerie']; + $serie->paisSerie = empty($_POST['paisSerie']) ? null : $_POST['paisSerie']; + $serie->idiomaSerie = empty($_POST['idiomaSerie']) ? null : $_POST['idiomaSerie']; + $serie->posterSerie = empty($_POST['posterSerie']) ? null : $_POST['posterSerie']; + $serie->sinopsisSerie = empty($_POST['sinopsisSerie']) ? null : $_POST['sinopsisSerie']; + + $idSerie = $serie->agregar(); + + if (isset($idSerie['error'])) { + echo json_encode($idSerie); + break; + } + + // Usamos ese idSerie para agregarla como pendiente a la tabla usuariosxseries + $usuarioxSerie = new UsuarioxSerie(); + $usuarioxSerie->idUsuario = $_SESSION['idUsuario']; + $usuarioxSerie->idSerie = $idSerie; + + // Comprobamos si ya estÔ registrada, si no se agrega + $resultado = $usuarioxSerie->existe(); + if(!$resultado){ + $resultado = $usuarioxSerie->agregarPend(); + + echo json_encode([ + 'idSerie' => $idSerie, + 'idUsuarioSerie' => $resultado + ]); + }else{ + echo json_encode($resultado); + } + break; + + case 'buscar': + $usuarioxSerie = new UsuarioxSerie(); + $usuarioxSerie->idUsuario = $_SESSION['idUsuario']; + $lista = $usuarioxSerie->buscar(); + echo json_encode($lista); + break; + + case 'favorita': + $usuarioxSerie = new UsuarioxSerie(); + $usuarioxSerie->idUsuarioSerie = $_POST['idUsuarioSerie']; + $usuarioxSerie->idUsuario = $_SESSION['idUsuario']; + $usuarioxSerie->favSerie = $_POST['favSerie']; + $resultado = $usuarioxSerie -> favorita(); + echo json_encode($resultado); + break; + + case 'comprobar': + $usuarioxSerie = new UsuarioxSerie(); + $usuarioxSerie->idUsuarioSerie = $_POST['idUsuarioSerie']; + $usuarioxSerie->idUsuario = $_SESSION['idUsuario']; + $resultado = $usuarioxSerie -> comprobar(); + echo json_encode($resultado); + break; + + case 'comprobarContenido': + $serie = new Serie(); + $serie->idSerie = $_POST['idSerie']; + + echo json_encode($serie -> comprobar()); + break; + + case 'editarVal': + $usuarioxSerie = new UsuarioxSerie(); + $usuarioxSerie->idUsuarioSerie = $_POST['idUsuarioSerie']; + $usuarioxSerie->idUsuario = $_SESSION['idUsuario']; + $usuarioxSerie->ratingSerie = $_POST['ratingSerie']; + echo json_encode($usuarioxSerie->editarVal()); + break; + + case 'editarFecha': + $usuarioxSerie = new UsuarioxSerie(); + $usuarioxSerie->idUsuarioSerie = $_POST['idUsuarioSerie']; + $usuarioxSerie->idUsuario = $_SESSION['idUsuario']; + $usuarioxSerie->fechaSerie = empty($_POST['fechaSerie']) ? null : $_POST['fechaSerie']; + + echo json_encode($usuarioxSerie->editarFecha()); + break; + + case 'editarEstado': + $usuarioxSerie = new UsuarioxSerie(); + $usuarioxSerie->idUsuarioSerie = $_POST['idUsuarioSerie']; + $usuarioxSerie->idUsuario = $_SESSION['idUsuario']; + $usuarioxSerie->estadoSerie = $_POST['estadoSerie']; + echo json_encode($usuarioxSerie->editarEstado()); + break; + + case 'editarNotas': + $usuarioxSerie = new UsuarioxSerie(); + $usuarioxSerie->idUsuarioSerie = $_POST['idUsuarioSerie']; + $usuarioxSerie->idUsuario = $_SESSION['idUsuario']; + $usuarioxSerie->notasSerie = empty($_POST['notasSerie']) ? null : $_POST['notasSerie']; + + echo json_encode($usuarioxSerie->editarNotas()); + break; + + case 'agregarPendTabla': + $usuarioxSerie = new UsuarioxSerie(); + $usuarioxSerie->idUsuarioSerie = $_POST['idUsuarioSerie']; + $usuarioxSerie->fechaSerie = empty($_POST['fechaSerie']) ? null : $_POST['fechaSerie']; + $usuarioxSerie->estadoSerie = empty($_POST['estadoSerie']) ? null : $_POST['estadoSerie']; + $usuarioxSerie->ratingSerie = empty($_POST['ratingSerie']) ? null : $_POST['ratingSerie']; + $usuarioxSerie->notasSerie = empty($_POST['notasSerie']) ? null : $_POST['notasSerie']; + $usuarioxSerie->favSerie = $_POST['favSerie']; + $usuarioxSerie->idUsuario = $_SESSION['idUsuario']; + + echo json_encode($usuarioxSerie->agregarPendTabla()); + break; + + case 'eliminar': + $usuarioxSerie = new UsuarioxSerie(); + $usuarioxSerie->idUsuarioSerie = $_POST['idUsuarioSerie']; + $usuarioxSerie->idUsuario = $_SESSION['idUsuario']; + echo json_encode($usuarioxSerie->eliminar()); + break; + + case 'temporada': + $api = new ApiSerie(); + $resultado = $api->temporada($_POST['idApiSerie'],$_POST['numeroTemporada']); + + if(isset($resultado['error'])){ + echo json_encode($resultado); + break; + } + + $resultado = $api->transformarDatosTemporada($resultado); + echo json_encode($resultado); + + break; + +} // Fin de switch + + +?> \ No newline at end of file diff --git a/controladores/controladorTemporada.php b/controladores/controladorTemporada.php new file mode 100644 index 0000000..36ffca7 --- /dev/null +++ b/controladores/controladorTemporada.php @@ -0,0 +1,327 @@ +idApi = $_POST['idApiSerie']; + $serie->nombreSerie = empty($_POST['nombreSerie']) ? null : $_POST['nombreSerie']; + $serie->creadorSerie = empty($_POST['creadorSerie']) ? null : $_POST['creadorSerie']; + $serie->directorSerie = empty($_POST['directorSerie']) ? null : $_POST['directorSerie']; + $serie->actorSerie = empty($_POST['actorSerie']) ? null : $_POST['actorSerie']; + $serie->guionistaSerie = empty($_POST['guionistaSerie']) ? null : $_POST['guionistaSerie']; + $serie->companiaSerie = empty($_POST['companiaSerie']) ? null : $_POST['companiaSerie']; + $serie->generoSerie = empty($_POST['generoSerie']) ? null : $_POST['generoSerie']; + $serie->anoSerie = empty($_POST['anoSerie']) ? null : $_POST['anoSerie']; + $serie->temporadasSerie = empty($_POST['temporadasSerie']) ? null : $_POST['temporadasSerie']; + $serie->episodiosSerie = empty($_POST['episodiosSerie']) ? null : $_POST['episodiosSerie']; + $serie->ratingAvgSerie = empty($_POST['ratingAvgSerie']) ? null : $_POST['ratingAvgSerie']; + $serie->paisSerie = empty($_POST['paisSerie']) ? null : $_POST['paisSerie']; + $serie->idiomaSerie = empty($_POST['idiomaSerie']) ? null : $_POST['idiomaSerie']; + $serie->posterSerie = empty($_POST['posterSerie']) ? null : $_POST['posterSerie']; + $serie->sinopsisSerie = empty($_POST['sinopsisSerie']) ? null : $_POST['sinopsisSerie']; + + $idSerie = $serie->agregar(); + + if (isset($idSerie['error'])) { + echo json_encode($idSerie); + break; + } + + // Segundo metemos la temporada en la tabla seriestemporadas usando el $idSerie, y exista o no devolverÔ su idTemporada. + $temporada = new Temporada(); + + $temporada->idApi = $_POST['idApiTemporada']; + $temporada->idSerie = $idSerie; + $temporada->nombreTemporada = empty($_POST['nombreTemporada']) ? null : $_POST['nombreTemporada']; + $temporada->numeroTemporada = empty($_POST['numeroTemporada']) ? null : $_POST['numeroTemporada']; + $temporada->directorTemporada = empty($_POST['directorTemporada']) ? null : $_POST['directorTemporada']; + $temporada->actorTemporada = empty($_POST['actorTemporada']) ? null : $_POST['actorTemporada']; + $temporada->guionistaTemporada = empty($_POST['guionistaTemporada']) ? null : $_POST['guionistaTemporada']; + $temporada->episodiosTemporada = empty($_POST['episodiosTemporada']) ? null : $_POST['episodiosTemporada']; + $temporada->anoTemporada = empty($_POST['anoTemporada']) ? null : $_POST['anoTemporada']; + $temporada->ratingAvgTemporada = empty($_POST['ratingAvgTemporada']) ? null : $_POST['ratingAvgTemporada']; + $temporada->posterTemporada = empty($_POST['posterTemporada']) ? null : $_POST['posterTemporada']; + $temporada->sinopsisTemporada = empty($_POST['sinopsisTemporada']) ? null : $_POST['sinopsisTemporada']; + + $idTemporada = $temporada->agregar(); + + if (isset($idTemporada['error'])) { + echo json_encode($idTemporada); + break; + } + + // Usamos ese idTemporada para agregarla a la tabla usuariosxtemporadas + $usuarioxTemporada = new UsuarioxTemporada(); + $usuarioxTemporada->idUsuario = $_SESSION['idUsuario']; + $usuarioxTemporada->idTemporada = $idTemporada; + + // Comprobamos si ya estÔ registrada, si no se agrega + $resultado = $usuarioxTemporada->existe(); + + if(!$resultado){ + $usuarioxTemporada->fechaTemporada = empty($_POST['fechaTemporada']) ? null : $_POST['fechaTemporada']; + $usuarioxTemporada->ratingTemporada = empty($_POST['ratingTemporada']) ? null : $_POST['ratingTemporada']; + $usuarioxTemporada->notasTemporada = empty($_POST['notasTemporada']) ? null : $_POST['notasTemporada']; + $usuarioxTemporada->favTemporada = $_POST['favTemporada']; + $resultado = $usuarioxTemporada->agregar(); + + echo json_encode([ + 'idTemporada' => $idTemporada, + 'idUsuarioTemporada' => $resultado + ]); + }else{ + echo json_encode($resultado); + } + + break; + + case "buscarApi": + $api = new ApiSerie(); + $resultado = $api->buscar($_POST['nombreTemporada']); + + $series = []; + foreach($resultado as $item){ + $series[] = $api->transformarDatos($item); + } + + echo json_encode($series); + break; + + case "detallesApi": + + $api = new ApiSerie(); + $resultado = $api->detalles($_POST["idApi"]); + + if(isset($resultado['error'])){ + echo json_encode($resultado); + break; + } + + $resultado = $api->transformarDatos($resultado); + + echo json_encode($resultado); + + break; + + case 'detallesApiTemporada': + $api = new ApiSerie(); + $resultado = $api->temporada($_POST['idApiSerie'],$_POST['numeroTemporada']); + + if(isset($resultado['error'])){ + echo json_encode($resultado); + break; + } + + $resultado = $api->transformarDatosTemporada($resultado, $_POST['nombreSerie']); + echo json_encode($resultado); + + break; + + case 'detallesApiEpisodio': + $api = new ApiSerie(); + $resultado = $api->episodio($_POST['idApiSerie'], $_POST['numeroTemporada'], $_POST['numeroEpisodio']); + + if(isset($resultado['error'])){ + echo json_encode($resultado); + break; + } + + $resultado = $api->transformarDatosEpisodio($resultado, $_POST['numeroTemporada'], $_POST['nombreSerie']); + echo json_encode($resultado); + + break; + + case 'listarTodo': + $usuarioxTemporada = new UsuarioxTemporada(); + $usuarioxTemporada->idUsuario = $_SESSION['idUsuario']; + $lista = $usuarioxTemporada->listarTodo(); + echo json_encode($lista); + break; + + case 'listarEstrellas': + $usuarioxTemporada = new UsuarioxTemporada(); + $usuarioxTemporada->idUsuario = $_SESSION['idUsuario']; + $usuarioxTemporada->ratingTemporada = $_POST['i']; + $lista = $usuarioxTemporada->listarEstrellas(); + echo json_encode($lista); + break; + + case 'listarFav': + $usuarioxTemporada = new UsuarioxTemporada(); + $usuarioxTemporada->idUsuario = $_SESSION['idUsuario']; + $lista = $usuarioxTemporada->listarFav(); + echo json_encode($lista); + break; + + case 'listarPendientes': + $usuarioxTemporada = new UsuarioxTemporada(); + $usuarioxTemporada->idUsuario = $_SESSION['idUsuario']; + $lista = $usuarioxTemporada->listarPendientes(); + echo json_encode($lista); + break; + + case 'agregarPend': + + // Primero metemos la serie completa en series, y exista o no devolverÔ su idSerie. + $serie = new Serie(); + $serie->idApi = $_POST['idApiSerie']; + $serie->nombreSerie = empty($_POST['nombreSerie']) ? null : $_POST['nombreSerie']; + $serie->creadorSerie = empty($_POST['creadorSerie']) ? null : $_POST['creadorSerie']; + $serie->directorSerie = empty($_POST['directorSerie']) ? null : $_POST['directorSerie']; + $serie->actorSerie = empty($_POST['actorSerie']) ? null : $_POST['actorSerie']; + $serie->guionistaSerie = empty($_POST['guionistaSerie']) ? null : $_POST['guionistaSerie']; + $serie->companiaSerie = empty($_POST['companiaSerie']) ? null : $_POST['companiaSerie']; + $serie->generoSerie = empty($_POST['generoSerie']) ? null : $_POST['generoSerie']; + $serie->anoSerie = empty($_POST['anoSerie']) ? null : $_POST['anoSerie']; + $serie->temporadasSerie = empty($_POST['temporadasSerie']) ? null : $_POST['temporadasSerie']; + $serie->episodiosSerie = empty($_POST['episodiosSerie']) ? null : $_POST['episodiosSerie']; + $serie->ratingAvgSerie = empty($_POST['ratingAvgSerie']) ? null : $_POST['ratingAvgSerie']; + $serie->paisSerie = empty($_POST['paisSerie']) ? null : $_POST['paisSerie']; + $serie->idiomaSerie = empty($_POST['idiomaSerie']) ? null : $_POST['idiomaSerie']; + $serie->posterSerie = empty($_POST['posterSerie']) ? null : $_POST['posterSerie']; + $serie->sinopsisSerie = empty($_POST['sinopsisSerie']) ? null : $_POST['sinopsisSerie']; + + $idSerie = $serie->agregar(); + + if (isset($idSerie['error'])) { + echo json_encode($idSerie); + break; + } + + + // Segundo metemos la temporada en la tabla seriestemporadas usando el $idSerie, y exista o no devolverÔ su idTemporada. + $temporada = new Temporada(); + + $temporada->idApi = $_POST['idApiTemporada']; + $temporada->idSerie = $idSerie; + $temporada->nombreTemporada = empty($_POST['nombreTemporada']) ? null : $_POST['nombreTemporada']; + $temporada->numeroTemporada = empty($_POST['numeroTemporada']) ? null : $_POST['numeroTemporada']; + $temporada->directorTemporada = empty($_POST['directorTemporada']) ? null : $_POST['directorTemporada']; + $temporada->actorTemporada = empty($_POST['actorTemporada']) ? null : $_POST['actorTemporada']; + $temporada->guionistaTemporada = empty($_POST['guionistaTemporada']) ? null : $_POST['guionistaTemporada']; + $temporada->episodiosTemporada = empty($_POST['episodiosTemporada']) ? null : $_POST['episodiosTemporada']; + $temporada->anoTemporada = empty($_POST['anoTemporada']) ? null : $_POST['anoTemporada']; + $temporada->ratingAvgTemporada = empty($_POST['ratingAvgTemporada']) ? null : $_POST['ratingAvgTemporada']; + $temporada->posterTemporada = empty($_POST['posterTemporada']) ? null : $_POST['posterTemporada']; + $temporada->sinopsisTemporada = empty($_POST['sinopsisTemporada']) ? null : $_POST['sinopsisTemporada']; + + $idTemporada = $temporada->agregar(); + + if (isset($idTemporada['error'])) { + echo json_encode($idTemporada); + break; + } + + + // Usamos ese idTemporada para agregarla a la tabla usuariosxtemporadas + $usuarioxTemporada = new UsuarioxTemporada(); + $usuarioxTemporada->idUsuario = $_SESSION['idUsuario']; + $usuarioxTemporada->idTemporada = $idTemporada; + + // Comprobamos si ya estÔ registrada, si no se agrega + $resultado = $usuarioxTemporada->existe(); + + if(!$resultado){ + $resultado = $usuarioxTemporada->agregarPend(); + + echo json_encode([ + 'idTemporada' => $idTemporada, + 'idUsuarioTemporada' => $resultado + ]); + }else{ + echo json_encode($resultado); + } + + break; + + case 'buscar': + $usuarioxTemporada = new UsuarioxTemporada(); + $usuarioxTemporada->idUsuario = $_SESSION['idUsuario']; + $lista = $usuarioxTemporada->buscar(); + echo json_encode($lista); + break; + + case 'favorita': + $usuarioxTemporada = new UsuarioxTemporada(); + $usuarioxTemporada->idUsuarioTemporada = $_POST['idUsuarioTemporada']; + $usuarioxTemporada->idUsuario = $_SESSION['idUsuario']; + $usuarioxTemporada->favTemporada = $_POST['favTemporada']; + $resultado = $usuarioxTemporada -> favorita(); + echo json_encode($resultado); + break; + + case 'comprobar': + $usuarioxTemporada = new UsuarioxTemporada(); + $usuarioxTemporada->idUsuarioTemporada = $_POST['idUsuarioTemporada']; + $usuarioxTemporada->idUsuario = $_SESSION['idUsuario']; + $resultado = $usuarioxTemporada -> comprobar(); + echo json_encode($resultado); + break; + + case 'comprobarContenido': + $temporada = new Temporada(); + $temporada->idTemporada = $_POST['idTemporada']; + + echo json_encode($temporada -> comprobar()); + break; + + case 'editarVal': + $usuarioxTemporada = new UsuarioxTemporada(); + $usuarioxTemporada->idUsuarioTemporada = $_POST['idUsuarioTemporada']; + $usuarioxTemporada->idUsuario = $_SESSION['idUsuario']; + $usuarioxTemporada->ratingTemporada = $_POST['ratingTemporada']; + echo json_encode($usuarioxTemporada->editarVal()); + break; + + case 'editarFecha': + $usuarioxTemporada = new UsuarioxTemporada(); + $usuarioxTemporada->idUsuarioTemporada = $_POST['idUsuarioTemporada']; + $usuarioxTemporada->idUsuario = $_SESSION['idUsuario']; + $usuarioxTemporada->fechaTemporada = empty($_POST['fechaTemporada']) ? null : $_POST['fechaTemporada']; + + echo json_encode($usuarioxTemporada->editarFecha()); + break; + + case 'editarNotas': + $usuarioxTemporada = new UsuarioxTemporada(); + $usuarioxTemporada->idUsuarioTemporada = $_POST['idUsuarioTemporada']; + $usuarioxTemporada->idUsuario = $_SESSION['idUsuario']; + $usuarioxTemporada->notasTemporada = empty($_POST['notasTemporada']) ? null : $_POST['notasTemporada']; + + echo json_encode($usuarioxTemporada->editarNotas()); + break; + + case 'agregarPendTabla': + $usuarioxTemporada = new UsuarioxTemporada(); + $usuarioxTemporada->idUsuarioTemporada = $_POST['idUsuarioTemporada']; + $usuarioxTemporada->fechaTemporada = empty($_POST['fechaTemporada']) ? null : $_POST['fechaTemporada']; + $usuarioxTemporada->ratingTemporada = empty($_POST['ratingTemporada']) ? null : $_POST['ratingTemporada']; + $usuarioxTemporada->notasTemporada = empty($_POST['notasTemporada']) ? null : $_POST['notasTemporada']; + $usuarioxTemporada->favTemporada = $_POST['favTemporada']; + $usuarioxTemporada->idUsuario = $_SESSION['idUsuario']; + + echo json_encode($usuarioxTemporada->agregarPendTabla()); + break; + + case 'eliminar': + $usuarioxTemporada = new UsuarioxTemporada(); + $usuarioxTemporada->idUsuarioTemporada = $_POST['idUsuarioTemporada']; + $usuarioxTemporada->idUsuario = $_SESSION['idUsuario']; + echo json_encode($usuarioxTemporada->eliminar()); + break; + +} // Fin de switch + + +?> \ No newline at end of file diff --git a/controladores/controladorUsuario.php b/controladores/controladorUsuario.php new file mode 100644 index 0000000..1047e32 --- /dev/null +++ b/controladores/controladorUsuario.php @@ -0,0 +1,127 @@ +identificador = $_POST['identificador']; + $usuario->contrasena = $_POST['contrasena']; + $validacion = $usuario->validar(); + echo json_encode($validacion); + + break; + + case 'insertar': + $usuario = new Usuario(); + $usuario->username = $_POST['username']; + $usuario->email = $_POST['email']; + $usuario->contrasena = $_POST['contrasena']; + + $resultado = $usuario->insertar(); + echo json_encode($resultado); + break; + + case 'editarNombre': + $usuario = new Usuario(); + $usuario->idUsuario = $_POST['idUsuario']; + $usuario->nombreUsuario = $_POST['nombreUsuario']; + + $resultado = $usuario->editarNombre(); + echo json_encode($resultado); + + break; + + case 'editarAvatar': + + $usuario = new Usuario(); + $usuario->idUsuario = $_SESSION['idUsuario']; + + $resultado = $usuario->editarAvatar(); + echo json_encode($resultado); + + break; + + case 'cerrarSesion': + $usuario = new Usuario(); + $respuesta = $usuario->cerrarSesion(); + + echo json_encode($respuesta); + break; + + case 'numeroTotal': + $usuarioxPelicula = new UsuarioxPelicula(); + $usuarioxPelicula->idUsuario = $_SESSION['idUsuario']; + + $usuarioxSerie = new UsuarioxSerie(); + $usuarioxSerie->idUsuario = $_SESSION['idUsuario']; + + $usuarioxJuego = new UsuarioxJuego(); + $usuarioxJuego->idUsuario = $_SESSION['idUsuario']; + + $usuarioxLibro = new UsuarioxLibro(); + $usuarioxLibro->idUsuario = $_SESSION['idUsuario']; + + echo json_encode([ + 'peliculas' => $usuarioxPelicula->listarTodo(), + 'series' => $usuarioxSerie->listarTodo(), + 'juegos' => $usuarioxJuego->listarTodo(), + 'libros' => $usuarioxLibro->listarTodo() + ]); + break; + + case 'revisarCookies': + + if(isset($_COOKIE['autentificadoEnBlog'])){ + $usuario = new Usuario(); + $usuario->cookie = $_COOKIE['autentificadoEnBlog']; + $respuesta = $usuario->compruebaCookie(); + + if(isset($respuesta['sinCoincidencias'])){ + if($_SESSION['validadoPorCookie']){ + $usuario->cerrarSesion(); + } + echo json_encode ($respuesta); + }else{ + // Almacenamos datos del usuario para que javascript los utilice, pero no pasamos datos sensibles + $datosUsuario = [ + 'nombreUsuario' => $usuario->nombreUsuario, + 'avatar' => $usuario->avatar + ]; + echo json_encode($datosUsuario); + } + }else{ + // Si hay un usuario autentificado por cookie pero ya no estÔ la cookie + if(isset($_SESSION['idUsuario'])){ + if(isset($_SESSION['validadoPorCookie']) && $_SESSION['validadoPorCookie']){ + $usuario = new Usuario(); + $usuario->cerrarSesion(); + } + } + } + + if(!isset($_COOKIE['autentificadoEnBlog'])){ + $respuesta=[ + 'estado' => 'No hay cookies de autentificación en el navegador' + ]; + echo json_encode($respuesta); + } + + break; + +} // Fin de switch + + + +?> \ No newline at end of file diff --git a/images/avatars/1.jpg b/images/avatars/1.jpg new file mode 100644 index 0000000..2c611d1 Binary files /dev/null and b/images/avatars/1.jpg differ diff --git a/images/bg.jpg b/images/bg.jpg new file mode 100644 index 0000000..d27f914 Binary files /dev/null and b/images/bg.jpg differ diff --git a/images/favicon.svg b/images/favicon.svg new file mode 100644 index 0000000..fb6d942 --- /dev/null +++ b/images/favicon.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/images/libros/15155833.jpg b/images/libros/15155833.jpg new file mode 100644 index 0000000..e627a7d Binary files /dev/null and b/images/libros/15155833.jpg differ diff --git a/images/noAvatar.jpg b/images/noAvatar.jpg new file mode 100644 index 0000000..efff31a Binary files /dev/null and b/images/noAvatar.jpg differ diff --git a/images/noPoster.jpeg b/images/noPoster.jpeg new file mode 100644 index 0000000..98957b6 Binary files /dev/null and b/images/noPoster.jpeg differ diff --git a/images/overlay.png b/images/overlay.png new file mode 100644 index 0000000..3cd22cc Binary files /dev/null and b/images/overlay.png differ diff --git a/images/pic01.jpg b/images/pic01.jpg new file mode 100644 index 0000000..2c4200c Binary files /dev/null and b/images/pic01.jpg differ diff --git a/images/pic02.jpg b/images/pic02.jpg new file mode 100644 index 0000000..34ac5e8 Binary files /dev/null and b/images/pic02.jpg differ diff --git a/images/pic03.jpg b/images/pic03.jpg new file mode 100644 index 0000000..db24317 Binary files /dev/null and b/images/pic03.jpg differ diff --git a/includes/conexionBD.php b/includes/conexionBD.php new file mode 100644 index 0000000..973b91e --- /dev/null +++ b/includes/conexionBD.php @@ -0,0 +1,26 @@ +load(); + +function conexionBD (){ + try{ + $servidor = 'mysql:host='.$_ENV['bDatosServer'].';dbname='.$_ENV['bDatos']; + $user=$_ENV['bDatosUser']; + $password=$_ENV['bDatosPass']; + $options=array( + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8" + ); + $pdo = new PDO($servidor, $user, $password, $options); + } + catch(PDOException $e){ + $resultado = ['error' => 'Error Temporal: No se puede conectar con la base de datos.']; + return $resultado; + } + + return $pdo; +} + +?> \ No newline at end of file diff --git a/includes/limpiaFormulario.php b/includes/limpiaFormulario.php new file mode 100644 index 0000000..8c4f888 --- /dev/null +++ b/includes/limpiaFormulario.php @@ -0,0 +1,11 @@ + $valor){ + $respuestas[$clave] = htmlspecialchars($valor, ENT_QUOTES); + }; + + return $respuestas; +} + +?> \ No newline at end of file diff --git a/index.php b/index.php new file mode 100644 index 0000000..83aa0cb --- /dev/null +++ b/index.php @@ -0,0 +1,475 @@ + + + + + + MyDiary + + + + + + + + + + + +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/js/configContenido.js b/js/configContenido.js new file mode 100644 index 0000000..8e3b9a6 --- /dev/null +++ b/js/configContenido.js @@ -0,0 +1,2059 @@ +const contenidoConfig = { + + pelicula: { + nombreContenido: 'Película', + nombrePluralContenido: 'Películas', + genero: "a", + + controlador: 'controladores/controladorPelicula.php', + + idUsuarioContenido: 'idUsuarioPelicula', + idContenido: "idPelicula", + nombre: "nombrePelicula", + ano: "anoPelicula", + poster: "posterPelicula", + rating: "ratingPelicula", + fav: "favPelicula", + pendiente: "pendientePelicula", + fecha: "fechaPelicula", + notas: "notasPelicula", + + noPoster: "https:\/\/image.tmdb.org\/t\/p\/w500", + + accionFecha: "visualización", + pluralFecha: "", + + tabla: "tablaPelicula", + color: "colorPelicula", + colorBoton: "colorPeliculaBoton", + + icono: "bi-film", + + camposBD: { + idApi: "idApi", + nombrePelicula: "nombrePelicula", + directorPelicula: "directorPelicula", + actorPelicula: "actorPelicula", + guionistaPelicula: "guionistaPelicula", + generoPelicula: "generoPelicula", + anoPelicula: "anoPelicula", + companiaPelicula: "companiaPelicula", + duracionPelicula: "duracionPelicula", + ratingAvgPelicula: "ratingAvgPelicula", + paisPelicula: "paisPelicula", + idiomaPelicula: "idiomaPelicula", + posterPelicula: "posterPelicula", + sinopsisPelicula: "sinopsisPelicula" + }, + + campos: { + idApi: "idApi", + nombre: "nombrePelicula", + director: "directorPelicula", + actor: "actorPelicula", + guionista: "guionistaPelicula", + genero: "generoPelicula", + ano: "anoPelicula", + compania: "companiaPelicula", + duracion: "duracionPelicula", + ratingAvg: "ratingAvgPelicula", + pais: "paisPelicula", + idioma: "idiomaPelicula", + poster: "posterPelicula", + sinopsis: "sinopsisPelicula" + }, + + formAgregar: [ + { + type: "date", + nombre: "fechaPelicula", + label: "Fecha de visualización", + id: "fechaFormAgregar", + ancho: 12 + } + ], + + formFecha: [ + { + type: "date", + nombre: "fechaPelicula", + label: "", + id: "fechaFormEditar", + ancho: 12 + } + ], + + detalles: [ + { + campo: "directorPelicula", + titulo: "Director", + icono: "bi-camera-reels", + zona: "poster" + }, + { + campo: "actorPelicula", + titulo: "Reparto", + icono: "bi-people", + zona: "poster" + }, + { + campo: "guionistaPelicula", + titulo: "Guion", + icono: "bi-pencil", + zona: "poster" + }, + { + campo: "generoPelicula", + titulo: "Géneros", + icono: "bi-tags", + zona: "poster" + }, + { + campo: "companiaPelicula", + titulo: "Productoras", + icono: "bi-building", + zona: "poster" + }, + { + campo: "anoPelicula", + titulo: "Año", + zona: "datos" + }, + { + campo: "duracionPelicula", + titulo: "Duración", + unidad: " min", + zona: "datos" + }, + { + campo: "ratingAvgPelicula", + titulo: "Valoración", + zona: "datos" + }, + { + campo: "paisPelicula", + titulo: "País", + icono: "bi-globe", + zona: "abajo" + }, + { + campo: "idiomaPelicula", + titulo: "Idiomas", + icono: "bi-translate", + zona: "abajo" + }, + { + campo: "sinopsisPelicula", + titulo: "Sinopsis", + icono: "bi-text-paragraph", + zona: "sinopsis" + } + ], + + detallesInfo: [ + { + campo: "directorPelicula", + titulo: "Director", + icono: "bi-camera-reels", + zona: "poster" + }, + { + campo: "actorPelicula", + titulo: "Reparto", + icono: "bi-people", + zona: "poster" + }, + { + campo: "guionistaPelicula", + titulo: "Guion", + icono: "bi-pencil", + zona: "poster" + }, + { + campo: "generoPelicula", + titulo: "Géneros", + icono: "bi-tags", + zona: "poster" + }, + { + campo: "companiaPelicula", + titulo: "Productoras", + icono: "bi-building", + zona: "poster" + }, + { + campo: "anoPelicula", + titulo: "Año", + zona: "datos" + }, + { + campo: "duracionPelicula", + titulo: "Duración", + unidad: " min", + zona: "datos" + }, + { + campo: "ratingAvgPelicula", + titulo: "Valoración", + zona: "datos" + }, + { + campo: "paisPelicula", + titulo: "País", + icono: "bi-globe", + zona: "poster" + }, + { + campo: "idiomaPelicula", + titulo: "Idiomas", + icono: "bi-translate", + zona: "poster" + }, + { + campo: "sinopsisPelicula", + titulo: "Sinopsis", + icono: "bi-text-paragraph", + zona: "sinopsis" + } + ], + + historial: { + agregar: "agregarPelicula", + listar: "listarPelicula" + }, + + filas: 10, + + columns:[ + {field:"idUsuarioPelicula", visible:false, download: false}, + {field:"idPelicula", visible:false, download: false}, + {field:"idApi", visible:false, download: false}, + {field:"pendientePelicula", visible:false, download: false}, + {field:"posterPelicula", visible:false, download: false}, + {field:"ratingAvgPelicula", visible:false, download: false}, + {field:"notasPelicula", visible:false, download: false}, + {field:"favPelicula", visible:false, download: false}, + {field:"nombrePelicula", title:"Película", widthGrow:5, variableHeight: true, cssClass: "expandirCelda nombreTabla", headerTooltip: "Nombre de la película", formatter: cell => celdaNombre(cell)}, + {field:"directorPelicula", title:"Director", widthGrow:3, cssClass: "expandirCelda", headerTooltip: "Director de la película"}, + {field:"anoPelicula", title:"Año", width:70, headerTooltip: "Año de salida de la película"}, + {field:"fechaPelicula", title:"Visualización", width:120, headerTooltip: "Fecha de visualización", formatter: cell => cambiarFecha(cell.getValue())}, + {field:"ratingPelicula", title:"Valoración", width:110, headerTooltip: "Valoración personal de la película", formatter: cell => transformarRatingTabla(cell.getValue())}, + {field:"iconos", title:"", width:60, download:false, formatter: cell => celdaIconos(cell)} + ] + }, // Fin pelicula + + serie: { + nombreContenido: 'Serie', + nombrePluralContenido: 'Series', + genero: "a", + + controlador: 'controladores/controladorSerie.php', + + idUsuarioContenido: 'idUsuarioSerie', + idContenido: "idSerie", + nombre: "nombreSerie", + ano: "anoSerie", + poster: "posterSerie", + rating: "ratingSerie", + fav: "favSerie", + pendiente: "pendienteSerie", + fecha: "fechaSerie", + estado: "estadoSerie", + notas: "notasSerie", + + noPoster: "https:\/\/image.tmdb.org\/t\/p\/w500", + + accionFecha: "visualización", + pluralFecha: "", + + tabla: "tablaSerie", + color: "colorSerie", + colorBoton: "colorSerieBoton", + + icono: "bi-tv", + + camposBD: { + idApi: "idApi", + nombreSerie: "nombreSerie", + creadorSerie: "creadorSerie", + directorSerie: "directorSerie", + actorSerie: "actorSerie", + guionistaSerie: "guionistaSerie", + companiaSerie: "companiaSerie", + generoSerie: "generoSerie", + anoSerie: "anoSerie", + temporadasSerie: "temporadasSerie", + episodiosSerie: "episodiosSerie", + ratingAvgSerie: "ratingAvgSerie", + paisSerie: "paisSerie", + idiomaSerie: "idiomaSerie", + posterSerie: "posterSerie", + sinopsisSerie: "sinopsisSerie", + }, + + campos: { + idApi: "idApi", + nombre: "nombreSerie", + creador: "creadorSerie", + director: "directorSerie", + actor: "actorSerie", + guionista: "guionistaSerie", + compania: "companiaSerie", + genero: "generoSerie", + ano: "anoSerie", + temporadas: "temporadasSerie", + episodios: "episodiosSerie", + ratingAvg: "ratingAvgSerie", + pais: "paisSerie", + idioma: "idiomaSerie", + poster: "posterSerie", + sinopsis: "sinopsisSerie", + }, + + formAgregar: [ + { + type: "select", + nombre: "estadoSerie", + label: "Estado", + id: "estadoFormAgregar", + ancho: 6, + }, + { + type: "date", + nombre: "fechaSerie", + label: "Fecha de visualización", + id: "fechaFormAgregar", + ancho: 6 + } + ], + + formAgregarSerie: [ + { + type: "select", + nombre: "estadoSerie", + label: "Estado", + id: "estadoFormAgregar", + ancho: 6, + }, + { + type: "date", + nombre: "fechaSerie", + label: "Fecha de visualización", + id: "fechaFormAgregar", + ancho: 6 + } + ], + + formAgregarTemporada: [ + { + type: "date", + nombre: "fechaTemporada", + label: "Fecha de visualización", + id: "fechaFormAgregar", + ancho: 12 + } + ], + + formAgregarEpisodio: [ + { + type: "date", + nombre: "fechaEpisodio", + label: "Fecha de visualización", + id: "fechaFormAgregar", + ancho: 12 + } + ], + + formFecha: [ + { + type: "date", + nombre: "fechaSerie", + label: "", + id: "fechaFormEditar", + ancho: 12 + } + ], + + editarEstado: true, + + detalles: [ + { + campo: "creadorSerie", + titulo: "Creador", + icono: "bi-camera-reels", + zona: "poster" + }, + { + campo: "directorSerie", + titulo: "Director", + icono: "bi-camera-reels", + zona: "poster" + }, + { + campo: "actorSerie", + titulo: "Reparto", + icono: "bi-people", + zona: "poster" + }, + { + campo: "guionistaSerie", + titulo: "Guion", + icono: "bi-pencil", + zona: "poster" + }, + { + campo: "generoSerie", + titulo: "Géneros", + icono: "bi-tags", + zona: "poster" + }, + { + campo: "companiaSerie", + titulo: "Productoras", + icono: "bi-building", + zona: "poster" + }, + { + campo: "anoSerie", + titulo: "Año", + zona: "datos" + }, + { + campo: "temporadasSerie", + titulo: "Temporadas", + zona: "datos" + }, + { + campo: "episodiosSerie", + titulo: "Episodios", + zona: "datos" + }, + { + campo: "ratingAvgSerie", + titulo: "Valoración", + zona: "datos" + }, + { + campo: "paisSerie", + titulo: "País", + icono: "bi-globe", + zona: "abajo" + }, + { + campo: "idiomaSerie", + titulo: "Idiomas", + icono: "bi-translate", + zona: "abajo" + }, + { + campo: "sinopsisSerie", + titulo: "Sinopsis", + icono: "bi-text-paragraph", + zona: "sinopsis" + } + ], + + detallesInfo: [ + { + campo: "creadorSerie", + titulo: "Creador", + icono: "bi-camera-reels", + zona: "poster" + }, + { + campo: "directorSerie", + titulo: "Director", + icono: "bi-camera-reels", + zona: "poster" + }, + { + campo: "actorSerie", + titulo: "Reparto", + icono: "bi-people", + zona: "poster" + }, + { + campo: "guionistaSerie", + titulo: "Guion", + icono: "bi-pencil", + zona: "poster" + }, + { + campo: "generoSerie", + titulo: "Géneros", + icono: "bi-tags", + zona: "poster" + }, + { + campo: "companiaSerie", + titulo: "Productoras", + icono: "bi-building", + zona: "poster" + }, + { + campo: "anoSerie", + titulo: "Año", + zona: "datos" + }, + { + campo: "temporadasSerie", + titulo: "Temporadas", + zona: "datos" + }, + { + campo: "episodiosSerie", + titulo: "Episodios", + zona: "datos" + }, + { + campo: "ratingAvgSerie", + titulo: "Valoración", + zona: "datos" + }, + { + campo: "paisSerie", + titulo: "País", + icono: "bi-globe", + zona: "poster" + }, + { + campo: "idiomaSerie", + titulo: "Idiomas", + icono: "bi-translate", + zona: "poster" + }, + { + campo: "sinopsisSerie", + titulo: "Sinopsis", + icono: "bi-text-paragraph", + zona: "sinopsis" + } + ], + + detallesSerie: [ + { + campo: "creadorSerie", + titulo: "Creador", + icono: "bi-camera-reels", + zona: "poster" + }, + { + campo: "directorSerie", + titulo: "Director", + icono: "bi-camera-reels", + zona: "poster" + }, + { + campo: "actorSerie", + titulo: "Reparto", + icono: "bi-people", + zona: "poster" + }, + { + campo: "guionistaSerie", + titulo: "Guion", + icono: "bi-pencil", + zona: "poster" + }, + { + campo: "generoSerie", + titulo: "Géneros", + icono: "bi-tags", + zona: "poster" + }, + { + campo: "companiaSerie", + titulo: "Productoras", + icono: "bi-building", + zona: "poster" + }, + { + campo: "anoSerie", + titulo: "Año", + zona: "datos" + }, + { + campo: "temporadasSerie", + titulo: "Temporadas", + zona: "datos" + }, + { + campo: "episodiosSerie", + titulo: "Episodios", + zona: "datos" + }, + { + campo: "ratingAvgSerie", + titulo: "Valoración", + zona: "datos" + }, + { + campo: "paisSerie", + titulo: "País", + icono: "bi-globe", + zona: "abajo" + }, + { + campo: "idiomaSerie", + titulo: "Idiomas", + icono: "bi-translate", + zona: "abajo" + }, + { + campo: "sinopsisSerie", + titulo: "Sinopsis", + icono: "bi-text-paragraph", + zona: "sinopsis" + } + ], + + detallesTemporada: [ + { + campo: "directorTemporada", + titulo: "Director", + icono: "bi-camera-reels", + zona: "poster" + }, + { + campo: "actorTemporada", + titulo: "Reparto", + icono: "bi-people", + zona: "poster" + }, + { + campo: "guionistaTemporada", + titulo: "Guion", + icono: "bi-pencil", + zona: "poster" + }, + { + campo: "anoTemporada", + titulo: "Año", + zona: "datos" + }, + { + campo: "numeroTemporada", + titulo: "Temporada", + zona: "datos" + }, + { + campo: "episodiosTemporada", + titulo: "Episodios", + zona: "datos" + }, + { + campo: "ratingAvgTemporada", + titulo: "Valoración", + zona: "datos" + }, + { + campo: "sinopsisTemporada", + titulo: "Sinopsis", + icono: "bi-text-paragraph", + zona: "sinopsis" + } + ], + + detallesEpisodio: [ + { + campo: "directorEpisodio", + titulo: "Director", + icono: "bi-camera-reels", + zona: "poster" + }, + { + campo: "actorEpisodio", + titulo: "Reparto", + icono: "bi-people", + zona: "poster" + }, + { + campo: "guionistaEpisodio", + titulo: "Guion", + icono: "bi-pencil", + zona: "poster" + }, + { + campo: "anoEpisodio", + titulo: "Año", + zona: "datos" + }, + { + campo: "numeroEpisodio", + titulo: "Episodio", + zona: "datos" + }, + { + campo: "duracionEpisodio", + titulo: "Duracion", + zona: "datos" + }, + { + campo: "ratingAvgEpisodio", + titulo: "Valoración", + zona: "datos" + }, + { + campo: "sinopsisEpisodio", + titulo: "Sinopsis", + icono: "bi-text-paragraph", + zona: "sinopsis" + } + ], + + historial: { + agregar: "agregarSerie", + listar: "listarSerie" + }, + + filas: 10, + + columns:[ + {field:"idUsuarioSerie", visible:false, download: false}, + {field:"idSerie", visible:false, download: false}, + {field:"idApi", visible:false, download: false}, + {field:"pendienteSerie", visible:false, download: false}, + {field:"posterSerie", visible:false, download: false}, + {field:"ratingAvgSerie", visible:false, download: false}, + {field:"notasSerie", visible:false, download: false}, + {field:"favSerie", visible:false, download: false}, + {field:"nombreSerie", title:"Serie", widthGrow:5, variableHeight: true, cssClass: "expandirCelda nombreTabla", headerTooltip: "Nombre de la serie", formatter: cell => celdaNombre(cell)}, + {field:"creadorSerie", title:"Creador", widthGrow:3, cssClass: "expandirCelda", headerTooltip: "Creador de la serie"}, + {field:"anoSerie", title:"Año", width:70, headerTooltip: "Año de salida de la serie"}, + {field:"fechaSerie", title:"Visualización", width:120, headerTooltip: "Fecha de visualización", formatter: cell => cambiarFecha(cell.getValue())}, + {field:"estadoSerie", title:"Estado", width:100, headerTooltip: "Estado personal de la serie"}, + {field:"ratingSerie", title:"Valoración", width:110, headerTooltip: "Valoración personal de la serie", formatter: cell => transformarRatingTabla(cell.getValue())}, + {field:"iconos", title:"", width:60, download:false, formatter: cell => celdaIconos(cell)} + ] + }, // Fin serie + + temporada: { + nombreContenido: 'Temporada', + nombrePluralContenido: 'Temporadas', + genero: "a", + + controlador: 'controladores/controladorTemporada.php', + + idUsuarioContenido: 'idUsuarioTemporada', + idContenido: "idTemporada", + nombre: "nombreTemporada", + ano: "anoTemporada", + poster: "posterTemporada", + rating: "ratingTemporada", + fav: "favTemporada", + pendiente: "pendienteTemporada", + fecha: "fechaTemporada", + notas: "notasTemporada", + + noPoster: "https:\/\/image.tmdb.org\/t\/p\/w500", + + accionFecha: "visualización", + pluralFecha: "", + + tabla: "tablaTemporada", + color: "colorSerie", + colorBoton: "colorSerieBoton", + + icono: "bi-collection-play", + + camposBD: { + idApi: "idApi", + idSerie: "idSerie", + nombreTemporada: "nombreTemporada", + numeroTemporada: "numeroTemporada", + directorTemporada: "directorTemporada", + actorSerie: "actorSerie", + guionistaTemporada: "guionistaTemporada", + anoTemporada: "anoTemporada", + episodiosTemporada: "episodiosTemporada", + ratingAvgTemporada: "ratingAvgTemporada", + posterTemporada: "posterTemporada", + sinopsisTemporada: "sinopsisTemporada", + }, + + campos: { + idApi: "idApi", + idSerie: "idSerie", + nombre: "nombreTemporada", + numero: "numeroTemporada", + director: "directorTemporada", + actor: "actorSerie", + guionista: "guionistaTemporada", + ano: "anoTemporada", + episodios: "episodiosTemporada", + ratingAvg: "ratingAvgTemporada", + poster: "posterTemporada", + sinopsis: "sinopsisTemporada", + }, + + formAgregar: [ + { + type: "date", + nombre: "fechaTemporada", + label: "Fecha de visualización", + id: "fechaFormAgregar", + ancho: 12 + } + ], + + formAgregarSerie: [ + { + type: "select", + nombre: "estadoSerie", + label: "Estado", + id: "estadoFormAgregar", + ancho: 6, + }, + { + type: "date", + nombre: "fechaSerie", + label: "Fecha de visualización", + id: "fechaFormAgregar", + ancho: 6 + } + ], + + formAgregarTemporada: [ + { + type: "date", + nombre: "fechaTemporada", + label: "Fecha de visualización", + id: "fechaFormAgregar", + ancho: 12 + } + ], + + formAgregarEpisodio: [ + { + type: "date", + nombre: "fechaEpisodio", + label: "Fecha de visualización", + id: "fechaFormAgregar", + ancho: 12 + } + ], + + formFecha: [ + { + type: "date", + nombre: "fechaTemporada", + label: "", + id: "fechaFormEditar", + ancho: 12 + } + ], + + detalles: [ + { + campo: "directorTemporada", + titulo: "Director", + icono: "bi-camera-reels", + zona: "poster" + }, + { + campo: "actorTemporada", + titulo: "Reparto", + icono: "bi-people", + zona: "poster" + }, + { + campo: "guionistaTemporada", + titulo: "Guion", + icono: "bi-pencil", + zona: "poster" + }, + { + campo: "anoTemporada", + titulo: "Año", + zona: "datos" + }, + { + campo: "numeroTemporada", + titulo: "Temporada", + zona: "datos" + }, + { + campo: "episodiosTemporada", + titulo: "Episodios", + zona: "datos" + }, + { + campo: "ratingAvgTemporada", + titulo: "Valoración", + zona: "datos" + }, + { + campo: "sinopsisTemporada", + titulo: "Sinopsis", + icono: "bi-text-paragraph", + zona: "sinopsis" + } + ], + + detallesInfo: [ + { + campo: "directorTemporada", + titulo: "Director", + icono: "bi-camera-reels", + zona: "poster" + }, + { + campo: "actorTemporada", + titulo: "Reparto", + icono: "bi-people", + zona: "poster" + }, + { + campo: "guionistaTemporada", + titulo: "Guion", + icono: "bi-pencil", + zona: "poster" + }, + { + campo: "anoTemporada", + titulo: "Año", + zona: "datos" + }, + { + campo: "numeroTemporada", + titulo: "Temporada", + zona: "datos" + }, + { + campo: "episodiosTemporada", + titulo: "Episodios", + zona: "datos" + }, + { + campo: "ratingAvgTemporada", + titulo: "Valoración", + zona: "datos" + }, + { + campo: "sinopsisTemporada", + titulo: "Sinopsis", + icono: "bi-text-paragraph", + zona: "sinopsis" + } + ], + + detallesSerie: [ + { + campo: "creadorSerie", + titulo: "Creador", + icono: "bi-camera-reels", + zona: "poster" + }, + { + campo: "directorSerie", + titulo: "Director", + icono: "bi-camera-reels", + zona: "poster" + }, + { + campo: "actorSerie", + titulo: "Reparto", + icono: "bi-people", + zona: "poster" + }, + { + campo: "guionistaSerie", + titulo: "Guion", + icono: "bi-pencil", + zona: "poster" + }, + { + campo: "generoSerie", + titulo: "Géneros", + icono: "bi-tags", + zona: "poster" + }, + { + campo: "companiaSerie", + titulo: "Productoras", + icono: "bi-building", + zona: "poster" + }, + { + campo: "anoSerie", + titulo: "Año", + zona: "datos" + }, + { + campo: "temporadasSerie", + titulo: "Temporadas", + zona: "datos" + }, + { + campo: "episodiosSerie", + titulo: "Episodios", + zona: "datos" + }, + { + campo: "ratingAvgSerie", + titulo: "Valoración", + zona: "datos" + }, + { + campo: "paisSerie", + titulo: "País", + icono: "bi-globe", + zona: "abajo" + }, + { + campo: "idiomaSerie", + titulo: "Idiomas", + icono: "bi-translate", + zona: "abajo" + }, + { + campo: "sinopsisSerie", + titulo: "Sinopsis", + icono: "bi-text-paragraph", + zona: "sinopsis" + } + ], + + detallesTemporada: [ + { + campo: "directorTemporada", + titulo: "Director", + icono: "bi-camera-reels", + zona: "poster" + }, + { + campo: "actorTemporada", + titulo: "Reparto", + icono: "bi-people", + zona: "poster" + }, + { + campo: "guionistaTemporada", + titulo: "Guion", + icono: "bi-pencil", + zona: "poster" + }, + { + campo: "anoTemporada", + titulo: "Año", + zona: "datos" + }, + { + campo: "numeroTemporada", + titulo: "Temporada", + zona: "datos" + }, + { + campo: "episodiosTemporada", + titulo: "Episodios", + zona: "datos" + }, + { + campo: "ratingAvgTemporada", + titulo: "Valoración", + zona: "datos" + }, + { + campo: "sinopsisTemporada", + titulo: "Sinopsis", + icono: "bi-text-paragraph", + zona: "sinopsis" + } + ], + + detallesEpisodio: [ + { + campo: "directorEpisodio", + titulo: "Director", + icono: "bi-camera-reels", + zona: "poster" + }, + { + campo: "actorEpisodio", + titulo: "Reparto", + icono: "bi-people", + zona: "poster" + }, + { + campo: "guionistaEpisodio", + titulo: "Guion", + icono: "bi-pencil", + zona: "poster" + }, + { + campo: "anoEpisodio", + titulo: "Año", + zona: "datos" + }, + { + campo: "numeroEpisodio", + titulo: "Episodio", + zona: "datos" + }, + { + campo: "duracionEpisodio", + titulo: "Duracion", + zona: "datos" + }, + { + campo: "ratingAvgEpisodio", + titulo: "Valoración", + zona: "datos" + }, + { + campo: "sinopsisEpisodio", + titulo: "Sinopsis", + icono: "bi-text-paragraph", + zona: "sinopsis" + } + ], + + historial: { + agregar: "agregarTemporada", + listar: "listarSerie" + }, + + filas: 10, + + columns:[ + {field:"idUsuarioTemporada", visible:false, download: false}, + {field:"idTemporada", visible:false, download: false}, + {field:"idSerie", visible:false, download: false}, + {field:"idApi", visible:false, download: false}, + {field:"pendienteTemporada", visible:false, download: false}, + {field:"posterTemporada", visible:false, download: false}, + {field:"ratingAvgTemporada", visible:false, download: false}, + {field:"notasTemporada", visible:false, download: false}, + {field:"favTemporada", visible:false, download: false}, + {field:"nombreTemporada", title:"Temporada", widthGrow:5, variableHeight: true, cssClass: "expandirCelda nombreTabla", headerTooltip: "Nombre de la temporada", formatter: cell => celdaNombre(cell)}, + {field:"directorTemporada", title:"Director", widthGrow:3, cssClass: "expandirCelda", headerTooltip: "Director de la temporada"}, + {field:"anoTemporada", title:"Año", width:70, headerTooltip: "Año de salida de la temporada"}, + {field:"fechaTemporada", title:"Visualización", width:120, headerTooltip: "Fecha de visualización", formatter: cell => cambiarFecha(cell.getValue())}, + {field:"ratingTemporada", title:"Valoración", width:110, headerTooltip: "Valoración personal de la temporada", formatter: cell => transformarRatingTabla(cell.getValue())}, + {field:"iconos", title:"", width:60, download:false, formatter: cell => celdaIconos(cell)} + ] + }, // Fin temporada + + episodio: { + nombreContenido: 'Episodio', + nombrePluralContenido: 'Episodios', + genero: "o", + + controlador: 'controladores/controladorEpisodio.php', + + idUsuarioContenido: 'idUsuarioEpisodio', + idContenido: "idEpisodio", + nombre: "nombreEpisodio", + ano: "anoEpisodio", + poster: "posterEpisodio", + rating: "ratingEpisodio", + fav: "favEpisodio", + pendiente: "pendienteEpisodio", + fecha: "fechaEpisodio", + notas: "notasEpisodio", + + noPoster: "https:\/\/image.tmdb.org\/t\/p\/w500", + + accionFecha: "visualización", + pluralFecha: "", + + tabla: "tablaEpisodio", + color: "colorSerie", + colorBoton: "colorSerieBoton", + + icono: "bi-play-btn", + + camposBD: { + idApi: "idApi", + idTemporada: "idTemporada", + nombreEpisodio: "nombreEpisodio", + numeroEpisodio: "numeroEpisodio", + directorEpisodio: "directorEpisodio", + actorEpisodio: "actorEpisodio", + guionistaEpisodio: "guionistaEpisodio", + anoEpisodio: "anoEpisodio", + duracionEpisodio: "duracionEpisodio", + ratingAvgEpisodio: "ratingAvgEpisodio", + posterEpisodio: "posterEpisodio", + sinopsisEpisodio: "sinopsisEpisodio", + }, + + campos: { + idApi: "idApi", + idTemporada: "idTemporada", + nombre: "nombreEpisodio", + numero: "numeroEpisodio", + director: "directorEpisodio", + actor: "actorEpisodio", + guionista: "guionistaEpisodio", + ano: "anoEpisodio", + duracion: "duracionEpisodio", + ratingAvg: "ratingAvgEpisodio", + poster: "posterEpisodio", + sinopsis: "sinopsisEpisodio", + }, + + formAgregar: [ + { + type: "date", + nombre: "fechaEpisodio", + label: "Fecha de visualización", + id: "fechaFormAgregar", + ancho: 12 + } + ], + + formAgregarSerie: [ + { + type: "select", + nombre: "estadoSerie", + label: "Estado", + id: "estadoFormAgregar", + ancho: 6, + }, + { + type: "date", + nombre: "fechaSerie", + label: "Fecha de visualización", + id: "fechaFormAgregar", + ancho: 6 + } + ], + + formAgregarTemporada: [ + { + type: "date", + nombre: "fechaTemporada", + label: "Fecha de visualización", + id: "fechaFormAgregar", + ancho: 12 + } + ], + + formAgregarEpisodio: [ + { + type: "date", + nombre: "fechaEpisodio", + label: "Fecha de visualización", + id: "fechaFormAgregar", + ancho: 12 + } + ], + + formFecha: [ + { + type: "date", + nombre: "fechaEpisodio", + label: "", + id: "fechaFormEditar", + ancho: 12 + } + ], + + detalles: [ + { + campo: "directorEpisodio", + titulo: "Director", + icono: "bi-camera-reels", + zona: "poster" + }, + { + campo: "actorEpisodio", + titulo: "Reparto", + icono: "bi-people", + zona: "poster" + }, + { + campo: "guionistaEpisodio", + titulo: "Guion", + icono: "bi-pencil", + zona: "poster" + }, + { + campo: "anoEpisodio", + titulo: "Año", + zona: "datos" + }, + { + campo: "numeroEpisodio", + titulo: "Episodio", + zona: "datos" + }, + { + campo: "duracionEpisodio", + titulo: "Duracion", + zona: "datos" + }, + { + campo: "ratingAvgEpisodio", + titulo: "Valoración", + zona: "datos" + }, + { + campo: "sinopsisEpisodio", + titulo: "Sinopsis", + icono: "bi-text-paragraph", + zona: "sinopsis" + } + ], + + detallesInfo: [ + { + campo: "directorEpisodio", + titulo: "Director", + icono: "bi-camera-reels", + zona: "poster" + }, + { + campo: "actorEpisodio", + titulo: "Reparto", + icono: "bi-people", + zona: "poster" + }, + { + campo: "guionistaEpisodio", + titulo: "Guion", + icono: "bi-pencil", + zona: "poster" + }, + { + campo: "anoEpisodio", + titulo: "Año", + zona: "datos" + }, + { + campo: "numeroEpisodio", + titulo: "Episodio", + zona: "datos" + }, + { + campo: "duracionEpisodio", + titulo: "Duracion", + zona: "datos" + }, + { + campo: "ratingAvgEpisodio", + titulo: "Valoración", + zona: "datos" + }, + { + campo: "sinopsisEpisodio", + titulo: "Sinopsis", + icono: "bi-text-paragraph", + zona: "sinopsis" + } + ], + + detallesSerie: [ + { + campo: "creadorSerie", + titulo: "Creador", + icono: "bi-camera-reels", + zona: "poster" + }, + { + campo: "directorSerie", + titulo: "Director", + icono: "bi-camera-reels", + zona: "poster" + }, + { + campo: "actorSerie", + titulo: "Reparto", + icono: "bi-people", + zona: "poster" + }, + { + campo: "guionistaSerie", + titulo: "Guion", + icono: "bi-pencil", + zona: "poster" + }, + { + campo: "generoSerie", + titulo: "Géneros", + icono: "bi-tags", + zona: "poster" + }, + { + campo: "companiaSerie", + titulo: "Productoras", + icono: "bi-building", + zona: "poster" + }, + { + campo: "anoSerie", + titulo: "Año", + zona: "datos" + }, + { + campo: "temporadasSerie", + titulo: "Temporadas", + zona: "datos" + }, + { + campo: "episodiosSerie", + titulo: "Episodios", + zona: "datos" + }, + { + campo: "ratingAvgSerie", + titulo: "Valoración", + zona: "datos" + }, + { + campo: "paisSerie", + titulo: "País", + icono: "bi-globe", + zona: "abajo" + }, + { + campo: "idiomaSerie", + titulo: "Idiomas", + icono: "bi-translate", + zona: "abajo" + }, + { + campo: "sinopsisSerie", + titulo: "Sinopsis", + icono: "bi-text-paragraph", + zona: "sinopsis" + } + ], + + detallesTemporada: [ + { + campo: "directorTemporada", + titulo: "Director", + icono: "bi-camera-reels", + zona: "poster" + }, + { + campo: "actorTemporada", + titulo: "Reparto", + icono: "bi-people", + zona: "poster" + }, + { + campo: "guionistaTemporada", + titulo: "Guion", + icono: "bi-pencil", + zona: "poster" + }, + { + campo: "anoTemporada", + titulo: "Año", + zona: "datos" + }, + { + campo: "numeroTemporada", + titulo: "Temporada", + zona: "datos" + }, + { + campo: "episodiosTemporada", + titulo: "Episodios", + zona: "datos" + }, + { + campo: "ratingAvgTemporada", + titulo: "Valoración", + zona: "datos" + }, + { + campo: "sinopsisTemporada", + titulo: "Sinopsis", + icono: "bi-text-paragraph", + zona: "sinopsis" + } + ], + + detallesEpisodio: [ + { + campo: "directorEpisodio", + titulo: "Director", + icono: "bi-camera-reels", + zona: "poster" + }, + { + campo: "actorEpisodio", + titulo: "Reparto", + icono: "bi-people", + zona: "poster" + }, + { + campo: "guionistaEpisodio", + titulo: "Guion", + icono: "bi-pencil", + zona: "poster" + }, + { + campo: "anoEpisodio", + titulo: "Año", + zona: "datos" + }, + { + campo: "numeroEpisodio", + titulo: "Episodio", + zona: "datos" + }, + { + campo: "duracionEpisodio", + titulo: "Duracion", + zona: "datos" + }, + { + campo: "ratingAvgEpisodio", + titulo: "Valoración", + zona: "datos" + }, + { + campo: "sinopsisEpisodio", + titulo: "Sinopsis", + icono: "bi-text-paragraph", + zona: "sinopsis" + } + ], + + historial: { + agregar: "agregarEpisodio", + listar: "listarSerie" + }, + + filas: 10, + + columns:[ + {field:"idUsuarioEpisodio", visible:false, download: false}, + {field:"idEpisodio", visible:false, download: false}, + {field:"idTemporada", visible:false, download: false}, + {field:"idApi", visible:false, download: false}, + {field:"pendienteEpisodio", visible:false, download: false}, + {field:"posterEpisodio", visible:false, download: false}, + {field:"ratingAvgEpisodio", visible:false, download: false}, + {field:"notasEpisodio", visible:false, download: false}, + {field:"favEpisodio", visible:false, download: false}, + {field:"nombreEpisodio", title:"Episodio", widthGrow:5, variableHeight: true, cssClass: "expandirCelda nombreTabla", headerTooltip: "Nombre del episodio", formatter: cell => celdaNombre(cell)}, + {field:"directorEpisodio", title:"Director", widthGrow:3, cssClass: "expandirCelda", headerTooltip: "Director del episodio"}, + {field:"anoEpisodio", title:"Año", width:70, headerTooltip: "Año de salida del episodio"}, + {field:"fechaEpisodio", title:"Visualización", width:120, headerTooltip: "Fecha de visualización", formatter: cell => cambiarFecha(cell.getValue())}, + {field:"ratingEpisodio", title:"Valoración", width:110, headerTooltip: "Valoración personal del episodio", formatter: cell => transformarRatingTabla(cell.getValue())}, + {field:"iconos", title:"", width:60, download:false, formatter: cell => celdaIconos(cell)} + ] + }, // Fin episodio + + juego: { + nombreContenido: 'Videojuego', + nombrePluralContenido: 'Videojuegos', + genero: "o", + + controlador: 'controladores/controladorJuego.php', + + idUsuarioContenido: 'idUsuarioJuego', + idContenido: "idJuego", + nombre: "nombreJuego", + ano: "anoJuego", + poster: "posterJuego", + rating: "ratingJuego", + fav: "favJuego", + pendiente: "pendienteJuego", + fecha: "fechaJuego", + fechaInicio: "fechaInicioJuego", + notas: "notasJuego", + plataforma: "plataformaJuego", + + noPoster: "", + + accionFecha: "juego", + pluralFecha: "s", + + tabla: "tablaJuego", + color: "colorJuego", + colorBoton: "colorJuegoBoton", + + icono: "bi-controller", + + camposBD: { + idApi: "idApi", + nombreJuego: "nombreJuego", + desarrolladorJuego: "desarrolladorJuego", + editorJuego: "editorJuego", + anoJuego: "anoJuego", + franquiciaJuego: "franquiciaJuego", + generoJuego: "generoJuego", + plataformasJuego: "plataformasJuego", + dlcJuego: "dlcJuego", + expansionJuego: "expansionJuego", + duracionJuego: "duracionJuego", + ratingAvgJuego: "ratingAvgJuego", + posterJuego: "posterJuego", + sinopsisJuego: "sinopsisJuego", + }, + + campos: { + idApi: "idApi", + nombre: "nombreJuego", + desarrollador: "desarrolladorJuego", + editor: "editorJuego", + ano: "anoJuego", + franquicia: "franquiciaJuego", + genero: "generoJuego", + plataformas: "plataformasJuego", + dlc: "dlcJuego", + expansion: "expansionJuego", + duracion: "duracionJuego", + ratingAvg: "ratingAvgJuego", + poster: "posterJuego", + sinopsis: "sinopsisJuego", + }, + + formAgregar: [ + { + type: "select", + nombre: "plataformaJuego", + label: "Plataforma", + id: "plataformaFormAgregar", + ancho: 12 + }, + { + type: "date", + nombre: "fechaInicioJuego", + label: "Fecha de comienzo", + id: "fechaInicioFormAgregar", + ancho: 6 + }, + { + type: "date", + nombre: "fechaJuego", + label: "Fecha de finalización", + id: "fechaFormAgregar", + ancho: 6, + } + ], + + formFecha: [ + { + type: "date", + nombre: "fechaInicioJuego", + label: "Fecha de inicio", + id: "fechaInicioFormEditar", + ancho: 6 + }, + { + type: "date", + nombre: "fechaJuego", + label: "Fecha de finalización", + id: "fechaFormEditar", + ancho: 6 + } + ], + + editarPlataforma: true, + + detalles: [ + { + campo: 'desarrolladorJuego', + titulo: 'Desarrollador', + icono: 'bi-code-square', + zona: 'poster' + }, + { + campo: 'editorJuego', + titulo: 'Editor', + icono: 'bi-building', + zona: 'poster' + }, + { + campo: "franquiciaJuego", + titulo: "Franquicia", + icono: "bi-collection", + zona: "poster" + }, + { + campo: 'generoJuego', + titulo: 'Géneros', + icono: 'bi-tags', + zona: 'poster' + }, + { + campo: 'plataformasJuego', + titulo: 'Plataformas', + icono: 'bi-controller', + zona: 'poster' + }, + { + campo: "dlcJuego", + titulo: "DLCs", + icono: "bi-box-seam", + zona: "abajo" + }, + { + campo: "expansionJuego", + titulo: "Expansiones", + icono: "bi-puzzle", + zona: "abajo" + }, + { + campo: 'anoJuego', + titulo: 'Año', + zona: 'datos' + }, + { + campo: "duracionJuego", + titulo: "Duración estimada", + zona: "datos" + }, + { + campo: 'ratingAvgJuego', + titulo: 'Valoración', + zona: 'datos' + }, + { + campo: 'sinopsisJuego', + titulo: 'Descripción', + icono: 'bi-text-paragraph', + zona: 'sinopsis' + } + ], + + detallesInfo: [ + { + campo: 'desarrolladorJuego', + titulo: 'Desarrollador', + icono: 'bi-code-square', + zona: 'poster' + }, + { + campo: 'editorJuego', + titulo: 'Editor', + icono: 'bi-building', + zona: 'poster' + }, + { + campo: "franquiciaJuego", + titulo: "Franquicia", + icono: "bi-collection", + zona: "poster" + }, + { + campo: 'generoJuego', + titulo: 'Géneros', + icono: 'bi-tags', + zona: 'poster' + }, + { + campo: 'plataformasJuego', + titulo: 'Plataformas', + icono: 'bi-controller', + zona: 'poster' + }, + { + campo: "expansionJuego", + titulo: "Expansiones", + icono: "bi-puzzle", + zona: "poster" + }, + { + campo: "dlcJuego", + titulo: "DLCs", + icono: "bi-box-seam", + zona: "poster" + }, + { + campo: 'anoJuego', + titulo: 'Año', + zona: 'datos' + }, + { + campo: "duracionJuego", + titulo: "Duración estimada", + zona: "datos" + }, + { + campo: 'ratingAvgJuego', + titulo: 'Valoración', + zona: 'datos' + }, + { + campo: 'sinopsisJuego', + titulo: 'Descripción', + icono: 'bi-text-paragraph', + zona: 'sinopsis' + } + ], + + historial: { + agregar: "agregarJuego", + listar: "listarJuego" + }, + + filas: 9, + + columns:[ + {field:"idUsuarioJuego", visible:false, download: false}, + {field:"idJuego", visible:false, download: false}, + {field:"idApi", visible:false, download: false}, + {field:"pendienteJuego", visible:false, download: false}, + {field:"posterJuego", visible:false, download: false}, + {field:"notasJuego", visible:false, download: false}, + {field:"favJuego", visible:false, download: false}, + {field:"nombreJuego", title:"Videojuego", widthGrow:5, variableHeight: true, cssClass: "expandirCelda nombreTabla", headerTooltip: "Nombre del videojuego", formatter: cell => celdaNombre(cell)}, + {field:"desarrolladorJuego", title:"Desarrollador", widthGrow:3, variableHeight: true, vertAlign:"middle", cssClass: "expandirCelda", headerTooltip: "Desarrollador del videojuego"}, + {field:"anoJuego", title:"Año", width:60, vertAlign:"middle", headerTooltip: "Año de salida del videojuego"}, + {field:"fechaInicioJuego", title:"Inicio", width:100, vertAlign:"middle", headerTooltip: "Fecha de inicio", formatter: cell => cambiarFecha(cell.getValue())}, + {field:"fechaJuego", title:"Finalización", width:110, vertAlign:"middle", headerTooltip: "Fecha de finalización", formatter: cell => cambiarFecha(cell.getValue())}, + {field:"plataformaJuego", title:"Plataforma", width:110, variableHeight: true, vertAlign:"middle", cssClass: "expandirCelda", headerTooltip:"Plataforma del videojuego"}, + {field:"ratingJuego", title:"Valoración", width:100, vertAlign:"middle", headerTooltip: "Valoración personal del videojuego", formatter: cell => transformarRatingTabla(cell.getValue())}, + {field:"iconos", title:"", width:50, vertAlign:"middle", download:false, formatter: cell => celdaIconos(cell)} + ] + + }, // Fin juego + + libro: { + nombreContenido: 'Libro', + nombrePluralContenido: 'Libros', + genero: "o", + + controlador: 'controladores/controladorLibro.php', + + idUsuarioContenido: 'idUsuarioLibro', + idContenido: "idLibro", + nombre: "nombreLibro", + ano: "anoLibro", + poster: "posterLibro", + rating: "ratingLibro", + fav: "favLibro", + pendiente: "pendienteLibro", + fecha: "fechaLibro", + fechaInicio: "fechaInicioLibro", + notas: "notasLibro", + + noPoster: "", + + accionFecha: "lectura", + pluralFecha: "s", + + tabla: "tablaLibro", + color: "colorLibro", + colorBoton: "colorLibroBoton", + + icono: "bi-book", + + camposBD: { + idApi: "idApi", + nombreLibro: "nombreLibro", + autorLibro: "autorLibro", + anoLibro: "anoLibro", + generoLibro: "generoLibro", + temaLibro: "temaLibro", + paginasLibro: "paginasLibro", + edicionesLibro: "edicionesLibro", + idiomaLibro: "idiomaLibro", + ratingAvgLibro: "ratingAvgLibro", + posterLibro: "posterLibro", + sinopsisLibro: "sinopsisLibro", + }, + + campos: { + idApi: "idApi", + nombre: "nombreLibro", + autor: "autorLibro", + ano: "anoLibro", + genero: "generoLibro", + tema: "temaLibro", + paginas: "paginasLibro", + ediciones: "edicionesLibro", + idioma: "idiomaLibro", + ratingAvg: "ratingAvgLibro", + poster: "posterLibro", + sinopsis: "sinopsisLibro", + }, + + formAgregar: [ + { + type: "date", + nombre: "fechaInicioLibro", + label: "Fecha de comienzo", + id: "fechaInicioFormAgregar", + ancho: 6 + }, + { + type: "date", + nombre: "fechaLibro", + label: "Fecha de finalización", + id: "fechaFormAgregar", + ancho: 6, + } + ], + + formFecha: [ + { + type: "date", + nombre: "fechaInicioLibro", + label: "Fecha de inicio", + id: "fechaInicioFormEditar", + ancho: 6 + }, + { + type: "date", + nombre: "fechaLibro", + label: "Fecha de finalización", + id: "fechaFormEditar", + ancho: 6 + } + ], + + detalles: [ + + { + campo: 'autorLibro', + titulo: 'Autor', + icono: 'bi-person', + zona: 'poster' + }, + + { + campo: 'generoLibro', + titulo: 'Géneros', + icono: 'bi-bookmark-star', + zona: 'poster' + }, + + { + campo: 'temaLibro', + titulo: 'Temas', + icono: 'bi-tags', + zona: 'poster' + }, + + { + campo: 'anoLibro', + titulo: 'Año', + zona: 'datos' + }, + + { + campo: 'paginasLibro', + titulo: 'PÔginas', + zona: 'datos' + }, + + { + campo: 'ratingAvgLibro', + titulo: 'Valoración', + zona: 'datos' + }, + + { + campo: 'idiomaLibro', + titulo: 'Idiomas', + icono: 'bi-translate', + zona: 'abajo' + }, + + { + campo: 'edicionesLibro', + titulo: 'Ediciones', + icono: 'bi-layers', + zona: 'abajo' + }, + + { + campo: 'sinopsisLibro', + titulo: 'Descripción', + icono: 'bi-text-paragraph', + zona: 'sinopsis' + } + + ], + + detallesInfo: [ + + { + campo: 'autorLibro', + titulo: 'Autor', + icono: 'bi-person', + zona: 'poster' + }, + + { + campo: 'generoLibro', + titulo: 'Géneros', + icono: 'bi-bookmark-star', + zona: 'poster' + }, + + { + campo: 'temaLibro', + titulo: 'Temas', + icono: 'bi-tags', + zona: 'poster' + }, + + { + campo: 'anoLibro', + titulo: 'Año', + zona: 'datos' + }, + + { + campo: 'paginasLibro', + titulo: 'PÔginas', + zona: 'datos' + }, + + { + campo: 'ratingAvgLibro', + titulo: 'Valoración', + zona: 'datos' + }, + + { + campo: 'idiomaLibro', + titulo: 'Idiomas', + icono: 'bi-translate', + zona: 'poster' + }, + + { + campo: 'edicionesLibro', + titulo: 'Ediciones', + icono: 'bi-layers', + zona: 'poster' + }, + + { + campo: 'sinopsisLibro', + titulo: 'Descripción', + icono: 'bi-text-paragraph', + zona: 'sinopsis' + } + + ], + + historial: { + agregar: "agregarLibro", + listar: "listarLibro" + }, + + filas: 10, + + columns:[ + {field:"idUsuarioLibro", visible:false, download: false}, + {field:"idLibro", visible:false, download: false}, + {field:"idApi", visible:false, download: false}, + {field:"pendienteLibro", visible:false, download: false}, + {field:"posterLibro", visible:false, download: false}, + {field:"notasLibro", visible:false, download: false}, + {field:"favLibro", visible:false, download: false}, + {field:"nombreLibro", title:"Libro", widthGrow:5, variableHeight: true, cssClass: "expandirCelda nombreTabla", headerTooltip: "Nombre del libro", formatter: cell => celdaNombre(cell)}, + {field:"autorLibro", title:"Autor", widthGrow:3, variableHeight: true, vertAlign:"middle", cssClass: "expandirCelda", headerTooltip: "Desarrollador del libro"}, + {field:"anoLibro", title:"Año", width:60, vertAlign:"middle", headerTooltip: "Año de salida del libro"}, + {field:"fechaInicioLibro", title:"Inicio", width:100, vertAlign:"middle", headerTooltip: "Fecha de inicio", formatter: cell => cambiarFecha(cell.getValue())}, + {field:"fechaLibro", title:"Finalización", width:110, vertAlign:"middle", headerTooltip: "Fecha de finalización", formatter: cell => cambiarFecha(cell.getValue())}, + {field:"ratingLibro", title:"Valoración", width:100, vertAlign:"middle", headerTooltip: "Valoración personal del libro", formatter: cell => transformarRatingTabla(cell.getValue())}, + {field:"iconos", title:"", width:50, vertAlign:"middle", download:false, formatter: cell => celdaIconos(cell)} + ] + + }, // Fin libro + +}; \ No newline at end of file diff --git a/js/contenido.js b/js/contenido.js new file mode 100644 index 0000000..4262692 --- /dev/null +++ b/js/contenido.js @@ -0,0 +1,1828 @@ +const parametros = new URLSearchParams(window.location.search); +let tipoContenido = parametros.get('tipo'); +if(!tipoContenido || !contenidoConfig[tipoContenido]){ + window.location.href = 'index.php'; +} +var config = contenidoConfig[tipoContenido]; +var configAnterior = null; + +var tablaActual = ''; +var contenidoSeleccionado = null; +var temporadaSeleccionada = null; +var episodioSeleccionado = null; +var temporizadorBusqueda; + +$(document).ready(function(){ + + tablaGeneral(); + mostrarHistorial(); + + if(tipoContenido=='serie' || tipoContenido=='temporada' || tipoContenido=='episodio'){ + botonesSeries(); + } + + + ///////////////////////////////////////////////// TABLAS ///////////////////////////////////////////////// + + // Funcionalidad boton todos los registros + $('#botTodos').click(function(event){ + event.preventDefault(); + tablaGeneral(); + }); + + /// Funcionalidad botones estrella + $('.botEstrella').click(function(event) { + event.preventDefault(); + let rating = this.id.replace('botEstrella', ''); + tablaEstrellas(rating); + }); + + // Funcionalidad boton favoritos + $('#botFav').click(function(event){ + event.preventDefault(); + tablaFavoritas(); + }); + + // Funcionalidad boton pendientes + $('#botPendientes').click(function(){ + event.preventDefault(); + tablaPendientes(); + }); + + // Funcionalidad buscar + $('#buscarForm').submit(function(event){ + event.preventDefault(); + let busqueda = $('#cajaBusqueda').val(); + + $.ajax({ + method: "POST", + url: config.controlador, + dataType: "json", + data: { + "busqueda": busqueda, + "orden": 'buscar' + }, + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + if(window.tabla){ + window.tabla.destroy(); + } + tablaActual = 'busqueda'; + window.tabla = crearTabla(respuesta, config.nombrePluralContenido+' Encontrad'+config.genero+'s por \''+busqueda+'\''); + } // Fin else + }) // Fin ajax + }); + + // Funcionalidad de corazones de tabla + $('#tablas').on('click', '.fav', function(event){ + event.preventDefault(); + + let corazon = $(this); + let id = $(this).data('id'); + let fav = $(this).hasClass('bi-heart') ? 1 : 0; + + $.ajax({ + method: "POST", + url: config.controlador, + dataType: "json", + data: { + [config.idUsuarioContenido]: id, + [config.fav]: fav, + "orden": 'favorita' + }, + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + corazon.hasClass('bi-heart-fill') ? agregarHistorial('desfav', id) : agregarHistorial('fav', id); + + corazon.toggleClass('bi-heart bi-heart-fill'); + if (tablaActual == 'favoritas'){ + window.tabla.deleteRow(id); + actualizarNumero(); + } + + } // Fin else + }); // Fin ajax + }); + + // Funcionalidad de notas de tabla + $('#tablas').on('click', '.notas', function(event){ + event.preventDefault(); + + let id = $(this).data('id'); + $('#idFormEditarNotas').val(id); + $('#posterNotas').attr('src', 'images/noPoster.jpeg'); + $('#nombreNotas').text('Cargando...'); + + obtenerDetalles(id).then(function(respuesta){ + if (respuesta[0][config.poster] == config.noPoster) { + $('#posterNotas').attr('src', 'images/noPoster.jpeg'); + }else{ + $('#posterNotas').attr('src', respuesta[0][config.poster]); + } + $('#nombreNotas').text(respuesta[0][config.nombre]); + }); + + $.ajax({ + method: "POST", + url: config.controlador, + dataType: "json", + data: { + [config.idUsuarioContenido]: id, + "orden": 'comprobar' + }, + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + if(respuesta[0][config.notas] == null){ + $('#textoNotas').text('Aún no has añadido ninguna nota.'); + $('#notasFormEditarNotas').val(respuesta[0][config.notas]); + }else{ + $('#textoNotas').text(respuesta[0][config.notas]); + $('#notasFormEditarNotas').val(respuesta[0][config.notas]); + } + } // Fin else + }) // Fin ajax + + + }); + + + ///////////////////////////////////////////////// AGREGAR ///////////////////////////////////////////////// + + // Funcionalidad buscar en Api + $('#nombreFormBuscarApi').on('input', function(){ + clearTimeout(temporizadorBusqueda); + let nombre = $('#nombreFormBuscarApi').val(); + if(nombre.length < 2){ + return; + } + temporizadorBusqueda = setTimeout(function(){ + + $.ajax({ + method: "POST", + url: config.controlador, + dataType: "json", + data: { + [config.nombre]: nombre, + "orden": 'buscarApi' + }, + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + let html = resultadosApi(respuesta); + $('#resultadosApi').html(html); + } // Fin else + }).fail(function(jqXHR, textStatus, errorThrown) { + console.log("Error AJAX:", textStatus); + console.log("Error:", errorThrown); + console.log("Respuesta del servidor:", jqXHR.responseText); + }); // Fin ajax + },600); + }); + + // Funcionalidad click en resultado Api + $('#modalAgregar').on("click",".resultadoApi", function(event){ + event.preventDefault(); + let idApi = $(this).data("id"); + + $.ajax({ + method: "POST", + url: config.controlador, + dataType: "json", + data:{ + "idApi": idApi, + "orden":"detallesApi" + } + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + contenidoSeleccionado = respuesta; + + if(config.nombreContenido == 'Serie' || config.nombreContenido == 'Temporada' || config.nombreContenido == 'Episodio'){ + let info = mostrarDetalles(contenidoSeleccionado, config.detallesSerie, 'posterSerie'); + $('#nuevosAgregar').html(info); + + let selector = mostrarSelectorTemporadas(contenidoSeleccionado); + $('#selectorSerie').html(selector); + + $('#nombreAgregar').text(contenidoSeleccionado['nombreSerie']); + + $('#selectorSerie').removeClass('d-none'); + }else{ + let info = mostrarDetalles(contenidoSeleccionado, config.detalles); + $('#nuevosAgregar').html(info); + + let form = mostrarFormAgregar(config.formAgregar); + $('#detallesFormAgregar').html(form); + + let hoy = new Date().toISOString().split('T')[0]; + $('#fechaFormAgregar').val(hoy); + + $('#nombreAgregar').text(contenidoSeleccionado[config.campos.nombre]); + + $('#formAgregar').removeClass('d-none'); + $('#pieAgregar').removeClass('d-none'); + } + + $('#contenidoBuscar').addClass('d-none'); + $('#contenidoAgregar').removeClass('d-none'); + $('#modal-dialog-Agregar').addClass('modal-xl'); + + } // Fin else + }); // Fin ajax + }); + + // Funcionalidad de estrellas en agregar + $('#estrellasAgregar').on('click', '.estrella', function(event){ + event.preventDefault(); + + let valor = $(this).data('valor'); + let mitad = this.getBoundingClientRect().left + this.offsetWidth / 2; + let rating; + + if(event.clientX < mitad){ + rating = valor - 0.5; + }else{ + rating = valor; + } + + $('#ratingFormAgregar').val(rating); + $('#infoEstrellasAgregar').removeClass('invisible'); + $('#infoEstrellasAgregar').text(rating+' de 5'); + }); + + // Funcionalidad de corazon en agregar + $('#corazonFormAgregar').click(function(event){ + event.preventDefault(); + $(this).toggleClass('bi-heart bi-heart-fill'); + }); + + // Funcionalidad de aceptar en agregar + $('#botAgregarAceptar').click(function(event){ + event.preventDefault(); + + let rating = $('#ratingFormAgregar').val(); + let fav = $('#corazonFormAgregar').hasClass('bi-heart-fill') ? 1 : 0; + let notas = $('#notasFormAgregar').val(); + + let datos = { + orden: "agregar", + [config.rating]: rating, + [config.fav]: fav, + [config.notas]: notas + }; + + // Recogemos los detalles para meterlos en la base de datos + for(const [campoPOST, campoContenido] of Object.entries(config.camposBD)){ + datos[campoPOST] = contenidoSeleccionado[campoContenido]; + } + + // Recogemos los datos especiales de cada apartado + for(const campo of config.formAgregar){ + datos[campo.nombre] = $('#' + campo.id).val(); + } + + $.ajax({ + method:"POST", + url: config.controlador, + dataType: "json", + data: datos + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + tablaGeneral(); + agregarHistorial('añadir', respuesta[config.idUsuarioContenido]); + + let modalAgregar = document.getElementById('modalAgregar'); + bootstrap.Modal.getInstance(modalAgregar).hide(); + $('#botSeries').click(); + + if(config.nombreContenido == 'Libro'){ + // Ajax para descargar la portada del apartado Libros + $.ajax({ + method: "POST", + url: config.controlador, + dataType: "json", + data: { + orden: 'descargarPoster', + [config.idContenido]: respuesta[config.idContenido], + [config.poster]: contenidoSeleccionado[config.poster] + } + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + } + }); // Fin ajax + } // Fin if + + } // Fin else + }).fail(function(jqXHR, textStatus, errorThrown) { + console.log("Error AJAX:", textStatus); + console.log("Error:", errorThrown); + console.log("Respuesta del servidor:", jqXHR.responseText); + }); // Fin ajax + }); + + + ///////////////////////////////////////////////// SERIES ///////////////////////////////////////////////// + + // Agregar + + // Funcionalidad click en serie completa + $('#modalAgregar').on('click','.serieCompleta',function(event){ + event.preventDefault(); + + configAnterior = config; + config = contenidoConfig['serie']; + + let form = mostrarFormAgregar(config.formAgregarSerie); + $('#detallesFormAgregar').html(form); + + let hoy = new Date().toISOString().split('T')[0]; + $('#fechaFormAgregar').val(hoy); + + $('#selectorSerie').addClass('d-none'); + $('#formAgregar').removeClass('d-none'); + $('#pieAgregar').removeClass('d-none'); + }); + + // Funcionalidad click en temporada + $('#modalAgregar').on('click','.temporadaOpcion',function(event){ + event.preventDefault(); + let idApiSerie = $(this).data('id'); + let numeroTemporada = $(this).data('temporada'); + let nombreSerie = contenidoSeleccionado['nombreSerie']; + + $.ajax({ + method: "POST", + url: "controladores/controladorTemporada.php", + dataType: "json", + data:{ + "orden": "detallesApiTemporada", + "idApiSerie": idApiSerie, + "numeroTemporada": numeroTemporada, + 'nombreSerie': nombreSerie + } + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + temporadaSeleccionada = respuesta; + + let info = mostrarDetalles(respuesta, config.detallesTemporada, 'posterTemporada'); + $('#nuevosAgregar').html(info); + + let selector = mostrarSelectorEpisodios(respuesta); + $('#selectorSerie').html(selector); + + $('#nombreAgregar').text(temporadaSeleccionada['nombreTemporada']); + } + }).fail(function( + jqXHR, + textStatus, + errorThrown + ){ + + console.error( + 'Error cargando temporada:', + textStatus, + errorThrown + ); + + console.error( + jqXHR.responseText + ); + + }); + }); + + // Funcionalidad click en temporada completa + $('#modalAgregar').on('click','.temporadaCompleta',function(event){ + event.preventDefault(); + + configAnterior = config; + config = contenidoConfig['temporada']; + + let form = mostrarFormAgregar(config.formAgregarTemporada); + $('#detallesFormAgregar').html(form); + + let hoy = new Date().toISOString().split('T')[0]; + $('#fechaFormAgregar').val(hoy); + + $('#selectorSerie').addClass('d-none'); + $('#formAgregar').removeClass('d-none'); + $('#pieAgregarTemporada').removeClass('d-none'); + }); + + // Funcionalidad de aceptar en agregar temporada + $('#botAgregarTemporadaAceptar').click(function(event){ + event.preventDefault(); + + let rating = $('#ratingFormAgregar').val(); + let fav = $('#corazonFormAgregar').hasClass('bi-heart-fill') ? 1 : 0; + let notas = $('#notasFormAgregar').val(); + let fecha = $('#fechaFormAgregar').val(); + + $.ajax({ + method:"POST", + url: 'controladores/controladorTemporada.php', + dataType: "json", + data: { + 'ratingTemporada': rating, + 'favTemporada': fav, + 'notasTemporada': notas, + 'fechaTemporada': fecha, + 'idApiTemporada': temporadaSeleccionada['idApi'], + 'nombreTemporada': temporadaSeleccionada['nombreTemporada'], + 'numeroTemporada': temporadaSeleccionada['numeroTemporada'], + 'directorTemporada': temporadaSeleccionada['directorTemporada'], + 'actorTemporada': temporadaSeleccionada['actorTemporada'], + 'guionistaTemporada': temporadaSeleccionada['guionistaTemporada'], + 'anoTemporada': temporadaSeleccionada['anoTemporada'], + 'episodiosTemporada': temporadaSeleccionada['episodiosTemporada'], + 'ratingAvgTemporada': temporadaSeleccionada['ratingAvgTemporada'], + 'posterTemporada': temporadaSeleccionada['posterTemporada'], + 'sinopsisTemporada': temporadaSeleccionada['sinopsisTemporada'], + 'idApiSerie': contenidoSeleccionado['idApi'], + 'nombreSerie': contenidoSeleccionado['nombreSerie'], + 'creadorSerie': contenidoSeleccionado['creadorSerie'], + 'directorSerie': contenidoSeleccionado['directorSerie'], + 'actorSerie': contenidoSeleccionado['actorSerie'], + 'companiaSerie': contenidoSeleccionado['companiaSerie'], + 'guionistaSerie': contenidoSeleccionado['guionistaSerie'], + 'generoSerie': contenidoSeleccionado['generoSerie'], + 'anoSerie': contenidoSeleccionado['anoSerie'], + 'temporadasSerie': contenidoSeleccionado['temporadasSerie'], + 'episodiosSerie': contenidoSeleccionado['episodiosSerie'], + 'ratingAvgSerie': contenidoSeleccionado['ratingAvgSerie'], + 'paisSerie': contenidoSeleccionado['paisSerie'], + 'idiomaSerie': contenidoSeleccionado['idiomaSerie'], + 'posterSerie': contenidoSeleccionado['posterSerie'], + 'sinopsisSerie': contenidoSeleccionado['sinopsisSerie'], + "orden": 'agregar' + } + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + agregarHistorial('añadir', respuesta['idUsuarioTemporada']); + + let modalAgregar = document.getElementById('modalAgregar'); + bootstrap.Modal.getInstance(modalAgregar).hide(); + $('#botTemporadas').click(); + } + }).fail(function(jqXHR, textStatus, errorThrown) { + console.log("Error AJAX:", textStatus); + console.log("Error:", errorThrown); + console.log("Respuesta del servidor:", jqXHR.responseText); + }); // Fin ajax + }); + + // Funcionalidad click en episodio + $('#modalAgregar').on('click','.episodioOpcion',function(event){ + event.preventDefault(); + + configAnterior = config; + config = contenidoConfig['episodio']; + + let idApiSerie = contenidoSeleccionado.idApi; + let numeroEpisodio = $(this).data('episodio'); + let numeroTemporada = $(this).data('temporada'); + let nombreSerie = contenidoSeleccionado['nombreSerie']; + + $.ajax({ + method: "POST", + url: "controladores/controladorEpisodio.php", + dataType: "json", + data:{ + "orden": "detallesApiEpisodio", + "idApiSerie": idApiSerie, + "numeroEpisodio": numeroEpisodio, + "numeroTemporada": numeroTemporada, + 'nombreSerie': nombreSerie + } + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + episodioSeleccionado = respuesta; + + let form = mostrarFormAgregar(config.formAgregarEpisodio); + $('#detallesFormAgregar').html(form); + + let info = mostrarDetalles(respuesta, config.detallesEpisodio, 'posterEpisodio'); + $('#nuevosAgregar').html(info); + + $('#nombreAgregar').text(respuesta['nombreEpisodio']); + + let hoy = new Date().toISOString().split('T')[0]; + $('#fechaFormAgregar').val(hoy); + + $('#selectorSerie').addClass('d-none'); + $('#formAgregar').removeClass('d-none'); + $('#pieAgregarEpisodio').removeClass('d-none'); + } + }).fail(function( + jqXHR, + textStatus, + errorThrown + ){ + + console.error( + 'Error cargando temporada:', + textStatus, + errorThrown + ); + + console.error( + jqXHR.responseText + ); + + }); + }); + + // Funcionalidad de aceptar en agregar episodio + $('#botAgregarEpisodioAceptar').click(function(event){ + event.preventDefault(); + + let rating = $('#ratingFormAgregar').val(); + let fav = $('#corazonFormAgregar').hasClass('bi-heart-fill') ? 1 : 0; + let notas = $('#notasFormAgregar').val(); + let fecha = $('#fechaFormAgregar').val(); + + $.ajax({ + method:"POST", + url: 'controladores/controladorEpisodio.php', + dataType: "json", + data: { + 'ratingEpisodio': rating, + 'favEpisodio': fav, + 'notasEpisodio': notas, + 'fechaEpisodio': fecha, + 'idApiEpisodio': episodioSeleccionado['idApi'], + 'nombreEpisodio': episodioSeleccionado['nombreEpisodio'], + 'numeroEpisodio': episodioSeleccionado['numeroEpisodio'], + 'directorEpisodio': episodioSeleccionado['directorEpisodio'], + 'actorEpisodio': episodioSeleccionado['actorEpisodio'], + 'guionistaEpisodio': episodioSeleccionado['guionistaEpisodio'], + 'anoEpisodio': episodioSeleccionado['anoEpisodio'], + 'duracionEpisodio': episodioSeleccionado['duracionEpisodio'], + 'ratingAvgEpisodio': episodioSeleccionado['ratingAvgEpisodio'], + 'posterEpisodio': episodioSeleccionado['posterEpisodio'], + 'sinopsisEpisodio': episodioSeleccionado['sinopsisEpisodio'], + 'idApiTemporada': temporadaSeleccionada['idApi'], + 'nombreTemporada': temporadaSeleccionada['nombreTemporada'], + 'numeroTemporada': temporadaSeleccionada['numeroTemporada'], + 'directorTemporada': temporadaSeleccionada['directorTemporada'], + 'actorTemporada': temporadaSeleccionada['actorTemporada'], + 'guionistaTemporada': temporadaSeleccionada['guionistaTemporada'], + 'anoTemporada': temporadaSeleccionada['anoTemporada'], + 'episodiosTemporada': temporadaSeleccionada['episodiosTemporada'], + 'ratingAvgTemporada': temporadaSeleccionada['ratingAvgTemporada'], + 'posterTemporada': temporadaSeleccionada['posterTemporada'], + 'sinopsisTemporada': temporadaSeleccionada['sinopsisTemporada'], + 'idApiSerie': contenidoSeleccionado['idApi'], + 'nombreSerie': contenidoSeleccionado['nombreSerie'], + 'creadorSerie': contenidoSeleccionado['creadorSerie'], + 'directorSerie': contenidoSeleccionado['directorSerie'], + 'actorSerie': contenidoSeleccionado['actorSerie'], + 'companiaSerie': contenidoSeleccionado['companiaSerie'], + 'guionistaSerie': contenidoSeleccionado['guionistaSerie'], + 'generoSerie': contenidoSeleccionado['generoSerie'], + 'anoSerie': contenidoSeleccionado['anoSerie'], + 'temporadasSerie': contenidoSeleccionado['temporadasSerie'], + 'episodiosSerie': contenidoSeleccionado['episodiosSerie'], + 'ratingAvgSerie': contenidoSeleccionado['ratingAvgSerie'], + 'paisSerie': contenidoSeleccionado['paisSerie'], + 'idiomaSerie': contenidoSeleccionado['idiomaSerie'], + 'posterSerie': contenidoSeleccionado['posterSerie'], + 'sinopsisSerie': contenidoSeleccionado['sinopsisSerie'], + "orden": 'agregar' + } + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + agregarHistorial('añadir', respuesta['idUsuarioEpisodio']); + + let modalAgregar = document.getElementById('modalAgregar'); + bootstrap.Modal.getInstance(modalAgregar).hide(); + $('#botEpisodios').click(); + } + }).fail(function(jqXHR, textStatus, errorThrown) { + console.log("Error AJAX:", textStatus); + console.log("Error:", errorThrown); + console.log("Respuesta del servidor:", jqXHR.responseText); + }); // Fin ajax + }); + + // Funcionalidad volver serie + $('#modalAgregar').on('click','.volverSeries',function(){ + event.preventDefault(); + + let info = mostrarDetalles(contenidoSeleccionado, config.detallesSerie, 'posterSerie'); + $('#nuevosAgregar').html(info); + + let selector = mostrarSelectorTemporadas(contenidoSeleccionado); + $('#selectorSerie').html(selector); + + $('#nombreAgregar').text(contenidoSeleccionado['nombreSerie']); + }); + + // Pendiente + + // Funcionalidad click en serie completa pendiente + $('#modalPendiente').on('click','.serieCompleta',function(event){ + event.preventDefault(); + + configAnterior = config; + config = contenidoConfig['serie']; + + $('#selectorSeriePend').addClass('d-none'); + $('#pieAgregarPend').removeClass('d-none'); + $('#modal-dialog-Pend').removeClass('modal-xl'); + $('#modal-dialog-Pend').addClass('modal-lg'); + $('#capaNuevosAgregarPend').removeClass('col-md-6'); + + }); + + // Funcionalidad click en temporada pendiente + $('#modalPendiente').on('click','.temporadaOpcion',function(event){ + event.preventDefault(); + let idApiSerie = $(this).data('id'); + let numeroTemporada = $(this).data('temporada'); + let nombreSerie = contenidoSeleccionado['nombreSerie']; + + $.ajax({ + method: "POST", + url: "controladores/controladorTemporada.php", + dataType: "json", + data:{ + "orden": "detallesApiTemporada", + "idApiSerie": idApiSerie, + "numeroTemporada": numeroTemporada, + 'nombreSerie': nombreSerie + } + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + temporadaSeleccionada = respuesta; + + let info = mostrarDetalles(respuesta, config.detallesTemporada, 'posterTemporada'); + $('#nuevosAgregarPend').html(info); + + let selector = mostrarSelectorEpisodios(respuesta); + $('#selectorSeriePend').html(selector); + + $('#nombreAgregarPend').text(temporadaSeleccionada['nombreTemporada']); + } + }).fail(function( + jqXHR, + textStatus, + errorThrown + ){ + + console.error( + 'Error cargando temporada:', + textStatus, + errorThrown + ); + + console.error( + jqXHR.responseText + ); + + }); + }); + + // Funcionalidad click en temporada completa pendiente + $('#modalPendiente').on('click','.temporadaCompleta',function(event){ + event.preventDefault(); + + configAnterior = config; + config = contenidoConfig['temporada']; + + $('#selectorSeriePend').addClass('d-none'); + $('#pieAgregarTemporadaPend').removeClass('d-none'); + $('#modal-dialog-Pend').removeClass('modal-xl'); + $('#modal-dialog-Pend').addClass('modal-lg'); + $('#capaNuevosAgregarPend').removeClass('col-md-6'); + }); + + // Funcionalidad de aceptar en agregar temporada pendiente + $('#botAgregarTemporadaPendAceptar').click(function(event){ + event.preventDefault(); + + $.ajax({ + method:"POST", + url: 'controladores/controladorTemporada.php', + dataType: "json", + data: { + 'idApiTemporada': temporadaSeleccionada['idApi'], + 'nombreTemporada': temporadaSeleccionada['nombreTemporada'], + 'numeroTemporada': temporadaSeleccionada['numeroTemporada'], + 'directorTemporada': temporadaSeleccionada['directorTemporada'], + 'actorTemporada': temporadaSeleccionada['actorTemporada'], + 'guionistaTemporada': temporadaSeleccionada['guionistaTemporada'], + 'anoTemporada': temporadaSeleccionada['anoTemporada'], + 'episodiosTemporada': temporadaSeleccionada['episodiosTemporada'], + 'ratingAvgTemporada': temporadaSeleccionada['ratingAvgTemporada'], + 'posterTemporada': temporadaSeleccionada['posterTemporada'], + 'sinopsisTemporada': temporadaSeleccionada['sinopsisTemporada'], + 'idApiSerie': contenidoSeleccionado['idApi'], + 'nombreSerie': contenidoSeleccionado['nombreSerie'], + 'creadorSerie': contenidoSeleccionado['creadorSerie'], + 'directorSerie': contenidoSeleccionado['directorSerie'], + 'actorSerie': contenidoSeleccionado['actorSerie'], + 'companiaSerie': contenidoSeleccionado['companiaSerie'], + 'guionistaSerie': contenidoSeleccionado['guionistaSerie'], + 'generoSerie': contenidoSeleccionado['generoSerie'], + 'anoSerie': contenidoSeleccionado['anoSerie'], + 'temporadasSerie': contenidoSeleccionado['episodiosSerie'], + 'episodiosSerie': contenidoSeleccionado['episodiosSerie'], + 'ratingAvgSerie': contenidoSeleccionado['ratingAvgSerie'], + 'paisSerie': contenidoSeleccionado['paisSerie'], + 'idiomaSerie': contenidoSeleccionado['idiomaSerie'], + 'posterSerie': contenidoSeleccionado['posterSerie'], + 'sinopsisSerie': contenidoSeleccionado['sinopsisSerie'], + "orden": 'agregarPend' + } + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + agregarHistorial('añadirPend', respuesta['idUsuarioTemporada']); + + let modalAgregarPend = document.getElementById('modalPendiente'); + bootstrap.Modal.getInstance(modalAgregarPend).hide(); + } + }).fail(function(jqXHR, textStatus, errorThrown) { + console.log("Error AJAX:", textStatus); + console.log("Error:", errorThrown); + console.log("Respuesta del servidor:", jqXHR.responseText); + }); // Fin ajax + }); + + // Funcionalidad click en episodio pendiente + $('#modalPendiente').on('click','.episodioOpcion',function(event){ + event.preventDefault(); + + configAnterior = config; + config = contenidoConfig['episodio']; + + let idApiSerie = contenidoSeleccionado.idApi; + let numeroEpisodio = $(this).data('episodio'); + let numeroTemporada = $(this).data('temporada'); + let nombreSerie = contenidoSeleccionado['nombreSerie']; + + $.ajax({ + method: "POST", + url: "controladores/controladorEpisodio.php", + dataType: "json", + data:{ + "orden": "detallesApiEpisodio", + "idApiSerie": idApiSerie, + "numeroEpisodio": numeroEpisodio, + "numeroTemporada": numeroTemporada, + "nombreSerie": nombreSerie + } + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + episodioSeleccionado = respuesta; + + let info = mostrarDetalles(respuesta, config.detallesEpisodio, 'posterEpisodio'); + $('#nuevosAgregarPend').html(info); + + $('#nombreAgregarPend').text(respuesta['nombreEpisodio']); + + $('#selectorSeriePend').addClass('d-none'); + $('#pieAgregarEpisodioPend').removeClass('d-none'); + $('#modal-dialog-Pend').removeClass('modal-xl'); + $('#modal-dialog-Pend').addClass('modal-lg'); + $('#capaNuevosAgregarPend').removeClass('col-md-6'); + } + }).fail(function( + jqXHR, + textStatus, + errorThrown + ){ + + console.error( + 'Error cargando temporada:', + textStatus, + errorThrown + ); + + console.error( + jqXHR.responseText + ); + + }); + }); + + // Funcionalidad de aceptar en agregar episodio pendiente + $('#botAgregarEpisodioPendAceptar').click(function(event){ + event.preventDefault(); + + $.ajax({ + method:"POST", + url: 'controladores/controladorEpisodio.php', + dataType: "json", + data: { + 'idApiEpisodio': episodioSeleccionado['idApi'], + 'nombreEpisodio': episodioSeleccionado['nombreEpisodio'], + 'numeroEpisodio': episodioSeleccionado['numeroEpisodio'], + 'directorEpisodio': episodioSeleccionado['directorEpisodio'], + 'actorEpisodio': episodioSeleccionado['actorEpisodio'], + 'guionistaEpisodio': episodioSeleccionado['guionistaEpisodio'], + 'anoEpisodio': episodioSeleccionado['anoEpisodio'], + 'duracionEpisodio': episodioSeleccionado['duracionEpisodio'], + 'ratingAvgEpisodio': episodioSeleccionado['ratingAvgEpisodio'], + 'posterEpisodio': episodioSeleccionado['posterEpisodio'], + 'sinopsisEpisodio': episodioSeleccionado['sinopsisEpisodio'], + 'idApiTemporada': temporadaSeleccionada['idApi'], + 'nombreTemporada': temporadaSeleccionada['nombreTemporada'], + 'numeroTemporada': temporadaSeleccionada['numeroTemporada'], + 'directorTemporada': temporadaSeleccionada['directorTemporada'], + 'actorTemporada': temporadaSeleccionada['actorTemporada'], + 'guionistaTemporada': temporadaSeleccionada['guionistaTemporada'], + 'anoTemporada': temporadaSeleccionada['anoTemporada'], + 'episodiosTemporada': temporadaSeleccionada['episodiosTemporada'], + 'ratingAvgTemporada': temporadaSeleccionada['ratingAvgTemporada'], + 'posterTemporada': temporadaSeleccionada['posterTemporada'], + 'sinopsisTemporada': temporadaSeleccionada['sinopsisTemporada'], + 'idApiSerie': contenidoSeleccionado['idApi'], + 'nombreSerie': contenidoSeleccionado['nombreSerie'], + 'creadorSerie': contenidoSeleccionado['creadorSerie'], + 'directorSerie': contenidoSeleccionado['directorSerie'], + 'actorSerie': contenidoSeleccionado['actorSerie'], + 'companiaSerie': contenidoSeleccionado['companiaSerie'], + 'guionistaSerie': contenidoSeleccionado['guionistaSerie'], + 'generoSerie': contenidoSeleccionado['generoSerie'], + 'anoSerie': contenidoSeleccionado['anoSerie'], + 'temporadasSerie': contenidoSeleccionado['episodiosSerie'], + 'episodiosSerie': contenidoSeleccionado['episodiosSerie'], + 'ratingAvgSerie': contenidoSeleccionado['ratingAvgSerie'], + 'paisSerie': contenidoSeleccionado['paisSerie'], + 'idiomaSerie': contenidoSeleccionado['idiomaSerie'], + 'posterSerie': contenidoSeleccionado['posterSerie'], + 'sinopsisSerie': contenidoSeleccionado['sinopsisSerie'], + "orden": 'agregarPend' + } + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + agregarHistorial('añadirPend', respuesta['idUsuarioEpisodio']); + + let modalAgregarPend = document.getElementById('modalPendiente'); + bootstrap.Modal.getInstance(modalAgregarPend).hide(); + } + }).fail(function(jqXHR, textStatus, errorThrown) { + console.log("Error AJAX:", textStatus); + console.log("Error:", errorThrown); + console.log("Respuesta del servidor:", jqXHR.responseText); + }); // Fin ajax + }); + + // Funcionalidad volver serie pendiente + $('#modalPendiente').on('click','.volverSeries',function(){ + event.preventDefault(); + + let info = mostrarDetalles(contenidoSeleccionado, config.detallesSerie, 'posterSerie'); + $('#nuevosAgregarPend').html(info); + + let selector = mostrarSelectorTemporadas(contenidoSeleccionado); + $('#selectorSeriePend').html(selector); + + $('#nombreAgregarPend').text(contenidoSeleccionado['nombreSerie']); + }); + + + ///////////////////////////////////////////////// EDITAR ///////////////////////////////////////////////// + + // Funcionalidad de editar valoración + $('#tablas').on('click', '.editarValoracion', function(event){ + event.preventDefault(); + + let id = $(this).data('id'); + + $('#editarValForm').removeClass('d-none'); + $('#botVal').removeClass('d-none'); + $('#editarModalLabel').text('Editar Valoración'); + + $.ajax({ + method: "POST", + url: config.controlador, + dataType: "json", + data: { + [config.idUsuarioContenido]: id, + "orden": 'comprobar' + }, + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + $('#idFormEditar').val(id); + let rating = Number(respuesta[0][config.rating]); + $('#ratingFormEditar').val(rating); + let estrellas = transformarRating(rating); + $('#estrellasEditar').html(estrellas); + } // Fin else + }); // Fin ajax + }); + + // Funcionalidad de estrellas en editar + $('#modalEditar').on('click', '.estrella', function(event){ + event.preventDefault(); + + let valor = $(this).data('valor'); + let id = $(this).data('id'); + let mitad = this.getBoundingClientRect().left + this.offsetWidth / 2; + let rating; + + if(event.clientX < mitad){ + rating = valor - 0.5; + }else{ + rating = valor; + } + + $('#ratingFormEditar').val(rating); + $('#infoEstrellasEditar').removeClass('invisible'); + $('#infoEstrellasEditar').text(rating+' de 5'); + + }); + + // Funcionalidad de aceptar en editar valoracion + $('#botFormEditarValAceptar').click(function(event){ + event.preventDefault(); + + let rating = $('#ratingFormEditar').val(); + let id = $('#idFormEditar').val(); + + $.ajax({ + method: "POST", + url: config.controlador, + dataType: "json", + data: { + [config.rating]: rating, + [config.idUsuarioContenido]: id, + "orden": 'editarVal' + }, + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + mostrarExito(respuesta.exito); + agregarHistorial('editarVal', id); + window.tabla.updateData([{ + [config.idUsuarioContenido]: id, + [config.rating]: rating + }]); + + $('#ratingFormEditar').val(''); + $('#idFormEditar').val(''); + $('#infoEstrellasEditar').addClass('invisible'); + + let modalElemento = document.getElementById('modalEditar'); + bootstrap.Modal.getInstance(modalElemento).hide(); + } // Fin else + }) // Fin ajax + }); + + // Funcionalidad de editar fecha + $('#tablas').on('click', '.editarFecha', function(event){ + event.preventDefault(); + + let id = $(this).data('id'); + + $('#editarFechaForm').removeClass('d-none'); + $('#botFecha').removeClass('d-none'); + $('#editarModalLabel').text('Editar fecha de '+config.accionFecha); + $('#nuevosEditarFecha').html('
Cargando...
'); + + $.ajax({ + method: "POST", + url: config.controlador, + dataType: "json", + data: { + [config.idUsuarioContenido]: id, + "orden": 'comprobar' + }, + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + + $('#nuevosEditarFecha').html(mostrarFormFecha()); + + $('#idFormEditar').val(id); + + for(const campo of config.formFecha){ + $('#' + campo.id).val(respuesta[0][campo.nombre] ?? ''); + } + + } // Fin else + }); // Fin ajax + }); + + // Funcionalidad de aceptar en editar fecha + $('#botFormEditarFechaAceptar').click(function(event){ + event.preventDefault(); + + let id = $('#idFormEditar').val(); + + let datos = { + [config.idUsuarioContenido]: id, + }; + + for(const campo of config.formFecha){ + datos[campo.nombre] = $('#' + campo.id).val(); + } + + $.ajax({ + method: "POST", + url: config.controlador, + dataType: "json", + data: { + ...datos, + orden: "editarFecha" + } + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + mostrarExito(respuesta.exito); + agregarHistorial('editarFecha', id); + + window.tabla.updateData([datos]).then(function(){ + if(window.tabla.getRow(id)){ + window.tabla.getRow(id).reformat(); + } + }); + + $('#fechaFormEditar').val(''); + $('#fechaInicioFormEditar').val(''); + $('#idFormEditar').val(''); + + let modalElemento = $('#modalEditar'); + bootstrap.Modal.getInstance(modalElemento).hide(); + } // Fin else + }) // Fin ajax + }); + + // Funcionalidad de editar estado Serie + $('#tablas').on('click', '.editarEstado', function(event){ + event.preventDefault(); + + let id = $(this).data('id'); + + $('#editarEstadoForm').removeClass('d-none'); + $('#botEstado').removeClass('d-none'); + $('#editarModalLabel').text('Editar Estado'); + + $('#idFormEditar').val(id); + + obtenerDetalles(id).then(function(respuesta){ + let html = mostrarFormEstado(respuesta[0]); + $('#nuevosEditarEstado').html(html); + + return $.ajax({ + method: "POST", + url: config.controlador, + dataType: "json", + data: { + [config.idUsuarioContenido]: id, + "orden": 'comprobar' + }, + }); // Fin ajax + }).then(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + $('#estadoFormEditar').val(respuesta[0][config.estado]); + } // Fin else + }); // Fin then + + }); + + // Funcionalidad de aceptar en editar estado Serie + $('#botFormEditarEstadoAceptar').click(function(event){ + event.preventDefault(); + + let id = $('#idFormEditar').val(); + let estado = $('#estadoFormEditar').val(); + + $.ajax({ + method: "POST", + url: config.controlador, + dataType: "json", + data: { + [config.idUsuarioContenido]: id, + [config.estado]: estado, + orden: "editarEstado" + } + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + mostrarExito(respuesta.exito); + agregarHistorial('editarEstado', id); + + window.tabla.updateData([{ + [config.idUsuarioContenido]: id, + [config.estado]: estado + }]); + + $('#estadoFormEditar').val(''); + $('#idFormEditar').val(''); + + let modalElemento = $('#modalEditar'); + bootstrap.Modal.getInstance(modalElemento).hide(); + } // Fin else + }) // Fin ajax + }); + + // Funcionalidad de editar plataforma Juego + $('#tablas').on('click', '.editarPlataforma', function(event){ + event.preventDefault(); + + let id = $(this).data('id'); + + $('#editarPlataformaForm').removeClass('d-none'); + $('#botPlat').removeClass('d-none'); + $('#editarModalLabel').text('Editar Plataforma'); + $('#nuevosEditarPlataforma').html('
Cargando...
'); + + $('#idFormEditar').val(id); + + obtenerDetalles(id).then(function(respuesta){ + let html = mostrarFormPlataforma(respuesta[0]); + $('#nuevosEditarPlataforma').html(html); + + return $.ajax({ + method: "POST", + url: config.controlador, + dataType: "json", + data: { + [config.idUsuarioContenido]: id, + "orden": 'comprobar' + }, + }); // Fin ajax + }).then(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + $('#plataformaFormEditar').val(respuesta[0][config.plataforma]); + } // Fin else + }); // Fin then + + }); + + // Funcionalidad de aceptar en editar plataforma Juego + $('#botFormEditarPlatAceptar').click(function(event){ + event.preventDefault(); + + let id = $('#idFormEditar').val(); + let plataforma = $('#plataformaFormEditar').val(); + + $.ajax({ + method: "POST", + url: config.controlador, + dataType: "json", + data: { + [config.idUsuarioContenido]: id, + [config.plataforma]: plataforma, + orden: "editarPlataforma" + } + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + mostrarExito(respuesta.exito); + agregarHistorial('editarPlataforma', id); + + window.tabla.updateData([{ + [config.idUsuarioContenido]: id, + [config.plataforma]: plataforma + }]); + + $('#plataformaFormEditar').val(''); + $('#idFormEditar').val(''); + + let modalElemento = $('#modalEditar'); + bootstrap.Modal.getInstance(modalElemento).hide(); + } // Fin else + }) // Fin ajax + }); + + // Funcionalidad de editar notas + $('#botEditarNotas').click(function(event){ + event.preventDefault(); + + let notas = $('#notasFormEditarNotas').val(); + + $('#editorNotas').removeClass('d-none'); + $('#textoNotas').addClass('d-none'); + $('#botEditarNotas').addClass('d-none'); + $('#notasTextarea').trigger('focus'); + if(notas==''){ + $('#notasTextarea').val('') + }else{ + $('#notasTextarea').val(notas); + } + + }); + + // Funcionalidad de aceptar en editar notas + $('#botGuardarNotas').click(function(event){ + event.preventDefault(); + + let notas = $('#notasTextarea').val(); + let id = $('#idFormEditarNotas').val(); + + $.ajax({ + method: "POST", + url: config.controlador, + dataType: "json", + data: { + [config.idUsuarioContenido]: id, + [config.notas]: notas, + "orden": 'editarNotas' + }, + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + mostrarExito(respuesta.exito); + agregarHistorial('editarNotas', id); + + $('#editorNotas').addClass('d-none'); + $('#textoNotas').removeClass('d-none'); + $('#botEditarNotas').removeClass('d-none'); + $('#notasFormEditarNotas').val(notas); + + if(notas==''){ + $('#textoNotas').text('Aún no has añadido ninguna nota.') + }else{ + $('#textoNotas').text(notas); + } + + notas = notas === '' ? null : notas; + + let fila = window.tabla.getRow(id); + + fila.update({ + [config.notas]: notas + }).then(function(){ + fila.reformat(); + }); + + } // Fin else + }) // Fin ajax + }); + + // Funcionalidad de cancelar en editar notas + $('#botCancelarNotas').click(function(event){ + event.preventDefault(); + + $('#editorNotas').addClass('d-none'); + $('#textoNotas').removeClass('d-none'); + $('#botEditarNotas').removeClass('d-none'); + }); + + + /////////////////////////////////////////////// PENDIENTES /////////////////////////////////////////////// + + // Funcionalidad de buscar pendiente + $('#nombreFormPend').on('input', function(){ + + clearTimeout(temporizadorBusqueda); + let nombre = $('#nombreFormPend').val(); + if(nombre.length < 2){ + return; + } + + temporizadorBusqueda = setTimeout(function(){ + + $.ajax({ + method: "POST", + url: config.controlador, + dataType: "json", + data: { + [config.nombre]: nombre, + "orden": 'buscarApi' + }, + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + let html = resultadosApi(respuesta); + $('#resultadosApiPend').html(html); + } // Fin else + }) // Fin ajax + + },500); + + }); + + // Funcionalidad click en resultado Api pendiente + $('#modalPendiente').on("click",".resultadoApi", function(event){ + event.preventDefault(); + let idApi = $(this).data("id"); + + $.ajax({ + method: "POST", + url: config.controlador, + dataType: "json", + data:{ + "idApi": idApi, + "orden":"detallesApi" + } + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + contenidoSeleccionado = respuesta; + + if(config.nombreContenido == 'Serie' || config.nombreContenido == 'Temporada' || config.nombreContenido == 'Episodio'){ + let info = mostrarDetalles(contenidoSeleccionado, config.detallesSerie, 'posterSerie'); + $('#nuevosAgregarPend').html(info); + + let selector = mostrarSelectorTemporadas(contenidoSeleccionado); + $('#selectorSeriePend').html(selector); + + $('#nombreAgregarPend').text(contenidoSeleccionado['nombreSerie']); + + $('#selectorSeriePend').removeClass('d-none'); + $('#modal-dialog-Pend').addClass('modal-xl'); + $('#capaNuevosAgregarPend').addClass('col-md-6'); + }else{ + + let info = mostrarDetalles(contenidoSeleccionado, config.detallesInfo); + $('#nuevosAgregarPend').html(info); + + $('#nombreAgregarPend').text(contenidoSeleccionado[config.campos.nombre]); + + $('#pieAgregarPend').removeClass('d-none'); + $('#modal-dialog-Pend').addClass('modal-lg'); + } + + $('#contenidoBuscarPend').addClass('d-none'); + $('#contenidoAgregarPend').removeClass('d-none'); + + } // Fin else + }); // Fin ajax + }); + + // Funcionalidad de aceptar en agregar pendiente + $('#botAgregarPendAceptar').click(function(event){ + event.preventDefault(); + + let datos = { + orden: "agregarPend", + }; + + for(const [campoPOST, campoContenido] of Object.entries(config.camposBD)){ + datos[campoPOST] = contenidoSeleccionado[campoContenido]; + } + + $.ajax({ + method:"POST", + url: config.controlador, + dataType: "json", + data: datos + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + agregarHistorial('añadirPend', respuesta[config.idUsuarioContenido]); + tablaPendientes(); + + let modalPendiente = document.getElementById('modalPendiente'); + bootstrap.Modal.getInstance(modalPendiente).hide(); + + $.ajax({ + method: "POST", + url: config.controlador, + dataType: "json", + data: { + orden: 'descargarPoster', + [config.idContenido]: respuesta[config.idContenido], + [config.poster]: contenidoSeleccionado[config.poster] + } + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + } + }); + + } // Fin else + }).fail(function(jqXHR, textStatus, errorThrown) { + console.log("Error AJAX:", textStatus); + console.log("Error:", errorThrown); + console.log("Respuesta del servidor:", jqXHR.responseText); + }); // Fin ajax + }); + + // Funcionalidad de click de agregar en pendiente en tabla + $('#tablas').on('click', '.agregarPendTabla', function(event){ + event.preventDefault(); + + let id = $(this).data('id'); + + $('#nombreAgregar').text('Cargando...'); + + obtenerDetalles(id).then(function(respuesta){ + + let info = mostrarDetalles(respuesta[0], config.detalles); + $('#nuevosAgregar').html(info); + $('#nombreAgregar').text(respuesta[0][config.campos.nombre]); + + let form = mostrarFormAgregar(config.formAgregar); + $('#detallesFormAgregar').html(form); + + let hoy = new Date().toISOString().split('T')[0]; + $('#fechaFormAgregar').val(hoy); + }); + + $('#idFormAgregarPendTabla').val(id); + + $('#contenidoBuscar').addClass('d-none'); + $('#contenidoAgregar').removeClass('d-none'); + $('#formAgregar').removeClass('d-none'); + $('#pieAgregarPendTabla').removeClass('d-none'); + $('#modal-dialog-Agregar').addClass('modal-xl'); + + }); + + // Funcionalidad de aceptar en agregar pendiente en tabla + $('#botAgregarPendTablaAceptar').click(function(event){ + event.preventDefault(); + + let id = $('#idFormAgregarPendTabla').val(); + let rating = $('#ratingFormAgregar').val(); + let fav = $('#corazonFormAgregar').hasClass('bi-heart-fill') ? 1 : 0; + let notas = $('#notasFormAgregar').val(); + + let datos = { + [config.idUsuarioContenido]: id, + [config.rating]: rating, + [config.fav]: fav, + [config.notas]: notas, + "orden": 'agregarPendTabla' + } + + for(const campo of config.formAgregar){ + datos[campo.nombre] = $('#' + campo.id).val(); + } + + $.ajax({ + method: "POST", + url: config.controlador, + dataType: "json", + data: datos + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + agregarHistorial('añadir', id); + tablaGeneral(); + + let modalAgregar = document.getElementById('modalAgregar'); + bootstrap.Modal.getInstance(modalAgregar).hide(); + + } // Fin else + }); // Fin ajax + }); + + + //////////////////////////////////////////////// ELIMINAR //////////////////////////////////////////////// + + // Funcionalidad de eliminar + $('#tablas').on('click', '.eliminar', function(event){ + event.preventDefault(); + + let id = $(this).data('id'); + $('#idFormEliminar').val(id); + + // Ajax para comprobar el idPelicula de este idUsuarioContenido en usuariosxcontenidos + $.ajax({ + method: "POST", + url: config.controlador, + dataType: "json", + data: { + [config.idUsuarioContenido]: id, + "orden": 'comprobar' + }, + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + // Ajax para comprobar los datos de este idContenido + $.ajax({ + method: "POST", + url: config.controlador, + data: { + [config.idContenido]: respuesta[0][config.idContenido], + "orden": 'comprobarContenido' + }, + }).done(function(respuesta){ + respuesta=JSON.parse(respuesta); + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + if(respuesta[0][config.ano]){ + $('#eliminarModalLabel').html('¿EstÔ seguro de que quiere eliminar '+respuesta[0][config.nombre]+' ('+respuesta[0][config.ano]+')?'); + }else{ + $('#eliminarModalLabel').html('¿EstÔ seguro de que quiere eliminar '+respuesta[0][config.nombre]+'?'); + } + + } // Fin else + }); // Fin ajax + + } // Fin else + }); // Fin ajax + }); + + // Funcionalidad de aceptar en eliminar + $('#botFormEliminarAceptar').click(function(event){ + event.preventDefault(); + + let id = $('#idFormEliminar').val(); + agregarHistorial('eliminar', id); + + $.ajax({ + method: "POST", + url: config.controlador, + dataType: "json", + data: { + [config.idUsuarioContenido]: id, + "orden": 'eliminar' + }, + }).done(function(respuesta){ + if(respuesta.error){ + mostrarError(respuesta.error); + console.log(respuesta.error_tecnico); + }else{ + mostrarExito(respuesta.exito); + if(tablaActual=='pendientes'){ + tablaPendientes(); + }else{ + $('#idFormEliminar').val(''); + + window.tabla.deleteRow(id); + actualizarNumero(); + } + + let modalElemento = $('#modalEliminar'); + bootstrap.Modal.getInstance(modalElemento).hide(); + } // Fin else + }) // Fin ajax + }); + + + ///////////////////////////////////////////////// OTROS ////////////////////////////////////////////////// + + // Información + $('#tablas').on('click', '.info', function(event){ + event.preventDefault(); + + let id = $(this).data('id'); + + $('#contenidoBuscarPend').addClass('d-none'); + $('#contenidoAgregarPend').removeClass('d-none'); + $('#modal-dialog-Pend').addClass('modal-lg'); + $('#pendienteModalLabel').text('Información'); + $('#nombreAgregarPend').text('Cargando...'); + $('#contenidoAgregarPend').css('max-height', '80vh'); + $('#nuevosAgregarPend').html(''); + + obtenerDetalles(id).then(function(respuesta){ + let info = mostrarDetalles(respuesta[0], config.detallesInfo); + $('#nuevosAgregarPend').html(info); + $('#nombreAgregarPend').text(respuesta[0][config.campos.nombre]); + }); + + }); + + // Botones del apartado Series + $('#nuevosBotones').on('click', 'button', function(){ + + $('#nuevosBotones button').removeClass('active'); + $(this).addClass('active'); + + if($(this).attr('id') === 'botSeries'){ + config = contenidoConfig['serie']; + }else if($(this).attr('id') === 'botTemporadas'){ + config = contenidoConfig['temporada']; + }else if($(this).attr('id') === 'botEpisodios'){ + config = contenidoConfig['episodio']; + } + + tablaGeneral(); + }); + + // Movilidad de las estrellas de los formularios + $('form').on('mousemove', '.estrella', function(){ + + let estrella = $(this); + let valor = estrella.data('valor'); + + let mitad = this.getBoundingClientRect().left + this.offsetWidth / 2; + + let rating; + + if(event.clientX < mitad){ + rating = valor - 0.5; + }else{ + rating = valor; + } + + $('.estrella').each(function(){ + + let posicion = $(this).data('valor'); + + $(this).removeClass('bi-star bi-star-fill bi-star-half'); + + if(posicion <= Math.floor(rating)){ + $(this).addClass('bi-star-fill'); + } + else if(posicion == Math.ceil(rating) && rating % 1 != 0){ + $(this).addClass('bi-star-half'); + } + else{ + $(this).addClass('bi-star'); + } + + }); // Fin de la función de cada estrella + }); + + // Cargar historial al abrir panel + $('#panelHistorial').on('shown.bs.collapse', function(){ + mostrarHistorial(); + }); + + // Funcionalidad de X en menu + $(document).on('click', '#menu .close', function(event) { + event.preventDefault(); + $('body').removeClass('is-menu-visible'); + $('#menu').removeClass('visible'); + }); + + // Abrir modal buscar + $('#modalAgregar').on('shown.bs.modal', function () { + if (!$('#contenidoBuscar').hasClass('d-none')) { + $('#nombreFormBuscarApi').trigger('focus'); + } + }); + + // Abrir modal buscar pendiente + $('#modalPendiente').on('shown.bs.modal', function () { + if (!$('#contenidoBuscarPend').hasClass('d-none')) { + $('#nombreFormPend').trigger('focus'); + } + }); + + // Placeholder buscar + $('#cajaBusqueda').attr('placeholder', 'Buscar '+config.nombreContenido+'...'); + + // Texto en boton agregar + $('#botAgregar').text('Agregar ' + config.nombreContenido); + + // Títulos modales + $('#agregarModalLabel').text('Agregar '+config.nombreContenido); + $('#pendienteModalLabel').text('Agregar '+config.nombreContenido+' Pendiente'); + $('#notasModalLabel').text('Notas de '+config.nombreContenido); + $('#editarFechaModalLabel').text('Editar fecha de '+config.accionFecha); + + // Colores + $('#botAgregar').addClass(config.color); + $('.bi-star-fill').addClass(config.color); + $('.bi-star-half').addClass(config.color); + $('.bi-star').addClass(config.color); + $('.xModal').addClass(config.color); + $('#nombreAgregar').addClass(config.color); + $('#nombreAgregarPend').addClass(config.color); + $('#nombreNotas').addClass(config.color); + $('#estrellasEditar').addClass(config.color); + $('#botAgregarAceptar').addClass(config.colorBoton); + $('#botAgregarTemporadaAceptar').addClass(config.colorBoton); + $('#botAgregarEpisodioAceptar').addClass(config.colorBoton); + $('#botAgregarTemporadaPendAceptar').addClass(config.colorBoton); + $('#botAgregarEpisodioPendAceptar').addClass(config.colorBoton); + $('#botAgregarPendAceptar').addClass(config.colorBoton); + $('#botAgregarPendTablaAceptar').addClass(config.colorBoton); + $('#botFormEditarValAceptar').addClass(config.colorBoton); + $('#botFormEditarFechaAceptar').addClass(config.colorBoton); + $('#botFormEditarPlatAceptar').addClass(config.colorBoton); + $('#botFormEditarEstadoAceptar').addClass(config.colorBoton); + $('#botGuardarNotas').addClass(config.colorBoton); + $('#botEditarNotas').addClass(config.color); + $('#tablas').addClass(config.tabla); + + // Cerrar modales + $('.modal').on('hide.bs.modal', function(){ + document.activeElement.blur(); + + $('#nombreFormBuscarApi').val(''); + $('#nombreFormPend').val(''); + $('#resultadosApi').html(''); + $('#resultadosApiPend').html(''); + $('#contenidoBuscar').removeClass('d-none'); + $('#contenidoAgregar').addClass('d-none'); + $('#formAgregar').addClass('d-none'); + $('#contenidoBuscarPend').removeClass('d-none'); + $('#contenidoAgregarPend').addClass('d-none'); + $('#modal-dialog-Pend').removeClass('modal-lg'); + $('#pieAgregar').addClass('d-none'); + $('#pieAgregarEpisodio').addClass('d-none'); + $('#pieAgregarTemporada').addClass('d-none'); + $('#pieAgregarPend').addClass('d-none'); + $('#pieAgregarPendTabla').addClass('d-none'); + $('#pieAgregarEpisodioPend').addClass('d-none'); + $('#pieAgregarTemporadaPend').addClass('d-none'); + $('#modal-dialog-Agregar').removeClass('modal-xl'); + $('#modal-dialog-Pend').removeClass('modal-xl'); + $('#infoEstrellasAgregar').addClass('invisible'); + $('#pendienteModalLabel').text('Agregar '+config.nombreContenido+' Pendiente'); + $('#contenidoAgregarPend').css('max-height', ''); + + $('#editarFechaForm').addClass('d-none'); + $('#editarValForm').addClass('d-none'); + $('#editarPlataformaForm').addClass('d-none'); + $('#editarEstadoForm').addClass('d-none'); + $('#botVal').addClass('d-none'); + $('#botFecha').addClass('d-none'); + $('#botPlat').addClass('d-none'); + $('#botEstado').addClass('d-none'); + + $('#editorNotas').addClass('d-none'); + $('#textoNotas').removeClass('d-none'); + $('#botEditarNotas').removeClass('d-none'); + + if($('#corazonFormAgregar').hasClass('bi-heart-fill')){ + $('#corazonFormAgregar').removeClass('bi-heart-fill').addClass('bi-heart'); + } + $('#ratingFormAgregar').val(''); + $('#notasFormAgregar').val(''); + + if(configAnterior){ + config = configAnterior; + configAnterior = null; + } + }); + + // Reposicionar tabla + window.addEventListener("resize", function(){ + if(window.tabla){ + window.tabla.redraw(true); + } + }); + +}) // Fin document.ready + + + diff --git a/js/funciones.js b/js/funciones.js new file mode 100644 index 0000000..0bd0296 --- /dev/null +++ b/js/funciones.js @@ -0,0 +1,1276 @@ +// TABLAS + +function crearTabla(lista, texto){ + + let titulo = '
'; + titulo += '

'+texto +'

'; + if(lista.length == 1){ + titulo+= '

'+lista.length+' Registro

'; + }else{ + titulo+= '

'+lista.length+' Registros

'; + } + $("#tituloTablas").html(titulo); + + + window.tabla = new Tabulator("#tablas", { + data:lista, + index: config.idUsuarioContenido, + locale: "es", + langs:{ + "es":{ + "pagination":{ + "page_size":"Filas:", + "page_title":"Mostrar pÔgina", + "first":"<<", + "first_title":"Primera pÔgina", + "last":">>", + "last_title":"Última pÔgina", + "prev":"<", + "prev_title":"PÔgina anterior", + "next":">", + "next_title":"PÔgina siguiente", + "all":"Todo", + "counter":{ + "showing":"Mostrando", + "of":"de", + "rows":"filas", + "pages":"pÔginas" + } + }, + "headerFilters":{ + "default":"filtrar..." + } + } + }, + placeholder: '
No hay registros
', + pagination: true, + paginationSize: config.filas, + paginationSizeSelector: [config.filas, 25, 50, 100, 500], + movableColumns: true, + layout:"fitColumns", + responsiveLayout:false, + columnDefaults:{ + resizable:false, + headerSort:false, + headerHozAlign:"center", + hozAlign:"center" + }, + headerElement: '

'+texto+'

', + columns:config.columns + }); + + return window.tabla; +} // Fin crearTabla() + +function celdaNombre(cell){ + let datos = cell.getRow().getData(); + + if(datos[config.pendiente]==1){ + let codigo = '
(Pendiente)
'+datos[config.nombre]+'
'; + + codigo += '
'; + codigo +='