diff --git a/.gitignore b/.gitignore index 71f2920..42e7d3a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,11 @@ +.gitignore .DS_Store .vscode/ env/ -__pycache__/ -rental/__pycache__/ -# rental/migrations/ -villafleurie/__pycache__/ -villafleurie/staticfiles/ +**/__pycache__ villafleurie/static_files/ rental/client_secrets.json token.pickle *.env -*.tar debug.log rental/templates/rental/mails \ No newline at end of file diff --git a/nginx/Dockerfile b/nginx/Dockerfile index 0f30364..c88cd07 100644 --- a/nginx/Dockerfile +++ b/nginx/Dockerfile @@ -1,5 +1,3 @@ FROM nginx:latest - RUN rm /etc/nginx/conf.d/default.conf - COPY nginx/villafleurie.conf /etc/nginx/conf.d/ \ No newline at end of file diff --git a/rental/bookings.py b/rental/bookings.py index ca0832b..8922212 100644 --- a/rental/bookings.py +++ b/rental/bookings.py @@ -13,19 +13,18 @@ from villafleurie.settings import BASE_DIR def build_calendar_api_service(): """ Build Google Calendar API service and returns calendar list and service """ + creds = None - # If modifying these scopes, delete the file token.pickle. + SCOPES = [ 'https://www.googleapis.com/auth/calendar', 'https://www.googleapis.com/auth/calendar.events' ] - # The file token.pickle stores the user's access and refresh tokens, and is - # created automatically when the authorization flow completes for the first - # time. + if os.path.exists('token.pickle'): with open('token.pickle', 'rb') as token: creds = pickle.load(token) - # If there are no (valid) credentials available, let the user log in. + if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) @@ -34,14 +33,16 @@ def build_calendar_api_service(): flow = InstalledAppFlow.from_client_secrets_file( SECRETS, scopes=SCOPES, redirect_uri="http://localhost:8080/") creds = flow.run_local_server() - # Save the credentials for the next run + with open('token.pickle', 'wb') as token: pickle.dump(creds, token) + service = build('calendar', 'v3', credentials=creds) calendars = { 'T2': "burik7aclvhc7vsboh06c179uo@group.calendar.google.com", 'T3': "fu7h30p0gk4a2p4nvo7nsbgpok@group.calendar.google.com" } + return service, calendars @@ -55,6 +56,7 @@ def get_calendar_reservations(place): orderBy='startTime' ).execute() events = events_result.get('items', []) + if not events: print('No upcoming events found.') else: @@ -65,6 +67,7 @@ def get_calendar_reservations(place): 'start': event['start'].get('dateTime', event['start'].get('date')).strip(), 'end': event['end'].get('dateTime', event['end'].get('date')).strip() } + return reservation @@ -72,6 +75,7 @@ def synchronize_calendars(place): """ Get a complete list of existing bookings in calendar Creates reservation if not in db, update if already in db Delete from db reservation deleted from cal """ + reservation = get_calendar_reservations(place) place = get_object_or_404(Place, name=place.name) price = get_reservation_price( @@ -81,6 +85,7 @@ def synchronize_calendars(place): ) start = reservation['start'] end = reservation['end'] + guest = Guest.objects.filter(name=reservation['guest']) if not guest.exists(): guest = Guest.objects.create(name=reservation['guest']) @@ -108,17 +113,21 @@ def synchronize_calendars(place): def get_bookings(place): """ Synchronize with Master calendar via a call to synchronize_calendar Returns a list of all related place reservations """ + synchronize_calendars(place) booked_dates = Reservation.objects.filter(place=place) + return [booking for booking in booked_dates] def check_availability(place, start_date, end_date): """ check if the related place is available during a given period """ + bookings = get_bookings(place) for booking in bookings: if (booking.start <= start_date <= booking.end) or (booking.start <= end_date <= booking.end): return False + return True @@ -142,7 +151,3 @@ def update_calendar(reservation): }, } ).execute() - - -# if __name__ == "__main__": -# update_calendar(reservation) diff --git a/rental/enums.py b/rental/enums.py new file mode 100644 index 0000000..c175985 --- /dev/null +++ b/rental/enums.py @@ -0,0 +1,8 @@ +from django.db import models +from django.utils.translation import gettext_lazy as _ + + +class PlacesNames(models.TextChoices): + + T2 = "T2", _("T2") + T3 = "T3", _("T3") diff --git a/rental/forms.py b/rental/forms.py index 734e185..399a58e 100644 --- a/rental/forms.py +++ b/rental/forms.py @@ -1,9 +1,10 @@ from django import forms from .models import Reservation, Place, Guest +from .enums import PlaceNames class ReservationForm(forms.Form): - PLACES = (('T2', 'T2'), ('T3', 'T3'),) + name = forms.CharField( label="", max_length=100, @@ -13,6 +14,7 @@ class ReservationForm(forms.Form): 'placeholder': 'Nom *' }), required=True) + email = forms.EmailField( label='', widget=forms.EmailInput(attrs={ @@ -21,6 +23,7 @@ class ReservationForm(forms.Form): }), required=True ) + phone = forms.CharField( label='', max_length=30, @@ -30,12 +33,16 @@ class ReservationForm(forms.Form): 'placeholder': 'Téléphone *' }), required=True) + place = forms.ChoiceField( label='', widget=forms.Select( attrs={'class': 'form-control form-control-lg form-control-a'}), required=True, - choices=PLACES) + choices=PlacesNames.choices, + default=PlacesNames.T2 + ) + message = forms.CharField( label='', # max_length=100, @@ -47,6 +54,7 @@ class ReservationForm(forms.Form): 'placeholder': 'Message *' }), required=True) + start = forms.DateField( label='', input_formats=['%d/%m/%Y'], @@ -56,6 +64,7 @@ class ReservationForm(forms.Form): 'class': 'form-control form-control-lg form-control-a', 'placeholder': '01/01/2020 *'}), required=True) + end = forms.DateField( label='', input_formats=['%d/%m/%Y'], @@ -66,6 +75,7 @@ class ReservationForm(forms.Form): class ContactForm(forms.Form): + name = forms.CharField( label='', widget=forms.TextInput(attrs={ @@ -74,6 +84,7 @@ class ContactForm(forms.Form): }), required=True, ) + email = forms.EmailField( label='', widget=forms.EmailInput(attrs={ @@ -82,6 +93,7 @@ class ContactForm(forms.Form): }), required=True, ) + subject = forms.CharField( label='', widget=forms.TextInput(attrs={ @@ -90,6 +102,7 @@ class ContactForm(forms.Form): }), required=True, ) + message = forms.CharField( label='', # max_length=100, diff --git a/rental/pricing.py b/rental/pricing.py index 5b38d17..e598506 100644 --- a/rental/pricing.py +++ b/rental/pricing.py @@ -3,11 +3,13 @@ from datetime import datetime def get_reservation_price(place, start, end): """ Compute booking price as a function of place and dates """ + if type(start) == str: start = datetime.strptime(start, '%Y-%m-%d') if type(end) == str: end = datetime.strptime(end, '%Y-%m-%d') nights = (end - start).days + return place.price * nights diff --git a/rental/static/rental/img/about-1.jpg b/rental/static/rental/img/about-1.jpg index 8e97a84..8bb0f1b 100644 Binary files a/rental/static/rental/img/about-1.jpg and b/rental/static/rental/img/about-1.jpg differ diff --git a/rental/static/rental/img/about-2.jpg b/rental/static/rental/img/about-2.jpg index 8bb0f1b..8e61843 100644 Binary files a/rental/static/rental/img/about-2.jpg and b/rental/static/rental/img/about-2.jpg differ diff --git a/rental/static/rental/img/about-22.jpg b/rental/static/rental/img/about-22.jpg deleted file mode 100644 index a107d41..0000000 Binary files a/rental/static/rental/img/about-22.jpg and /dev/null differ diff --git a/rental/static/rental/img/agent-1.jpg b/rental/static/rental/img/agent-1.jpg index de23a58..88052c5 100644 Binary files a/rental/static/rental/img/agent-1.jpg and b/rental/static/rental/img/agent-1.jpg differ diff --git a/rental/static/rental/img/agent-2.jpg b/rental/static/rental/img/agent-2.jpg deleted file mode 100644 index c183bd5..0000000 Binary files a/rental/static/rental/img/agent-2.jpg and /dev/null differ diff --git a/rental/static/rental/img/agent-3.jpg b/rental/static/rental/img/agent-3.jpg deleted file mode 100644 index 14e5c58..0000000 Binary files a/rental/static/rental/img/agent-3.jpg and /dev/null differ diff --git a/rental/static/rental/img/agent-4.jpg b/rental/static/rental/img/agent-4.jpg deleted file mode 100644 index 88052c5..0000000 Binary files a/rental/static/rental/img/agent-4.jpg and /dev/null differ diff --git a/rental/static/rental/img/agent-44.jpg b/rental/static/rental/img/agent-44.jpg deleted file mode 100644 index 40cefc6..0000000 Binary files a/rental/static/rental/img/agent-44.jpg and /dev/null differ diff --git a/rental/static/rental/img/agent-5.jpg b/rental/static/rental/img/agent-5.jpg deleted file mode 100644 index a03e9ef..0000000 Binary files a/rental/static/rental/img/agent-5.jpg and /dev/null differ diff --git a/rental/static/rental/img/agent-6.jpg b/rental/static/rental/img/agent-6.jpg deleted file mode 100644 index 3be6530..0000000 Binary files a/rental/static/rental/img/agent-6.jpg and /dev/null differ diff --git a/rental/static/rental/img/agent-7.jpg b/rental/static/rental/img/agent-7.jpg deleted file mode 100644 index fe1f149..0000000 Binary files a/rental/static/rental/img/agent-7.jpg and /dev/null differ diff --git a/rental/static/rental/img/author-1.jpg b/rental/static/rental/img/author-1.jpg deleted file mode 100644 index 4bf1a73..0000000 Binary files a/rental/static/rental/img/author-1.jpg and /dev/null differ diff --git a/rental/static/rental/img/author-2.jpg b/rental/static/rental/img/author-2.jpg deleted file mode 100644 index 8a3eed7..0000000 Binary files a/rental/static/rental/img/author-2.jpg and /dev/null differ diff --git a/rental/static/rental/img/mini-testimonial-1.jpg b/rental/static/rental/img/mini-testimonial-1.jpg deleted file mode 100644 index af64bdb..0000000 Binary files a/rental/static/rental/img/mini-testimonial-1.jpg and /dev/null differ diff --git a/rental/static/rental/img/mini-testimonial-2.jpg b/rental/static/rental/img/mini-testimonial-2.jpg deleted file mode 100644 index b3c8757..0000000 Binary files a/rental/static/rental/img/mini-testimonial-2.jpg and /dev/null differ diff --git a/rental/static/rental/img/plan2.jpg b/rental/static/rental/img/plan2.jpg deleted file mode 100644 index e2cdadd..0000000 Binary files a/rental/static/rental/img/plan2.jpg and /dev/null differ diff --git a/rental/static/rental/img/post-1.jpg b/rental/static/rental/img/post-1.jpg deleted file mode 100644 index e337a28..0000000 Binary files a/rental/static/rental/img/post-1.jpg and /dev/null differ diff --git a/rental/static/rental/img/post-2.jpg b/rental/static/rental/img/post-2.jpg deleted file mode 100644 index f8950b9..0000000 Binary files a/rental/static/rental/img/post-2.jpg and /dev/null differ diff --git a/rental/static/rental/img/post-3.jpg b/rental/static/rental/img/post-3.jpg deleted file mode 100644 index b50f0e7..0000000 Binary files a/rental/static/rental/img/post-3.jpg and /dev/null differ diff --git a/rental/static/rental/img/post-4.jpg b/rental/static/rental/img/post-4.jpg deleted file mode 100644 index b3b79ee..0000000 Binary files a/rental/static/rental/img/post-4.jpg and /dev/null differ diff --git a/rental/static/rental/img/post-5.jpg b/rental/static/rental/img/post-5.jpg deleted file mode 100644 index d0002f4..0000000 Binary files a/rental/static/rental/img/post-5.jpg and /dev/null differ diff --git a/rental/static/rental/img/post-6.jpg b/rental/static/rental/img/post-6.jpg deleted file mode 100644 index ae30037..0000000 Binary files a/rental/static/rental/img/post-6.jpg and /dev/null differ diff --git a/rental/static/rental/img/post-7.jpg b/rental/static/rental/img/post-7.jpg deleted file mode 100644 index fa91654..0000000 Binary files a/rental/static/rental/img/post-7.jpg and /dev/null differ diff --git a/rental/static/rental/img/post-single-1.jpg b/rental/static/rental/img/post-single-1.jpg deleted file mode 100644 index 0a61c64..0000000 Binary files a/rental/static/rental/img/post-single-1.jpg and /dev/null differ diff --git a/rental/static/rental/img/post-single-2.jpg b/rental/static/rental/img/post-single-2.jpg deleted file mode 100644 index 12837f4..0000000 Binary files a/rental/static/rental/img/post-single-2.jpg and /dev/null differ diff --git a/rental/static/rental/img/property-1.jpg b/rental/static/rental/img/property-1.jpg deleted file mode 100644 index fe108e7..0000000 Binary files a/rental/static/rental/img/property-1.jpg and /dev/null differ diff --git a/rental/static/rental/img/property-10.jpg b/rental/static/rental/img/property-10.jpg deleted file mode 100644 index 7f48a4c..0000000 Binary files a/rental/static/rental/img/property-10.jpg and /dev/null differ diff --git a/rental/static/rental/img/property-2.jpg b/rental/static/rental/img/property-2.jpg deleted file mode 100644 index c0cb897..0000000 Binary files a/rental/static/rental/img/property-2.jpg and /dev/null differ diff --git a/rental/static/rental/img/property-3.jpg b/rental/static/rental/img/property-3.jpg deleted file mode 100644 index 9f477c2..0000000 Binary files a/rental/static/rental/img/property-3.jpg and /dev/null differ diff --git a/rental/static/rental/img/property-4.jpg b/rental/static/rental/img/property-4.jpg deleted file mode 100644 index 02beb41..0000000 Binary files a/rental/static/rental/img/property-4.jpg and /dev/null differ diff --git a/rental/static/rental/img/property-5.jpg b/rental/static/rental/img/property-5.jpg deleted file mode 100644 index d102634..0000000 Binary files a/rental/static/rental/img/property-5.jpg and /dev/null differ diff --git a/rental/static/rental/img/property-6.jpg b/rental/static/rental/img/property-6.jpg deleted file mode 100644 index 48c5071..0000000 Binary files a/rental/static/rental/img/property-6.jpg and /dev/null differ diff --git a/rental/static/rental/img/property-7.jpg b/rental/static/rental/img/property-7.jpg deleted file mode 100644 index aa91dd5..0000000 Binary files a/rental/static/rental/img/property-7.jpg and /dev/null differ diff --git a/rental/static/rental/img/property-8.jpg b/rental/static/rental/img/property-8.jpg deleted file mode 100644 index 7f2f226..0000000 Binary files a/rental/static/rental/img/property-8.jpg and /dev/null differ diff --git a/rental/static/rental/img/property-9.jpg b/rental/static/rental/img/property-9.jpg deleted file mode 100644 index 04660b7..0000000 Binary files a/rental/static/rental/img/property-9.jpg and /dev/null differ diff --git a/rental/static/rental/img/slide-1.jpg b/rental/static/rental/img/slide-1.jpg deleted file mode 100644 index cd923f7..0000000 Binary files a/rental/static/rental/img/slide-1.jpg and /dev/null differ diff --git a/rental/static/rental/img/slide-2.jpg b/rental/static/rental/img/slide-2.jpg deleted file mode 100644 index 7bbfd3a..0000000 Binary files a/rental/static/rental/img/slide-2.jpg and /dev/null differ diff --git a/rental/static/rental/img/slide-3.jpg b/rental/static/rental/img/slide-3.jpg deleted file mode 100644 index 64b743c..0000000 Binary files a/rental/static/rental/img/slide-3.jpg and /dev/null differ diff --git a/rental/static/rental/img/slide-about-11.jpg b/rental/static/rental/img/slide-about-11.jpg deleted file mode 100644 index 4c740b3..0000000 Binary files a/rental/static/rental/img/slide-about-11.jpg and /dev/null differ diff --git a/rental/static/rental/img/testimonial-1.jpg b/rental/static/rental/img/testimonial-1.jpg deleted file mode 100644 index a4b884e..0000000 Binary files a/rental/static/rental/img/testimonial-1.jpg and /dev/null differ diff --git a/rental/static/rental/img/testimonial-2.jpg b/rental/static/rental/img/testimonial-2.jpg deleted file mode 100644 index 0aae56f..0000000 Binary files a/rental/static/rental/img/testimonial-2.jpg and /dev/null differ diff --git a/rental/static/rental/lib/popper/popper.min.js b/rental/static/rental/lib/popper/popper.min.js index 9b7dbeb..27ea858 100644 --- a/rental/static/rental/lib/popper/popper.min.js +++ b/rental/static/rental/lib/popper/popper.min.js @@ -1,5 +1,1198 @@ /* Copyright (C) Federico Zivolo 2018 Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT). - */(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function e(e){return e&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=e.ownerDocument.defaultView,n=o.getComputedStyle(e,null);return t?n[t]:n}function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e)return document.body;switch(e.nodeName){case'HTML':case'BODY':return e.ownerDocument.body;case'#document':return e.body;}var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll|overlay)/.test(r+s+p)?e:n(o(e))}function r(e){return 11===e?pe:10===e?se:pe||se}function p(e){if(!e)return document.documentElement;for(var o=r(10)?document.body:null,n=e.offsetParent||null;n===o&&e.nextElementSibling;)n=(e=e.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TH','TD','TABLE'].indexOf(n.nodeName)&&'static'===t(n,'position')?p(n):n:e?e.ownerDocument.documentElement:document.documentElement}function s(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||p(e.firstElementChild)===e)}function d(e){return null===e.parentNode?e:d(e.parentNode)}function a(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,n=o?e:t,i=o?t:e,r=document.createRange();r.setStart(n,0),r.setEnd(i,0);var l=r.commonAncestorContainer;if(e!==l&&t!==l||n.contains(i))return s(l)?l:p(l);var f=d(e);return f.host?a(f.host,t):a(e,d(t).host)}function l(e){var t=1=o.clientWidth&&n>=o.clientHeight}),l=0a[e]&&!t.escapeWithReference&&(n=Q(f[o],a[e]-('right'===e?f.width:f.height))),le({},o,n)}};return l.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';f=fe({},f,m[t](e))}),e.offsets.popper=f,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,n=t.reference,i=e.placement.split('-')[0],r=Z,p=-1!==['top','bottom'].indexOf(i),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]r(n[s])&&(e.offsets.popper[d]=r(n[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,o){var n;if(!K(e.instance.modifiers,'arrow','keepTogether'))return e;var i=o.element;if('string'==typeof i){if(i=e.instance.popper.querySelector(i),!i)return e;}else if(!e.instance.popper.contains(i))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var r=e.placement.split('-')[0],p=e.offsets,s=p.popper,d=p.reference,a=-1!==['left','right'].indexOf(r),l=a?'height':'width',f=a?'Top':'Left',m=f.toLowerCase(),h=a?'left':'top',c=a?'bottom':'right',u=S(i)[l];d[c]-us[c]&&(e.offsets.popper[m]+=d[m]+u-s[c]),e.offsets.popper=g(e.offsets.popper);var b=d[m]+d[l]/2-u/2,w=t(e.instance.popper),y=parseFloat(w['margin'+f],10),E=parseFloat(w['border'+f+'Width'],10),v=b-e.offsets.popper[m]-y-E;return v=ee(Q(s[l]-u,v),0),e.arrowElement=i,e.offsets.arrow=(n={},le(n,m,$(v)),le(n,h,''),n),e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(W(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=v(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement,e.positionFixed),n=e.placement.split('-')[0],i=T(n),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case ge.FLIP:p=[n,i];break;case ge.CLOCKWISE:p=G(n);break;case ge.COUNTERCLOCKWISE:p=G(n,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(n!==s||p.length===d+1)return e;n=e.placement.split('-')[0],i=T(n);var a=e.offsets.popper,l=e.offsets.reference,f=Z,m='left'===n&&f(a.right)>f(l.left)||'right'===n&&f(a.left)f(l.top)||'bottom'===n&&f(a.top)f(o.right),g=f(a.top)f(o.bottom),b='left'===n&&h||'right'===n&&c||'top'===n&&g||'bottom'===n&&u,w=-1!==['top','bottom'].indexOf(n),y=!!t.flipVariations&&(w&&'start'===r&&h||w&&'end'===r&&c||!w&&'start'===r&&g||!w&&'end'===r&&u);(m||b||y)&&(e.flipped=!0,(m||b)&&(n=p[d+1]),y&&(r=z(r)),e.placement=n+(r?'-'+r:''),e.offsets.popper=fe({},e.offsets.popper,D(e.instance.popper,e.offsets.reference,e.placement)),e=P(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport'},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],n=e.offsets,i=n.popper,r=n.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return i[p?'left':'top']=r[o]-(s?i[p?'width':'height']:0),e.placement=T(t),e.offsets.popper=g(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!K(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=C(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottomo.right||t.top>o.bottom||t.rightwindow.devicePixelRatio||!me),c='bottom'===o?'top':'bottom',g='right'===n?'left':'right',b=H('transform');if(d='bottom'==c?'HTML'===l.nodeName?-l.clientHeight+h.bottom:-f.height+h.bottom:h.top,s='right'==g?'HTML'===l.nodeName?-l.clientWidth+h.right:-f.width+h.right:h.left,a&&b)m[b]='translate3d('+s+'px, '+d+'px, 0)',m[c]=0,m[g]=0,m.willChange='transform';else{var w='bottom'==c?-1:1,y='right'==g?-1:1;m[c]=d*w,m[g]=s*y,m.willChange=c+', '+g}var E={"x-placement":e.placement};return e.attributes=fe({},E,e.attributes),e.styles=fe({},m,e.styles),e.arrowStyles=fe({},e.offsets.arrow,e.arrowStyles),e},gpuAcceleration:!0,x:'bottom',y:'right'},applyStyle:{order:900,enabled:!0,fn:function(e){return j(e.instance.popper,e.styles),V(e.instance.popper,e.attributes),e.arrowElement&&Object.keys(e.arrowStyles).length&&j(e.arrowElement,e.arrowStyles),e},onLoad:function(e,t,o,n,i){var r=L(i,t,e,o.positionFixed),p=O(o.placement,r,t,e,o.modifiers.flip.boundariesElement,o.modifiers.flip.padding);return t.setAttribute('x-placement',p),j(t,{position:o.positionFixed?'fixed':'absolute'}),o},gpuAcceleration:void 0}}},ue}); -//# sourceMappingURL=popper.min.js.map + */ (function( + e, + t +) { + "object" == typeof exports && "undefined" != typeof module + ? (module.exports = t()) + : "function" == typeof define && define.amd + ? define(t) + : (e.Popper = t()); +})(this, function() { + "use strict"; + function e(e) { + return e && "[object Function]" === {}.toString.call(e); + } + function t(e, t) { + if (1 !== e.nodeType) return []; + var o = e.ownerDocument.defaultView, + n = o.getComputedStyle(e, null); + return t ? n[t] : n; + } + function o(e) { + return "HTML" === e.nodeName ? e : e.parentNode || e.host; + } + function n(e) { + if (!e) return document.body; + switch (e.nodeName) { + case "HTML": + case "BODY": + return e.ownerDocument.body; + case "#document": + return e.body; + } + var i = t(e), + r = i.overflow, + p = i.overflowX, + s = i.overflowY; + return /(auto|scroll|overlay)/.test(r + s + p) ? e : n(o(e)); + } + function r(e) { + return 11 === e ? pe : 10 === e ? se : pe || se; + } + function p(e) { + if (!e) return document.documentElement; + for ( + var o = r(10) ? document.body : null, n = e.offsetParent || null; + n === o && e.nextElementSibling; + + ) + n = (e = e.nextElementSibling).offsetParent; + var i = n && n.nodeName; + return i && "BODY" !== i && "HTML" !== i + ? -1 !== ["TH", "TD", "TABLE"].indexOf(n.nodeName) && + "static" === t(n, "position") + ? p(n) + : n + : e + ? e.ownerDocument.documentElement + : document.documentElement; + } + function s(e) { + var t = e.nodeName; + return "BODY" !== t && ("HTML" === t || p(e.firstElementChild) === e); + } + function d(e) { + return null === e.parentNode ? e : d(e.parentNode); + } + function a(e, t) { + if (!e || !e.nodeType || !t || !t.nodeType) return document.documentElement; + var o = e.compareDocumentPosition(t) & Node.DOCUMENT_POSITION_FOLLOWING, + n = o ? e : t, + i = o ? t : e, + r = document.createRange(); + r.setStart(n, 0), r.setEnd(i, 0); + var l = r.commonAncestorContainer; + if ((e !== l && t !== l) || n.contains(i)) return s(l) ? l : p(l); + var f = d(e); + return f.host ? a(f.host, t) : a(e, d(t).host); + } + function l(e) { + var t = + 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : "top", + o = "top" === t ? "scrollTop" : "scrollLeft", + n = e.nodeName; + if ("BODY" === n || "HTML" === n) { + var i = e.ownerDocument.documentElement, + r = e.ownerDocument.scrollingElement || i; + return r[o]; + } + return e[o]; + } + function f(e, t) { + var o = 2 < arguments.length && void 0 !== arguments[2] && arguments[2], + n = l(t, "top"), + i = l(t, "left"), + r = o ? -1 : 1; + return ( + (e.top += n * r), + (e.bottom += n * r), + (e.left += i * r), + (e.right += i * r), + e + ); + } + function m(e, t) { + var o = "x" === t ? "Left" : "Top", + n = "Left" == o ? "Right" : "Bottom"; + return ( + parseFloat(e["border" + o + "Width"], 10) + + parseFloat(e["border" + n + "Width"], 10) + ); + } + function h(e, t, o, n) { + return ee( + t["offset" + e], + t["scroll" + e], + o["client" + e], + o["offset" + e], + o["scroll" + e], + r(10) + ? parseInt(o["offset" + e]) + + parseInt(n["margin" + ("Height" === e ? "Top" : "Left")]) + + parseInt(n["margin" + ("Height" === e ? "Bottom" : "Right")]) + : 0 + ); + } + function c(e) { + var t = e.body, + o = e.documentElement, + n = r(10) && getComputedStyle(o); + return { height: h("Height", t, o, n), width: h("Width", t, o, n) }; + } + function g(e) { + return fe({}, e, { right: e.left + e.width, bottom: e.top + e.height }); + } + function u(e) { + var o = {}; + try { + if (r(10)) { + o = e.getBoundingClientRect(); + var n = l(e, "top"), + i = l(e, "left"); + (o.top += n), (o.left += i), (o.bottom += n), (o.right += i); + } else o = e.getBoundingClientRect(); + } catch (t) {} + var p = { + left: o.left, + top: o.top, + width: o.right - o.left, + height: o.bottom - o.top + }, + s = "HTML" === e.nodeName ? c(e.ownerDocument) : {}, + d = s.width || e.clientWidth || p.right - p.left, + a = s.height || e.clientHeight || p.bottom - p.top, + f = e.offsetWidth - d, + h = e.offsetHeight - a; + if (f || h) { + var u = t(e); + (f -= m(u, "x")), (h -= m(u, "y")), (p.width -= f), (p.height -= h); + } + return g(p); + } + function b(e, o) { + var i = 2 < arguments.length && void 0 !== arguments[2] && arguments[2], + p = r(10), + s = "HTML" === o.nodeName, + d = u(e), + a = u(o), + l = n(e), + m = t(o), + h = parseFloat(m.borderTopWidth, 10), + c = parseFloat(m.borderLeftWidth, 10); + i && s && ((a.top = ee(a.top, 0)), (a.left = ee(a.left, 0))); + var b = g({ + top: d.top - a.top - h, + left: d.left - a.left - c, + width: d.width, + height: d.height + }); + if (((b.marginTop = 0), (b.marginLeft = 0), !p && s)) { + var w = parseFloat(m.marginTop, 10), + y = parseFloat(m.marginLeft, 10); + (b.top -= h - w), + (b.bottom -= h - w), + (b.left -= c - y), + (b.right -= c - y), + (b.marginTop = w), + (b.marginLeft = y); + } + return ( + (p && !i ? o.contains(l) : o === l && "BODY" !== l.nodeName) && + (b = f(b, o)), + b + ); + } + function w(e) { + var t = 1 < arguments.length && void 0 !== arguments[1] && arguments[1], + o = e.ownerDocument.documentElement, + n = b(e, o), + i = ee(o.clientWidth, window.innerWidth || 0), + r = ee(o.clientHeight, window.innerHeight || 0), + p = t ? 0 : l(o), + s = t ? 0 : l(o, "left"), + d = { + top: p - n.top + n.marginTop, + left: s - n.left + n.marginLeft, + width: i, + height: r + }; + return g(d); + } + function y(e) { + var n = e.nodeName; + return "BODY" === n || "HTML" === n + ? !1 + : "fixed" === t(e, "position") || y(o(e)); + } + function E(e) { + if (!e || !e.parentElement || r()) return document.documentElement; + for (var o = e.parentElement; o && "none" === t(o, "transform"); ) + o = o.parentElement; + return o || document.documentElement; + } + function v(e, t, i, r) { + var p = 4 < arguments.length && void 0 !== arguments[4] && arguments[4], + s = { top: 0, left: 0 }, + d = p ? E(e) : a(e, t); + if ("viewport" === r) s = w(d, p); + else { + var l; + "scrollParent" === r + ? ((l = n(o(t))), + "BODY" === l.nodeName && (l = e.ownerDocument.documentElement)) + : "window" === r + ? (l = e.ownerDocument.documentElement) + : (l = r); + var f = b(l, d, p); + if ("HTML" === l.nodeName && !y(d)) { + var m = c(e.ownerDocument), + h = m.height, + g = m.width; + (s.top += f.top - f.marginTop), + (s.bottom = h + f.top), + (s.left += f.left - f.marginLeft), + (s.right = g + f.left); + } else s = f; + } + i = i || 0; + var u = "number" == typeof i; + return ( + (s.left += u ? i : i.left || 0), + (s.top += u ? i : i.top || 0), + (s.right -= u ? i : i.right || 0), + (s.bottom -= u ? i : i.bottom || 0), + s + ); + } + function x(e) { + var t = e.width, + o = e.height; + return t * o; + } + function O(e, t, o, n, i) { + var r = 5 < arguments.length && void 0 !== arguments[5] ? arguments[5] : 0; + if (-1 === e.indexOf("auto")) return e; + var p = v(o, n, r, i), + s = { + top: { width: p.width, height: t.top - p.top }, + right: { width: p.right - t.right, height: p.height }, + bottom: { width: p.width, height: p.bottom - t.bottom }, + left: { width: t.left - p.left, height: p.height } + }, + d = Object.keys(s) + .map(function(e) { + return fe({ key: e }, s[e], { area: x(s[e]) }); + }) + .sort(function(e, t) { + return t.area - e.area; + }), + a = d.filter(function(e) { + var t = e.width, + n = e.height; + return t >= o.clientWidth && n >= o.clientHeight; + }), + l = 0 < a.length ? a[0].key : d[0].key, + f = e.split("-")[1]; + return l + (f ? "-" + f : ""); + } + function L(e, t, o) { + var n = + 3 < arguments.length && void 0 !== arguments[3] ? arguments[3] : null, + i = n ? E(t) : a(t, o); + return b(o, i, n); + } + function S(e) { + var t = e.ownerDocument.defaultView, + o = t.getComputedStyle(e), + n = parseFloat(o.marginTop || 0) + parseFloat(o.marginBottom || 0), + i = parseFloat(o.marginLeft || 0) + parseFloat(o.marginRight || 0), + r = { width: e.offsetWidth + i, height: e.offsetHeight + n }; + return r; + } + function T(e) { + var t = { left: "right", right: "left", bottom: "top", top: "bottom" }; + return e.replace(/left|right|bottom|top/g, function(e) { + return t[e]; + }); + } + function D(e, t, o) { + o = o.split("-")[0]; + var n = S(e), + i = { width: n.width, height: n.height }, + r = -1 !== ["right", "left"].indexOf(o), + p = r ? "top" : "left", + s = r ? "left" : "top", + d = r ? "height" : "width", + a = r ? "width" : "height"; + return ( + (i[p] = t[p] + t[d] / 2 - n[d] / 2), + (i[s] = o === s ? t[s] - n[a] : t[T(s)]), + i + ); + } + function C(e, t) { + return Array.prototype.find ? e.find(t) : e.filter(t)[0]; + } + function N(e, t, o) { + if (Array.prototype.findIndex) + return e.findIndex(function(e) { + return e[t] === o; + }); + var n = C(e, function(e) { + return e[t] === o; + }); + return e.indexOf(n); + } + function P(t, o, n) { + var i = void 0 === n ? t : t.slice(0, N(t, "name", n)); + return ( + i.forEach(function(t) { + t["function"] && + console.warn("`modifier.function` is deprecated, use `modifier.fn`!"); + var n = t["function"] || t.fn; + t.enabled && + e(n) && + ((o.offsets.popper = g(o.offsets.popper)), + (o.offsets.reference = g(o.offsets.reference)), + (o = n(o, t))); + }), + o + ); + } + function k() { + if (!this.state.isDestroyed) { + var e = { + instance: this, + styles: {}, + arrowStyles: {}, + attributes: {}, + flipped: !1, + offsets: {} + }; + (e.offsets.reference = L( + this.state, + this.popper, + this.reference, + this.options.positionFixed + )), + (e.placement = O( + this.options.placement, + e.offsets.reference, + this.popper, + this.reference, + this.options.modifiers.flip.boundariesElement, + this.options.modifiers.flip.padding + )), + (e.originalPlacement = e.placement), + (e.positionFixed = this.options.positionFixed), + (e.offsets.popper = D(this.popper, e.offsets.reference, e.placement)), + (e.offsets.popper.position = this.options.positionFixed + ? "fixed" + : "absolute"), + (e = P(this.modifiers, e)), + this.state.isCreated + ? this.options.onUpdate(e) + : ((this.state.isCreated = !0), this.options.onCreate(e)); + } + } + function W(e, t) { + return e.some(function(e) { + var o = e.name, + n = e.enabled; + return n && o === t; + }); + } + function H(e) { + for ( + var t = [!1, "ms", "Webkit", "Moz", "O"], + o = e.charAt(0).toUpperCase() + e.slice(1), + n = 0; + n < t.length; + n++ + ) { + var i = t[n], + r = i ? "" + i + o : e; + if ("undefined" != typeof document.body.style[r]) return r; + } + return null; + } + function B() { + return ( + (this.state.isDestroyed = !0), + W(this.modifiers, "applyStyle") && + (this.popper.removeAttribute("x-placement"), + (this.popper.style.position = ""), + (this.popper.style.top = ""), + (this.popper.style.left = ""), + (this.popper.style.right = ""), + (this.popper.style.bottom = ""), + (this.popper.style.willChange = ""), + (this.popper.style[H("transform")] = "")), + this.disableEventListeners(), + this.options.removeOnDestroy && + this.popper.parentNode.removeChild(this.popper), + this + ); + } + function A(e) { + var t = e.ownerDocument; + return t ? t.defaultView : window; + } + function M(e, t, o, i) { + var r = "BODY" === e.nodeName, + p = r ? e.ownerDocument.defaultView : e; + p.addEventListener(t, o, { passive: !0 }), + r || M(n(p.parentNode), t, o, i), + i.push(p); + } + function F(e, t, o, i) { + (o.updateBound = i), + A(e).addEventListener("resize", o.updateBound, { passive: !0 }); + var r = n(e); + return ( + M(r, "scroll", o.updateBound, o.scrollParents), + (o.scrollElement = r), + (o.eventsEnabled = !0), + o + ); + } + function I() { + this.state.eventsEnabled || + (this.state = F( + this.reference, + this.options, + this.state, + this.scheduleUpdate + )); + } + function R(e, t) { + return ( + A(e).removeEventListener("resize", t.updateBound), + t.scrollParents.forEach(function(e) { + e.removeEventListener("scroll", t.updateBound); + }), + (t.updateBound = null), + (t.scrollParents = []), + (t.scrollElement = null), + (t.eventsEnabled = !1), + t + ); + } + function U() { + this.state.eventsEnabled && + (cancelAnimationFrame(this.scheduleUpdate), + (this.state = R(this.reference, this.state))); + } + function Y(e) { + return "" !== e && !isNaN(parseFloat(e)) && isFinite(e); + } + function j(e, t) { + Object.keys(t).forEach(function(o) { + var n = ""; + -1 !== ["width", "height", "top", "right", "bottom", "left"].indexOf(o) && + Y(t[o]) && + (n = "px"), + (e.style[o] = t[o] + n); + }); + } + function V(e, t) { + Object.keys(t).forEach(function(o) { + var n = t[o]; + !1 === n ? e.removeAttribute(o) : e.setAttribute(o, t[o]); + }); + } + function q(e, t) { + var o = e.offsets, + n = o.popper, + i = o.reference, + r = -1 !== ["left", "right"].indexOf(e.placement), + p = -1 !== e.placement.indexOf("-"), + s = i.width % 2 == n.width % 2, + d = 1 == i.width % 2 && 1 == n.width % 2, + a = function(e) { + return e; + }, + l = t ? (r || p || s ? $ : Z) : a, + f = t ? $ : a; + return { + left: l(d && !p && t ? n.left - 1 : n.left), + top: f(n.top), + bottom: f(n.bottom), + right: l(n.right) + }; + } + function K(e, t, o) { + var n = C(e, function(e) { + var o = e.name; + return o === t; + }), + i = + !!n && + e.some(function(e) { + return e.name === o && e.enabled && e.order < n.order; + }); + if (!i) { + var r = "`" + t + "`"; + console.warn( + "`" + + o + + "`" + + " modifier is required by " + + r + + " modifier in order to work, be sure to include it before " + + r + + "!" + ); + } + return i; + } + function z(e) { + return "end" === e ? "start" : "start" === e ? "end" : e; + } + function G(e) { + var t = 1 < arguments.length && void 0 !== arguments[1] && arguments[1], + o = ce.indexOf(e), + n = ce.slice(o + 1).concat(ce.slice(0, o)); + return t ? n.reverse() : n; + } + function _(e, t, o, n) { + var i = e.match(/((?:\-|\+)?\d*\.?\d*)(.*)/), + r = +i[1], + p = i[2]; + if (!r) return e; + if (0 === p.indexOf("%")) { + var s; + switch (p) { + case "%p": + s = o; + break; + case "%": + case "%r": + default: + s = n; + } + var d = g(s); + return (d[t] / 100) * r; + } + if ("vh" === p || "vw" === p) { + var a; + return ( + (a = + "vh" === p + ? ee(document.documentElement.clientHeight, window.innerHeight || 0) + : ee(document.documentElement.clientWidth, window.innerWidth || 0)), + (a / 100) * r + ); + } + return r; + } + function X(e, t, o, n) { + var i = [0, 0], + r = -1 !== ["right", "left"].indexOf(n), + p = e.split(/(\+|\-)/).map(function(e) { + return e.trim(); + }), + s = p.indexOf( + C(p, function(e) { + return -1 !== e.search(/,|\s/); + }) + ); + p[s] && + -1 === p[s].indexOf(",") && + console.warn( + "Offsets separated by white space(s) are deprecated, use a comma (,) instead." + ); + var d = /\s*,\s*|\s+/, + a = + -1 === s + ? [p] + : [ + p.slice(0, s).concat([p[s].split(d)[0]]), + [p[s].split(d)[1]].concat(p.slice(s + 1)) + ]; + return ( + (a = a.map(function(e, n) { + var i = (1 === n ? !r : r) ? "height" : "width", + p = !1; + return e + .reduce(function(e, t) { + return "" === e[e.length - 1] && -1 !== ["+", "-"].indexOf(t) + ? ((e[e.length - 1] = t), (p = !0), e) + : p + ? ((e[e.length - 1] += t), (p = !1), e) + : e.concat(t); + }, []) + .map(function(e) { + return _(e, i, t, o); + }); + })), + a.forEach(function(e, t) { + e.forEach(function(o, n) { + Y(o) && (i[t] += o * ("-" === e[n - 1] ? -1 : 1)); + }); + }), + i + ); + } + function J(e, t) { + var o, + n = t.offset, + i = e.placement, + r = e.offsets, + p = r.popper, + s = r.reference, + d = i.split("-")[0]; + return ( + (o = Y(+n) ? [+n, 0] : X(n, p, s, d)), + "left" === d + ? ((p.top += o[0]), (p.left -= o[1])) + : "right" === d + ? ((p.top += o[0]), (p.left += o[1])) + : "top" === d + ? ((p.left += o[0]), (p.top -= o[1])) + : "bottom" === d && ((p.left += o[0]), (p.top += o[1])), + (e.popper = p), + e + ); + } + for ( + var Q = Math.min, + Z = Math.floor, + $ = Math.round, + ee = Math.max, + te = "undefined" != typeof window && "undefined" != typeof document, + oe = ["Edge", "Trident", "Firefox"], + ne = 0, + ie = 0; + ie < oe.length; + ie += 1 + ) + if (te && 0 <= navigator.userAgent.indexOf(oe[ie])) { + ne = 1; + break; + } + var i = te && window.Promise, + re = i + ? function(e) { + var t = !1; + return function() { + t || + ((t = !0), + window.Promise.resolve().then(function() { + (t = !1), e(); + })); + }; + } + : function(e) { + var t = !1; + return function() { + t || + ((t = !0), + setTimeout(function() { + (t = !1), e(); + }, ne)); + }; + }, + pe = te && !!(window.MSInputMethodContext && document.documentMode), + se = te && /MSIE 10/.test(navigator.userAgent), + de = function(e, t) { + if (!(e instanceof t)) + throw new TypeError("Cannot call a class as a function"); + }, + ae = (function() { + function e(e, t) { + for (var o, n = 0; n < t.length; n++) + (o = t[n]), + (o.enumerable = o.enumerable || !1), + (o.configurable = !0), + "value" in o && (o.writable = !0), + Object.defineProperty(e, o.key, o); + } + return function(t, o, n) { + return o && e(t.prototype, o), n && e(t, n), t; + }; + })(), + le = function(e, t, o) { + return ( + t in e + ? Object.defineProperty(e, t, { + value: o, + enumerable: !0, + configurable: !0, + writable: !0 + }) + : (e[t] = o), + e + ); + }, + fe = + Object.assign || + function(e) { + for (var t, o = 1; o < arguments.length; o++) + for (var n in ((t = arguments[o]), t)) + Object.prototype.hasOwnProperty.call(t, n) && (e[n] = t[n]); + return e; + }, + me = te && /Firefox/i.test(navigator.userAgent), + he = [ + "auto-start", + "auto", + "auto-end", + "top-start", + "top", + "top-end", + "right-start", + "right", + "right-end", + "bottom-end", + "bottom", + "bottom-start", + "left-end", + "left", + "left-start" + ], + ce = he.slice(3), + ge = { + FLIP: "flip", + CLOCKWISE: "clockwise", + COUNTERCLOCKWISE: "counterclockwise" + }, + ue = (function() { + function t(o, n) { + var i = this, + r = + 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : {}; + de(this, t), + (this.scheduleUpdate = function() { + return requestAnimationFrame(i.update); + }), + (this.update = re(this.update.bind(this))), + (this.options = fe({}, t.Defaults, r)), + (this.state = { isDestroyed: !1, isCreated: !1, scrollParents: [] }), + (this.reference = o && o.jquery ? o[0] : o), + (this.popper = n && n.jquery ? n[0] : n), + (this.options.modifiers = {}), + Object.keys(fe({}, t.Defaults.modifiers, r.modifiers)).forEach( + function(e) { + i.options.modifiers[e] = fe( + {}, + t.Defaults.modifiers[e] || {}, + r.modifiers ? r.modifiers[e] : {} + ); + } + ), + (this.modifiers = Object.keys(this.options.modifiers) + .map(function(e) { + return fe({ name: e }, i.options.modifiers[e]); + }) + .sort(function(e, t) { + return e.order - t.order; + })), + this.modifiers.forEach(function(t) { + t.enabled && + e(t.onLoad) && + t.onLoad(i.reference, i.popper, i.options, t, i.state); + }), + this.update(); + var p = this.options.eventsEnabled; + p && this.enableEventListeners(), (this.state.eventsEnabled = p); + } + return ( + ae(t, [ + { + key: "update", + value: function() { + return k.call(this); + } + }, + { + key: "destroy", + value: function() { + return B.call(this); + } + }, + { + key: "enableEventListeners", + value: function() { + return I.call(this); + } + }, + { + key: "disableEventListeners", + value: function() { + return U.call(this); + } + } + ]), + t + ); + })(); + return ( + (ue.Utils = ("undefined" == typeof window ? global : window).PopperUtils), + (ue.placements = he), + (ue.Defaults = { + placement: "bottom", + positionFixed: !1, + eventsEnabled: !0, + removeOnDestroy: !1, + onCreate: function() {}, + onUpdate: function() {}, + modifiers: { + shift: { + order: 100, + enabled: !0, + fn: function(e) { + var t = e.placement, + o = t.split("-")[0], + n = t.split("-")[1]; + if (n) { + var i = e.offsets, + r = i.reference, + p = i.popper, + s = -1 !== ["bottom", "top"].indexOf(o), + d = s ? "left" : "top", + a = s ? "width" : "height", + l = { + start: le({}, d, r[d]), + end: le({}, d, r[d] + r[a] - p[a]) + }; + e.offsets.popper = fe({}, p, l[n]); + } + return e; + } + }, + offset: { order: 200, enabled: !0, fn: J, offset: 0 }, + preventOverflow: { + order: 300, + enabled: !0, + fn: function(e, t) { + var o = t.boundariesElement || p(e.instance.popper); + e.instance.reference === o && (o = p(o)); + var n = H("transform"), + i = e.instance.popper.style, + r = i.top, + s = i.left, + d = i[n]; + (i.top = ""), (i.left = ""), (i[n] = ""); + var a = v( + e.instance.popper, + e.instance.reference, + t.padding, + o, + e.positionFixed + ); + (i.top = r), (i.left = s), (i[n] = d), (t.boundaries = a); + var l = t.priority, + f = e.offsets.popper, + m = { + primary: function(e) { + var o = f[e]; + return ( + f[e] < a[e] && + !t.escapeWithReference && + (o = ee(f[e], a[e])), + le({}, e, o) + ); + }, + secondary: function(e) { + var o = "right" === e ? "left" : "top", + n = f[o]; + return ( + f[e] > a[e] && + !t.escapeWithReference && + (n = Q( + f[o], + a[e] - ("right" === e ? f.width : f.height) + )), + le({}, o, n) + ); + } + }; + return ( + l.forEach(function(e) { + var t = + -1 === ["left", "top"].indexOf(e) ? "secondary" : "primary"; + f = fe({}, f, m[t](e)); + }), + (e.offsets.popper = f), + e + ); + }, + priority: ["left", "right", "top", "bottom"], + padding: 5, + boundariesElement: "scrollParent" + }, + keepTogether: { + order: 400, + enabled: !0, + fn: function(e) { + var t = e.offsets, + o = t.popper, + n = t.reference, + i = e.placement.split("-")[0], + r = Z, + p = -1 !== ["top", "bottom"].indexOf(i), + s = p ? "right" : "bottom", + d = p ? "left" : "top", + a = p ? "width" : "height"; + return ( + o[s] < r(n[d]) && (e.offsets.popper[d] = r(n[d]) - o[a]), + o[d] > r(n[s]) && (e.offsets.popper[d] = r(n[s])), + e + ); + } + }, + arrow: { + order: 500, + enabled: !0, + fn: function(e, o) { + var n; + if (!K(e.instance.modifiers, "arrow", "keepTogether")) return e; + var i = o.element; + if ("string" == typeof i) { + if (((i = e.instance.popper.querySelector(i)), !i)) return e; + } else if (!e.instance.popper.contains(i)) + return ( + console.warn( + "WARNING: `arrow.element` must be child of its popper element!" + ), + e + ); + var r = e.placement.split("-")[0], + p = e.offsets, + s = p.popper, + d = p.reference, + a = -1 !== ["left", "right"].indexOf(r), + l = a ? "height" : "width", + f = a ? "Top" : "Left", + m = f.toLowerCase(), + h = a ? "left" : "top", + c = a ? "bottom" : "right", + u = S(i)[l]; + d[c] - u < s[m] && (e.offsets.popper[m] -= s[m] - (d[c] - u)), + d[m] + u > s[c] && (e.offsets.popper[m] += d[m] + u - s[c]), + (e.offsets.popper = g(e.offsets.popper)); + var b = d[m] + d[l] / 2 - u / 2, + w = t(e.instance.popper), + y = parseFloat(w["margin" + f], 10), + E = parseFloat(w["border" + f + "Width"], 10), + v = b - e.offsets.popper[m] - y - E; + return ( + (v = ee(Q(s[l] - u, v), 0)), + (e.arrowElement = i), + (e.offsets.arrow = ((n = {}), le(n, m, $(v)), le(n, h, ""), n)), + e + ); + }, + element: "[x-arrow]" + }, + flip: { + order: 600, + enabled: !0, + fn: function(e, t) { + if (W(e.instance.modifiers, "inner")) return e; + if (e.flipped && e.placement === e.originalPlacement) return e; + var o = v( + e.instance.popper, + e.instance.reference, + t.padding, + t.boundariesElement, + e.positionFixed + ), + n = e.placement.split("-")[0], + i = T(n), + r = e.placement.split("-")[1] || "", + p = []; + switch (t.behavior) { + case ge.FLIP: + p = [n, i]; + break; + case ge.CLOCKWISE: + p = G(n); + break; + case ge.COUNTERCLOCKWISE: + p = G(n, !0); + break; + default: + p = t.behavior; + } + return ( + p.forEach(function(s, d) { + if (n !== s || p.length === d + 1) return e; + (n = e.placement.split("-")[0]), (i = T(n)); + var a = e.offsets.popper, + l = e.offsets.reference, + f = Z, + m = + ("left" === n && f(a.right) > f(l.left)) || + ("right" === n && f(a.left) < f(l.right)) || + ("top" === n && f(a.bottom) > f(l.top)) || + ("bottom" === n && f(a.top) < f(l.bottom)), + h = f(a.left) < f(o.left), + c = f(a.right) > f(o.right), + g = f(a.top) < f(o.top), + u = f(a.bottom) > f(o.bottom), + b = + ("left" === n && h) || + ("right" === n && c) || + ("top" === n && g) || + ("bottom" === n && u), + w = -1 !== ["top", "bottom"].indexOf(n), + y = + !!t.flipVariations && + ((w && "start" === r && h) || + (w && "end" === r && c) || + (!w && "start" === r && g) || + (!w && "end" === r && u)); + (m || b || y) && + ((e.flipped = !0), + (m || b) && (n = p[d + 1]), + y && (r = z(r)), + (e.placement = n + (r ? "-" + r : "")), + (e.offsets.popper = fe( + {}, + e.offsets.popper, + D(e.instance.popper, e.offsets.reference, e.placement) + )), + (e = P(e.instance.modifiers, e, "flip"))); + }), + e + ); + }, + behavior: "flip", + padding: 5, + boundariesElement: "viewport" + }, + inner: { + order: 700, + enabled: !1, + fn: function(e) { + var t = e.placement, + o = t.split("-")[0], + n = e.offsets, + i = n.popper, + r = n.reference, + p = -1 !== ["left", "right"].indexOf(o), + s = -1 === ["top", "left"].indexOf(o); + return ( + (i[p ? "left" : "top"] = + r[o] - (s ? i[p ? "width" : "height"] : 0)), + (e.placement = T(t)), + (e.offsets.popper = g(i)), + e + ); + } + }, + hide: { + order: 800, + enabled: !0, + fn: function(e) { + if (!K(e.instance.modifiers, "hide", "preventOverflow")) return e; + var t = e.offsets.reference, + o = C(e.instance.modifiers, function(e) { + return "preventOverflow" === e.name; + }).boundaries; + if ( + t.bottom < o.top || + t.left > o.right || + t.top > o.bottom || + t.right < o.left + ) { + if (!0 === e.hide) return e; + (e.hide = !0), (e.attributes["x-out-of-boundaries"] = ""); + } else { + if (!1 === e.hide) return e; + (e.hide = !1), (e.attributes["x-out-of-boundaries"] = !1); + } + return e; + } + }, + computeStyle: { + order: 850, + enabled: !0, + fn: function(e, t) { + var o = t.x, + n = t.y, + i = e.offsets.popper, + r = C(e.instance.modifiers, function(e) { + return "applyStyle" === e.name; + }).gpuAcceleration; + void 0 !== r && + console.warn( + "WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!" + ); + var s, + d, + a = void 0 === r ? t.gpuAcceleration : r, + l = p(e.instance.popper), + f = u(l), + m = { position: i.position }, + h = q(e, 2 > window.devicePixelRatio || !me), + c = "bottom" === o ? "top" : "bottom", + g = "right" === n ? "left" : "right", + b = H("transform"); + if ( + ((d = + "bottom" == c + ? "HTML" === l.nodeName + ? -l.clientHeight + h.bottom + : -f.height + h.bottom + : h.top), + (s = + "right" == g + ? "HTML" === l.nodeName + ? -l.clientWidth + h.right + : -f.width + h.right + : h.left), + a && b) + ) + (m[b] = "translate3d(" + s + "px, " + d + "px, 0)"), + (m[c] = 0), + (m[g] = 0), + (m.willChange = "transform"); + else { + var w = "bottom" == c ? -1 : 1, + y = "right" == g ? -1 : 1; + (m[c] = d * w), (m[g] = s * y), (m.willChange = c + ", " + g); + } + var E = { "x-placement": e.placement }; + return ( + (e.attributes = fe({}, E, e.attributes)), + (e.styles = fe({}, m, e.styles)), + (e.arrowStyles = fe({}, e.offsets.arrow, e.arrowStyles)), + e + ); + }, + gpuAcceleration: !0, + x: "bottom", + y: "right" + }, + applyStyle: { + order: 900, + enabled: !0, + fn: function(e) { + return ( + j(e.instance.popper, e.styles), + V(e.instance.popper, e.attributes), + e.arrowElement && + Object.keys(e.arrowStyles).length && + j(e.arrowElement, e.arrowStyles), + e + ); + }, + onLoad: function(e, t, o, n, i) { + var r = L(i, t, e, o.positionFixed), + p = O( + o.placement, + r, + t, + e, + o.modifiers.flip.boundariesElement, + o.modifiers.flip.padding + ); + return ( + t.setAttribute("x-placement", p), + j(t, { position: o.positionFixed ? "fixed" : "absolute" }), + o + ); + }, + gpuAcceleration: void 0 + } + } + }), + ue + ); +}); diff --git a/rental/views.py b/rental/views.py index 0325dde..ce707cb 100644 --- a/rental/views.py +++ b/rental/views.py @@ -1,36 +1,37 @@ from django.shortcuts import render, get_object_or_404 -from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView -from .models import Testimonial, Reservation, Guest, Place -from django.urls import reverse_lazy -from django.views.generic.base import TemplateView -from .forms import ReservationForm, ContactForm from django.db import IntegrityError +from django.views.generic.base import TemplateView +from rental.forms import ReservationForm, ContactForm +from rental.models import Testimonial, Reservation, Guest, Place, Contact from rental.pricing import get_reservation_price from rental.bookings import check_availability, synchronize_calendars, update_calendar -# send_confirmation_mail, send_notification, send_quotation -from rental.tasks.apiMailer import * # gMailer -from rental.models import Contact +from rental.tasks.apiMailer import * # or gMailer def index(request): places = Place.objects.all() temoignages = Testimonial.objects.all() + context = { 'places': places, 'temoignages': temoignages } + return render(request, 'rental/index.html', context) def liste_location(request): places = Place.objects.all() + context = {'places': places} + return render(request, 'rental/list_place.html', context) def location(request, place_name='T2'): place = get_object_or_404(Place, name=place_name) images = place.images.all() + context = { 'place': place, 'images': images @@ -44,6 +45,7 @@ def location(request, place_name='T2'): def reservation(request): context, template = handle_reservation_form(request) + return render(request, template, context) @@ -58,6 +60,7 @@ def handle_reservation_form(request, context={}, init_template='rental/reservati place_name = form.cleaned_data['place'] start = form.cleaned_data['start'] end = form.cleaned_data['end'] + try: guest = Guest.objects.filter(email=email) if not guest.exists(): @@ -68,6 +71,7 @@ def handle_reservation_form(request, context={}, init_template='rental/reservati ) else: guest = guest.first() + place = get_object_or_404(Place, name=place_name) available = check_availability(place, start, end) price = get_reservation_price(place, start, end) @@ -91,13 +95,16 @@ def handle_reservation_form(request, context={}, init_template='rental/reservati context = {'form': form} template = 'rental/reservation.html' return context, template + except IntegrityError: form.errors['internal'] = "Une erreur interne est apparue. Merci de recommencer votre requête." else: form = ReservationForm() + context['form'] = form context['errors'] = form.errors.items() template = init_template + return context, template @@ -113,6 +120,7 @@ def calendar(request, place_name): 'place_name': place_name, 'bookings': bookings } + return render(request, 'rental/calendar.html', context)