| @ -0,0 +1,9 @@ | |||
| #!/bin/bash | |||
| #this is .openshift/action/hooks/build | |||
| #remember to make it +x so openshift can run it. | |||
| if [ ! -d ${OPENSHIFT_DATA_DIR}media ]; then | |||
| mkdir -p ${OPENSHIFT_DATA_DIR}media | |||
| fi | |||
| ln -snf ${OPENSHIFT_DATA_DIR}media $OPENSHIFT_REPO_DIR/wsgi/static/media | |||
| ######################### end of file | |||
| @ -1,24 +1,45 @@ | |||
| FROM python:3.11.4-slim-buster | |||
| # Add application sources with correct permissions for OpenShift | |||
| ENV APP_HOME=/app | |||
| RUN mkdir -p $APP_HOME/datos | |||
| ADD . $APP_HOME | |||
| # yup, python 3.11! | |||
| FROM python:3.11-slim | |||
| USER 0 | |||
| # install nginx | |||
| RUN apt-get update && apt-get install nginx -y | |||
| # copy our nginx configuration to overwrite nginx defaults | |||
| RUN rm /etc/nginx/sites-enabled/default | |||
| RUN rm /etc/nginx/sites-available/default | |||
| COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf | |||
| # link nginx logs to container stdout | |||
| RUN ln -sf /dev/stdout /var/log/nginx/access.log && ln -sf /dev/stderr /var/log/nginx/error.log | |||
| # copy the django code | |||
| COPY ./src ./app | |||
| RUN useradd nginx | |||
| RUN chgrp -R 0 ./app && chmod -R g=u ./app | |||
| RUN chown -R nginx:0 /var/log/nginx && \ | |||
| chown -R nginx:0 /var/lib/nginx && \ | |||
| chown -R nginx:0 /etc/nginx/conf.d | |||
| # Install the dependencies | |||
| RUN apt-get update && apt-get install -y sqlite3 | |||
| RUN touch /var/run/nginx.pid && \ | |||
| chown -R nginx:0 /var/run/nginx.pid | |||
| RUN pip install -U "pip>=19.3.1" && \ | |||
| pip install -r $APP_HOME/requirements.txt && \ | |||
| # python manage.py collectstatic --noinput && \ | |||
| python $APP_HOME/manage.py migrate | |||
| # change our working directory to the django projcet roo | |||
| WORKDIR /app | |||
| WORKDIR $APP_HOME | |||
| RUN chown -R 1000770000:0 ./ | |||
| USER 1000770000 | |||
| # create virtual env (notice the location?) | |||
| # update pip | |||
| # install requirements | |||
| RUN python -m venv /opt/venv && \ | |||
| /opt/venv/bin/python -m pip install pip --upgrade && \ | |||
| /opt/venv/bin/python -m pip install -r requirements.txt | |||
| # make our entrypoint.sh executable | |||
| RUN chmod +x config/entrypoint.sh | |||
| # USER nginx | |||
| EXPOSE 8080 | |||
| # Run the application | |||
| CMD python manage.py runserver 0.0.0.0:8080 | |||
| # execute our entrypoint.sh file | |||
| CMD ["./config/entrypoint.sh"] | |||
| @ -1,148 +1,12 @@ | |||
| ## Versiones de python | |||
| https://catalog.redhat.com/software/containers/ubi9/python-311/63f764b03f0b02a2e2d63fff | |||
| ## Deploying to OpenShift | |||
| To follow the next steps, you need to be logged in to an OpenShift cluster and have an OpenShift project where you can work on. | |||
| ### Using an application template | |||
| The directory `openshift/templates/` contains OpenShift application templates that you can add to your OpenShift project with: | |||
| oc create -f openshift/templates/<TEMPLATE_NAME>.json | |||
| The template `django.json` contains just a minimal set of components to get your Django application into OpenShift. | |||
| The template `django-postgresql.json` contains all of the components from `django.json`, plus a PostgreSQL database service and an Image Stream for the Python base image. For simplicity, the PostgreSQL database in this template uses ephemeral storage and, therefore, is not production ready. | |||
| After adding your templates, you can go to your OpenShift web console, browse to your project and click the create button. Create a new app from one of the templates that you have just added. | |||
| Adjust the parameter values to suit your configuration. Most times you can just accept the default values, however you will probably want to set the `GIT_REPOSITORY` parameter to point to your fork and the `DATABASE_*` parameters to match your database configuration. | |||
| Alternatively, you can use the command line to create your new app, assuming your OpenShift deployment has the default set of ImageStreams defined. Instructions for installing the default ImageStreams are available [here](https://docs.okd.io/latest/install_config/imagestreams_templates.html). If you are defining the set of ImageStreams now, remember to pass in the proper cluster-admin credentials and to create the ImageStreams in the 'openshift' namespace: | |||
| oc new-app openshift/templates/django.json -p SOURCE_REPOSITORY_URL=<your repository location> | |||
| Your application will be built and deployed automatically. If that doesn't happen, you can debug your build: | |||
| oc get builds | |||
| # take build name from the command above | |||
| oc logs build/<build-name> | |||
| And you can see information about your deployment too: | |||
| oc describe dc/django-example | |||
| In the web console, the overview tab shows you a service, by default called "django-example", that encapsulates all pods running your Django application. You can access your application by browsing to the service's IP address and port. You can determine these by running | |||
| oc get svc | |||
| ### Without an application template | |||
| Templates give you full control of each component of your application. | |||
| Sometimes your application is simple enough and you don't want to bother with templates. In that case, you can let OpenShift inspect your source code and create the required components automatically for you: | |||
| ```bash | |||
| $ oc new-app centos/python-35-centos7~https://github.com/sclorg/django-ex | |||
| imageStreams/python-35-centos7 | |||
| imageStreams/django-ex | |||
| buildConfigs/django-ex | |||
| deploymentConfigs/django-ex | |||
| services/django-ex | |||
| A build was created - you can run `oc start-build django-ex` to start it. | |||
| Service "django-ex" created at 172.30.16.213 with port mappings 8080. | |||
| ``` | |||
| You can access your application by browsing to the service's IP address and port. | |||
| ## Logs | |||
| By default your Django application is served with gunicorn and configured to output its access log to stderr. | |||
| You can look at the combined stdout and stderr of a given pod with this command: | |||
| oc get pods # list all pods in your project | |||
| oc logs <pod-name> | |||
| This can be useful to observe the correct functioning of your application. | |||
| ## Special environment variables | |||
| ### APP_CONFIG | |||
| You can fine tune the gunicorn configuration through the environment variable `APP_CONFIG` that, when set, should point to a config file as documented [here](http://docs.gunicorn.org/en/latest/settings.html). | |||
| ### DJANGO_SECRET_KEY | |||
| When using one of the templates provided in this repository, this environment variable has its value automatically generated. For security purposes, make sure to set this to a random string as documented [here](https://docs.djangoproject.com/en/1.8/ref/settings/#std:setting-SECRET_KEY). | |||
| ## One-off command execution | |||
| At times you might want to manually execute some command in the context of a running application in OpenShift. | |||
| You can drop into a Python shell for debugging, create a new user for the Django Admin interface, or perform any other task. | |||
| You can do all that by using regular CLI commands from OpenShift. | |||
| To make it a little more convenient, you can use the script `openshift/scripts/run-in-container.sh` that wraps some calls to `oc`. | |||
| In the future, the `oc` CLI tool might incorporate changes | |||
| that make this script obsolete. | |||
| Here is how you would run a command in a pod specified by label: | |||
| 1. Inspect the output of the command below to find the name of a pod that matches a given label: | |||
| oc get pods -l <your-label-selector> | |||
| 2. Open a shell in the pod of your choice. Because of how the images produced | |||
| with CentOS and RHEL work currently, we need to wrap commands with `bash` to | |||
| enable any Software Collections that may be used (done automatically inside | |||
| every bash shell). | |||
| oc exec -p <pod-name> -it -- bash | |||
| 3. Finally, execute any command that you need and exit the shell. | |||
| Related GitHub issues: | |||
| 1. https://github.com/GoogleCloudPlatform/kubernetes/issues/8876 | |||
| 2. https://github.com/openshift/origin/issues/2001 | |||
| The wrapper script combines the steps above into one. You can use it like this: | |||
| ./run-in-container.sh ./manage.py migrate # manually migrate the database | |||
| # (done for you as part of the deployment process) | |||
| ./run-in-container.sh ./manage.py createsuperuser # create a user to access Django Admin | |||
| ./run-in-container.sh ./manage.py shell # open a Python shell in the context of your app | |||
| If your Django pods are labeled with a name other than "django", you can use: | |||
| POD_NAME=name ./run-in-container.sh ./manage.py check | |||
| If there is more than one replica, you can also specify a POD by index: | |||
| POD_INDEX=1 ./run-in-container.sh ./manage.py shell | |||
| Or both together: | |||
| POD_NAME=django-example POD_INDEX=2 ./run-in-container.sh ./manage.py shell | |||
| ## Data persistence | |||
| You can deploy this application without a configured database in your OpenShift project, in which case Django will use a temporary SQLite database that will live inside your application's container, and persist only until you redeploy your application. | |||
| After each deploy you get a fresh, empty, SQLite database. That is fine for a first contact with OpenShift and perhaps Django, but sooner or later you will want to persist your data across deployments. | |||
| To do that, you should add a properly configured database server or ask your OpenShift administrator to add one for you. Then use `oc env` to update the `DATABASE_*` environment variables in your DeploymentConfig to match your database settings. | |||
| Redeploy your application to have your changes applied, and open the welcome page again to make sure your application is successfully connected to the database server. | |||
| ## Looking for help | |||
| If you get stuck at some point, or think that this document needs further details or clarification, you can give feedback and look for help using the channels mentioned in [the OKD repo](https://github.com/openshift/origin), or by filing an issue. | |||
| # Djangotutorial | |||
| ## creación de la app | |||
| oc new-app http://gitea.reymota.es/creylopez/djangotutorial.git -e DEBUG="False" -e VERSION=11.0 --name='djangotutorial' | |||
| ## asignación de los volúmenes | |||
| ### Si la pvc no está creada | |||
| oc set volume deployment.apps/djangotutorial --add --name=media -t pvc --claim-size=100M --claim-name='djangotutorial-media' --claim-class='lvms-vg1' --mount-path='/app/mediafiles/' | |||
| ### Si la pvc ya está creada | |||
| oc set volume deployment.apps/djangotutorial --add --name=media -t pvc --claim-name='djangotutorial-media' --mount-path='/app/mediafiles/' | |||
| ## exponer el servicio (crear ruta) | |||
| oc expose svc djangotutorial | |||
| @ -0,0 +1,11 @@ | |||
| apiVersion: v1 | |||
| data: | |||
| POSTGRES_DB: djangotutorial | |||
| POSTGRES_PASSWORD: Dsa-0213 | |||
| POSTGRES_USER: creylopez | |||
| kind: ConfigMap | |||
| metadata: | |||
| labels: | |||
| io.kompose.service: db-env-prod-db | |||
| name: env-prod-db | |||
| namespace: djangotutorial | |||
| @ -0,0 +1,52 @@ | |||
| apiVersion: apps/v1 | |||
| kind: Deployment | |||
| metadata: | |||
| annotations: | |||
| kompose.cmd: kompose convert | |||
| kompose.version: 1.34.0 (cbf2835db) | |||
| labels: | |||
| io.kompose.service: postgresql | |||
| name: postgresql | |||
| namespace: djangotutorial | |||
| spec: | |||
| replicas: 1 | |||
| selector: | |||
| matchLabels: | |||
| io.kompose.service: postgresql | |||
| strategy: | |||
| type: Recreate | |||
| template: | |||
| metadata: | |||
| annotations: | |||
| kompose.cmd: kompose convert | |||
| kompose.version: 1.34.0 (cbf2835db) | |||
| labels: | |||
| io.kompose.service: postgresql | |||
| spec: | |||
| containers: | |||
| - env: | |||
| - name: POSTGRES_DB | |||
| valueFrom: | |||
| configMapKeyRef: | |||
| key: POSTGRES_DB | |||
| name: env-prod-db | |||
| - name: POSTGRES_PASSWORD | |||
| valueFrom: | |||
| configMapKeyRef: | |||
| key: POSTGRES_PASSWORD | |||
| name: env-prod-db | |||
| - name: POSTGRES_USER | |||
| valueFrom: | |||
| configMapKeyRef: | |||
| key: POSTGRES_USER | |||
| name: env-prod-db | |||
| image: postgres:15 | |||
| name: postgresql | |||
| volumeMounts: | |||
| - mountPath: /var/lib/postgresql/data | |||
| name: postgresql | |||
| restartPolicy: Always | |||
| volumes: | |||
| - name: postgresql | |||
| persistentVolumeClaim: | |||
| claimName: postgresql | |||
| @ -0,0 +1,17 @@ | |||
| apiVersion: v1 | |||
| kind: Service | |||
| metadata: | |||
| annotations: | |||
| kompose.cmd: kompose convert | |||
| kompose.version: 1.34.0 (cbf2835db) | |||
| labels: | |||
| io.kompose.service: postgresql | |||
| name: postgresql | |||
| namespace: djangotutorial | |||
| spec: | |||
| ports: | |||
| - name: "5432" | |||
| port: 5432 | |||
| targetPort: 5432 | |||
| selector: | |||
| io.kompose.service: postgresql | |||
| @ -0,0 +1,17 @@ | |||
| apiVersion: v1 | |||
| kind: PersistentVolumeClaim | |||
| metadata: | |||
| finalizers: | |||
| - kubernetes.io/pvc-protection | |||
| labels: | |||
| template: postgresql-persistent-template | |||
| name: postgresql | |||
| namespace: djangotutorial | |||
| spec: | |||
| accessModes: | |||
| - ReadWriteOnce | |||
| resources: | |||
| requests: | |||
| storage: 1Gi | |||
| storageClassName: lvms-vg1 | |||
| volumeMode: Filesystem | |||
| @ -0,0 +1,3 @@ | |||
| oc delete -f Yamls/env-prod-db-configmap.yaml | |||
| oc delete -f Yamls/postgresql-deployment.yaml | |||
| oc delete -f Yamls/postgresql-service.yaml | |||
| @ -0,0 +1,4 @@ | |||
| oc create -f Yamls/env-prod-db-configmap.yaml | |||
| oc create -f Yamls/pvc-postgresql.yaml | |||
| oc create -f Yamls/postgresql-deployment.yaml | |||
| oc create -f Yamls/postgresql-service.yaml | |||
| @ -0,0 +1,32 @@ | |||
| upstream django_project { | |||
| server localhost:8000; | |||
| } | |||
| error_log /var/log/nginx/error.log; | |||
| server { | |||
| listen 8080; | |||
| access_log /var/log/nginx/access.log; | |||
| location / { | |||
| proxy_pass http://django_project; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| proxy_set_header Host $http_host; | |||
| proxy_redirect off; | |||
| client_max_body_size 100M; | |||
| } | |||
| location /static/ { | |||
| alias /app/staticfiles/; | |||
| } | |||
| location /media/ { | |||
| alias /app/mediafiles/; | |||
| } | |||
| error_page 500 502 503 504 /50x.html; | |||
| location = /50x.html { | |||
| root /usr/share/nginx/html; | |||
| } | |||
| } | |||
| @ -1,41 +0,0 @@ | |||
| #!/bin/bash | |||
| # Use this script to run one-off commands inside a container of a pod where your | |||
| # Python application code lives in. | |||
| # You can accomplish the same results by using regular commands from OpenShift. | |||
| # This script is just wrapping calls to `oc` to make it a little more | |||
| # convenient to use. In the future, the `oc` cli tool might incorporate changes | |||
| # that make this script obsolete. | |||
| # Related GitHub issues: | |||
| # - https://github.com/GoogleCloudPlatform/kubernetes/issues/8876 | |||
| # - https://github.com/openshift/origin/issues/2001 | |||
| # Usage examples: | |||
| # | |||
| # ./run-in-container.sh ./manage.py migrate | |||
| # ./run-in-container.sh ./manage.py createsuperuser | |||
| # ./run-in-container.sh ./manage.py shell | |||
| # | |||
| # If your Python pods are labeled with a name other than "django", you can use: | |||
| # | |||
| # POD_NAME=name ./run-in-container.sh ./manage.py check | |||
| # | |||
| # If there is more than one replica, you can also specify a POD by index: | |||
| # | |||
| # POD_INDEX=1 ./run-in-container.sh ./manage.py shell | |||
| # | |||
| # Or both together: | |||
| # | |||
| # POD_NAME=frontend POD_INDEX=2 ./run-in-container.sh ./manage.py shell | |||
| # Get name of a currently deployed pod by label and index | |||
| POD_INSTANCE_NAME=`oc get pods \ | |||
| -l "name=${POD_NAME:-django-frontend}" \ | |||
| -t "{{ with index .items ${POD_INDEX:-0} }}{{ .metadata.name }}{{ end }}"` | |||
| # Run command in a container of the specified pod: | |||
| oc exec -p "$POD_INSTANCE_NAME" -it -- bash -c "${@:-echo}" | |||
| @ -1,524 +0,0 @@ | |||
| { | |||
| "kind": "Template", | |||
| "apiVersion": "template.openshift.io/v1", | |||
| "metadata": { | |||
| "name": "django-psql-persistent", | |||
| "annotations": { | |||
| "openshift.io/display-name": "Django + PostgreSQL", | |||
| "description": "An example Django application with a PostgreSQL database. For more information about using this template, including OpenShift considerations, see https://github.com/sclorg/django-ex/blob/master/README.md.", | |||
| "tags": "quickstart,python,django", | |||
| "iconClass": "icon-python", | |||
| "openshift.io/long-description": "This template defines resources needed to develop a Django based application, including a build configuration, application deployment configuration, and database deployment configuration.", | |||
| "openshift.io/provider-display-name": "Red Hat, Inc.", | |||
| "openshift.io/documentation-url": "https://github.com/sclorg/django-ex", | |||
| "openshift.io/support-url": "https://access.redhat.com", | |||
| "template.openshift.io/bindable": "false" | |||
| } | |||
| }, | |||
| "message": "The following service(s) have been created in your project: ${NAME}, ${DATABASE_SERVICE_NAME}.\n\nFor more information about using this template, including OpenShift considerations, see https://github.com/sclorg/django-ex/blob/master/README.md.", | |||
| "labels": { | |||
| "template": "django-psql-persistent", | |||
| "app": "django-psql-persistent" | |||
| }, | |||
| "objects": [ | |||
| { | |||
| "kind": "Secret", | |||
| "apiVersion": "v1", | |||
| "metadata": { | |||
| "name": "${NAME}" | |||
| }, | |||
| "stringData" : { | |||
| "database-user" : "${DATABASE_USER}", | |||
| "database-password" : "${DATABASE_PASSWORD}", | |||
| "django-secret-key" : "${DJANGO_SECRET_KEY}" | |||
| } | |||
| }, | |||
| { | |||
| "kind": "Service", | |||
| "apiVersion": "v1", | |||
| "metadata": { | |||
| "name": "${NAME}", | |||
| "annotations": { | |||
| "description": "Exposes and load balances the application pods", | |||
| "service.alpha.openshift.io/dependencies": "[{\"name\": \"${DATABASE_SERVICE_NAME}\", \"kind\": \"Service\"}]" | |||
| } | |||
| }, | |||
| "spec": { | |||
| "ports": [ | |||
| { | |||
| "name": "web", | |||
| "port": 8080, | |||
| "targetPort": 8080 | |||
| } | |||
| ], | |||
| "selector": { | |||
| "name": "${NAME}" | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "kind": "Route", | |||
| "apiVersion": "route.openshift.io/v1", | |||
| "metadata": { | |||
| "name": "${NAME}" | |||
| }, | |||
| "spec": { | |||
| "host": "${APPLICATION_DOMAIN}", | |||
| "to": { | |||
| "kind": "Service", | |||
| "name": "${NAME}" | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "kind": "ImageStream", | |||
| "apiVersion": "image.openshift.io/v1", | |||
| "metadata": { | |||
| "name": "${NAME}", | |||
| "annotations": { | |||
| "description": "Keeps track of changes in the application image" | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "kind": "BuildConfig", | |||
| "apiVersion": "build.openshift.io/v1", | |||
| "metadata": { | |||
| "name": "${NAME}", | |||
| "annotations": { | |||
| "description": "Defines how to build the application", | |||
| "template.alpha.openshift.io/wait-for-ready": "true" | |||
| } | |||
| }, | |||
| "spec": { | |||
| "source": { | |||
| "type": "Git", | |||
| "git": { | |||
| "uri": "${SOURCE_REPOSITORY_URL}", | |||
| "ref": "${SOURCE_REPOSITORY_REF}" | |||
| }, | |||
| "contextDir": "${CONTEXT_DIR}" | |||
| }, | |||
| "strategy": { | |||
| "type": "Source", | |||
| "sourceStrategy": { | |||
| "from": { | |||
| "kind": "ImageStreamTag", | |||
| "namespace": "${NAMESPACE}", | |||
| "name": "python:${PYTHON_VERSION}" | |||
| }, | |||
| "env": [ | |||
| { | |||
| "name": "PIP_INDEX_URL", | |||
| "value": "${PIP_INDEX_URL}" | |||
| } | |||
| ] | |||
| } | |||
| }, | |||
| "output": { | |||
| "to": { | |||
| "kind": "ImageStreamTag", | |||
| "name": "${NAME}:latest" | |||
| } | |||
| }, | |||
| "triggers": [ | |||
| { | |||
| "type": "ImageChange" | |||
| }, | |||
| { | |||
| "type": "ConfigChange" | |||
| }, | |||
| { | |||
| "type": "GitHub", | |||
| "github": { | |||
| "secret": "${GITHUB_WEBHOOK_SECRET}" | |||
| } | |||
| } | |||
| ], | |||
| "postCommit": { | |||
| "script": "./manage.py test" | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "kind": "Deployment", | |||
| "apiVersion": "apps/v1", | |||
| "metadata": { | |||
| "name": "${NAME}", | |||
| "annotations": { | |||
| "description": "Defines how to deploy the application server", | |||
| "template.alpha.openshift.io/wait-for-ready": "true", | |||
| "image.openshift.io/triggers": "[{\"from\":{\"kind\":\"ImageStreamTag\",\"name\":\"${NAME}:latest\"},\"fieldPath\": \"spec.template.spec.containers[0].image\"}]" | |||
| } | |||
| }, | |||
| "spec": { | |||
| "strategy": { | |||
| "type": "Recreate" | |||
| }, | |||
| "replicas": 1, | |||
| "selector": { | |||
| "matchLabels":{ | |||
| "name": "${NAME}" | |||
| } | |||
| }, | |||
| "template": { | |||
| "metadata": { | |||
| "name": "${NAME}", | |||
| "labels": { | |||
| "name": "${NAME}" | |||
| } | |||
| }, | |||
| "spec": { | |||
| "containers": [ | |||
| { | |||
| "name": "django-psql-persistent", | |||
| "image": " ", | |||
| "ports": [ | |||
| { | |||
| "containerPort": 8080 | |||
| } | |||
| ], | |||
| "readinessProbe": { | |||
| "timeoutSeconds": 3, | |||
| "initialDelaySeconds": 3, | |||
| "httpGet": { | |||
| "path": "/health", | |||
| "port": 8080 | |||
| } | |||
| }, | |||
| "livenessProbe": { | |||
| "timeoutSeconds": 3, | |||
| "initialDelaySeconds": 30, | |||
| "httpGet": { | |||
| "path": "/health", | |||
| "port": 8080 | |||
| } | |||
| }, | |||
| "env": [ | |||
| { | |||
| "name": "DATABASE_SERVICE_NAME", | |||
| "value": "${DATABASE_SERVICE_NAME}" | |||
| }, | |||
| { | |||
| "name": "DATABASE_ENGINE", | |||
| "value": "${DATABASE_ENGINE}" | |||
| }, | |||
| { | |||
| "name": "DATABASE_NAME", | |||
| "value": "${DATABASE_NAME}" | |||
| }, | |||
| { | |||
| "name": "DATABASE_USER", | |||
| "valueFrom": { | |||
| "secretKeyRef" : { | |||
| "name" : "${NAME}", | |||
| "key" : "database-user" | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "name": "DATABASE_PASSWORD", | |||
| "valueFrom": { | |||
| "secretKeyRef" : { | |||
| "name" : "${NAME}", | |||
| "key" : "database-password" | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "name": "APP_CONFIG", | |||
| "value": "${APP_CONFIG}" | |||
| }, | |||
| { | |||
| "name": "DJANGO_SECRET_KEY", | |||
| "valueFrom": { | |||
| "secretKeyRef" : { | |||
| "name" : "${NAME}", | |||
| "key" : "django-secret-key" | |||
| } | |||
| } | |||
| } | |||
| ], | |||
| "resources": { | |||
| "limits": { | |||
| "memory": "${MEMORY_LIMIT}" | |||
| } | |||
| } | |||
| } | |||
| ] | |||
| } | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "kind": "PersistentVolumeClaim", | |||
| "apiVersion": "v1", | |||
| "metadata": { | |||
| "name": "${DATABASE_SERVICE_NAME}" | |||
| }, | |||
| "spec": { | |||
| "accessModes": [ | |||
| "ReadWriteOnce" | |||
| ], | |||
| "resources": { | |||
| "requests": { | |||
| "storage": "${VOLUME_CAPACITY}" | |||
| } | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "kind": "Service", | |||
| "apiVersion": "v1", | |||
| "metadata": { | |||
| "name": "${DATABASE_SERVICE_NAME}", | |||
| "annotations": { | |||
| "description": "Exposes the database server" | |||
| } | |||
| }, | |||
| "spec": { | |||
| "ports": [ | |||
| { | |||
| "name": "postgresql", | |||
| "port": 5432, | |||
| "targetPort": 5432 | |||
| } | |||
| ], | |||
| "selector": { | |||
| "name": "${DATABASE_SERVICE_NAME}" | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "kind": "Deployment", | |||
| "apiVersion": "apps/v1", | |||
| "metadata": { | |||
| "name": "${DATABASE_SERVICE_NAME}", | |||
| "annotations": { | |||
| "description": "Defines how to deploy the database", | |||
| "template.alpha.openshift.io/wait-for-ready": "true", | |||
| "image.openshift.io/triggers": "[{\"from\":{\"kind\":\"ImageStreamTag\",\"name\":\"postgresql:${POSTGRESQL_VERSION}\"},\"fieldPath\": \"spec.template.spec.containers[0].image\"}]" | |||
| } | |||
| }, | |||
| "spec": { | |||
| "strategy": { | |||
| "type": "Recreate" | |||
| }, | |||
| "replicas": 1, | |||
| "selector": { | |||
| "matchLabels":{ | |||
| "name": "${DATABASE_SERVICE_NAME}" | |||
| } | |||
| }, | |||
| "template": { | |||
| "metadata": { | |||
| "name": "${DATABASE_SERVICE_NAME}", | |||
| "labels": { | |||
| "name": "${DATABASE_SERVICE_NAME}" | |||
| } | |||
| }, | |||
| "spec": { | |||
| "volumes": [ | |||
| { | |||
| "name": "${DATABASE_SERVICE_NAME}-data", | |||
| "persistentVolumeClaim": { | |||
| "claimName": "${DATABASE_SERVICE_NAME}" | |||
| } | |||
| } | |||
| ], | |||
| "containers": [ | |||
| { | |||
| "name": "postgresql", | |||
| "image": " ", | |||
| "ports": [ | |||
| { | |||
| "containerPort": 5432 | |||
| } | |||
| ], | |||
| "env": [ | |||
| { | |||
| "name": "POSTGRESQL_USER", | |||
| "valueFrom": { | |||
| "secretKeyRef" : { | |||
| "name" : "${NAME}", | |||
| "key" : "database-user" | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "name": "POSTGRESQL_PASSWORD", | |||
| "valueFrom": { | |||
| "secretKeyRef" : { | |||
| "name" : "${NAME}", | |||
| "key" : "database-password" | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "name": "POSTGRESQL_DATABASE", | |||
| "value": "${DATABASE_NAME}" | |||
| } | |||
| ], | |||
| "volumeMounts": [ | |||
| { | |||
| "name": "${DATABASE_SERVICE_NAME}-data", | |||
| "mountPath": "/var/lib/pgsql/data" | |||
| } | |||
| ], | |||
| "readinessProbe": { | |||
| "timeoutSeconds": 1, | |||
| "initialDelaySeconds": 5, | |||
| "exec": { | |||
| "command": [ "/usr/libexec/check-container" ] | |||
| } | |||
| }, | |||
| "livenessProbe": { | |||
| "timeoutSeconds": 10, | |||
| "initialDelaySeconds": 120, | |||
| "exec": { | |||
| "command": [ "/usr/libexec/check-container", "--live" ] | |||
| } | |||
| }, | |||
| "resources": { | |||
| "limits": { | |||
| "memory": "${MEMORY_POSTGRESQL_LIMIT}" | |||
| } | |||
| } | |||
| } | |||
| ] | |||
| } | |||
| } | |||
| } | |||
| } | |||
| ], | |||
| "parameters": [ | |||
| { | |||
| "name": "NAME", | |||
| "displayName": "Name", | |||
| "description": "The name assigned to all of the frontend objects defined in this template.", | |||
| "required": true, | |||
| "value": "django-psql-persistent" | |||
| }, | |||
| { | |||
| "name": "NAMESPACE", | |||
| "displayName": "Namespace", | |||
| "required": true, | |||
| "description": "The OpenShift Namespace where the ImageStream resides.", | |||
| "value": "openshift" | |||
| }, | |||
| { | |||
| "name": "PYTHON_VERSION", | |||
| "displayName": "Version of Python Image", | |||
| "description": "Version of Python image to be used (3.6-ubi8, 3.8-ubi7, 3.8-ubi8, or latest).", | |||
| "value": "3.8-ubi8", | |||
| "required": true | |||
| }, | |||
| { | |||
| "name": "POSTGRESQL_VERSION", | |||
| "displayName": "Version of PostgreSQL Image", | |||
| "description": "Version of PostgreSQL image to be used (10-el8, 12-el8, or latest).", | |||
| "value": "12-el8", | |||
| "required": true | |||
| }, | |||
| { | |||
| "name": "MEMORY_LIMIT", | |||
| "displayName": "Memory Limit", | |||
| "required": true, | |||
| "description": "Maximum amount of memory the Django container can use.", | |||
| "value": "512Mi" | |||
| }, | |||
| { | |||
| "name": "MEMORY_POSTGRESQL_LIMIT", | |||
| "displayName": "Memory Limit (PostgreSQL)", | |||
| "required": true, | |||
| "description": "Maximum amount of memory the PostgreSQL container can use.", | |||
| "value": "512Mi" | |||
| }, | |||
| { | |||
| "name": "VOLUME_CAPACITY", | |||
| "displayName": "Volume Capacity", | |||
| "description": "Volume space available for data, e.g. 512Mi, 2Gi", | |||
| "value": "1Gi", | |||
| "required": true | |||
| }, | |||
| { | |||
| "name": "SOURCE_REPOSITORY_URL", | |||
| "displayName": "Git Repository URL", | |||
| "required": true, | |||
| "description": "The URL of the repository with your application source code.", | |||
| "value": "https://github.com/sclorg/django-ex.git" | |||
| }, | |||
| { | |||
| "name": "SOURCE_REPOSITORY_REF", | |||
| "displayName": "Git Reference", | |||
| "description": "Set this to a branch name, tag or other ref of your repository if you are not using the default branch." | |||
| }, | |||
| { | |||
| "name": "CONTEXT_DIR", | |||
| "displayName": "Context Directory", | |||
| "description": "Set this to the relative path to your project if it is not in the root of your repository." | |||
| }, | |||
| { | |||
| "name": "APPLICATION_DOMAIN", | |||
| "displayName": "Application Hostname", | |||
| "description": "The exposed hostname that will route to the Django service, if left blank a value will be defaulted.", | |||
| "value": "" | |||
| }, | |||
| { | |||
| "name": "GITHUB_WEBHOOK_SECRET", | |||
| "displayName": "GitHub Webhook Secret", | |||
| "description": "Github trigger secret. A difficult to guess string encoded as part of the webhook URL. Not encrypted.", | |||
| "generate": "expression", | |||
| "from": "[a-zA-Z0-9]{40}" | |||
| }, | |||
| { | |||
| "name": "DATABASE_SERVICE_NAME", | |||
| "displayName": "Database Service Name", | |||
| "required": true, | |||
| "value": "postgresql" | |||
| }, | |||
| { | |||
| "name": "DATABASE_ENGINE", | |||
| "displayName": "Database Engine", | |||
| "required": true, | |||
| "description": "Database engine: postgresql, mysql or sqlite (default).", | |||
| "value": "postgresql" | |||
| }, | |||
| { | |||
| "name": "DATABASE_NAME", | |||
| "displayName": "Database Name", | |||
| "required": true, | |||
| "value": "default" | |||
| }, | |||
| { | |||
| "name": "DATABASE_USER", | |||
| "displayName": "Database Username", | |||
| "required": true, | |||
| "value": "django" | |||
| }, | |||
| { | |||
| "name": "DATABASE_PASSWORD", | |||
| "displayName": "Database User Password", | |||
| "generate": "expression", | |||
| "from": "[a-zA-Z0-9]{16}" | |||
| }, | |||
| { | |||
| "name": "APP_CONFIG", | |||
| "displayName": "Application Configuration File Path", | |||
| "description": "Relative path to Gunicorn configuration file (optional)." | |||
| }, | |||
| { | |||
| "name": "DJANGO_SECRET_KEY", | |||
| "displayName": "Django Secret Key", | |||
| "description": "Set this to a long random string.", | |||
| "generate": "expression", | |||
| "from": "[\\w]{50}" | |||
| }, | |||
| { | |||
| "name": "PIP_INDEX_URL", | |||
| "displayName": "Custom PyPi Index URL", | |||
| "description": "The custom PyPi index URL", | |||
| "value": "" | |||
| } | |||
| ] | |||
| } | |||
| @ -1,498 +0,0 @@ | |||
| { | |||
| "kind": "Template", | |||
| "apiVersion": "template.openshift.io/v1", | |||
| "metadata": { | |||
| "name": "django-psql-example", | |||
| "annotations": { | |||
| "openshift.io/display-name": "Django + PostgreSQL (Ephemeral)", | |||
| "description": "An example Django application with a PostgreSQL database. For more information about using this template, including OpenShift considerations, see https://github.com/sclorg/django-ex/blob/master/README.md.\n\nWARNING: Any data stored will be lost upon pod destruction. Only use this template for testing.", | |||
| "tags": "quickstart,python,django", | |||
| "iconClass": "icon-python", | |||
| "openshift.io/long-description": "This template defines resources needed to develop a Django based application, including a build configuration, application deployment configuration, and database deployment configuration. The database is stored in non-persistent storage, so this configuration should be used for experimental purposes only.", | |||
| "openshift.io/provider-display-name": "Red Hat, Inc.", | |||
| "openshift.io/documentation-url": "https://github.com/sclorg/django-ex", | |||
| "openshift.io/support-url": "https://access.redhat.com", | |||
| "template.openshift.io/bindable": "false" | |||
| } | |||
| }, | |||
| "message": "The following service(s) have been created in your project: ${NAME}, ${DATABASE_SERVICE_NAME}.\n\nFor more information about using this template, including OpenShift considerations, see https://github.com/sclorg/django-ex/blob/master/README.md.", | |||
| "labels": { | |||
| "template": "django-psql-example", | |||
| "app": "django-psql-example" | |||
| }, | |||
| "objects": [ | |||
| { | |||
| "kind": "Secret", | |||
| "apiVersion": "v1", | |||
| "metadata": { | |||
| "name": "${NAME}" | |||
| }, | |||
| "stringData" : { | |||
| "database-user" : "${DATABASE_USER}", | |||
| "database-password" : "${DATABASE_PASSWORD}", | |||
| "django-secret-key" : "${DJANGO_SECRET_KEY}" | |||
| } | |||
| }, | |||
| { | |||
| "kind": "Service", | |||
| "apiVersion": "v1", | |||
| "metadata": { | |||
| "name": "${NAME}", | |||
| "annotations": { | |||
| "description": "Exposes and load balances the application pods", | |||
| "service.alpha.openshift.io/dependencies": "[{\"name\": \"${DATABASE_SERVICE_NAME}\", \"kind\": \"Service\"}]" | |||
| } | |||
| }, | |||
| "spec": { | |||
| "ports": [ | |||
| { | |||
| "name": "web", | |||
| "port": 8080, | |||
| "targetPort": 8080 | |||
| } | |||
| ], | |||
| "selector": { | |||
| "name": "${NAME}" | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "kind": "Route", | |||
| "apiVersion": "route.openshift.io/v1", | |||
| "metadata": { | |||
| "name": "${NAME}" | |||
| }, | |||
| "spec": { | |||
| "host": "${APPLICATION_DOMAIN}", | |||
| "to": { | |||
| "kind": "Service", | |||
| "name": "${NAME}" | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "kind": "ImageStream", | |||
| "apiVersion": "image.openshift.io/v1", | |||
| "metadata": { | |||
| "name": "${NAME}", | |||
| "annotations": { | |||
| "description": "Keeps track of changes in the application image" | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "kind": "BuildConfig", | |||
| "apiVersion": "build.openshift.io/v1", | |||
| "metadata": { | |||
| "name": "${NAME}", | |||
| "annotations": { | |||
| "description": "Defines how to build the application", | |||
| "template.alpha.openshift.io/wait-for-ready": "true" | |||
| } | |||
| }, | |||
| "spec": { | |||
| "source": { | |||
| "type": "Git", | |||
| "git": { | |||
| "uri": "${SOURCE_REPOSITORY_URL}", | |||
| "ref": "${SOURCE_REPOSITORY_REF}" | |||
| }, | |||
| "contextDir": "${CONTEXT_DIR}" | |||
| }, | |||
| "strategy": { | |||
| "type": "Source", | |||
| "sourceStrategy": { | |||
| "from": { | |||
| "kind": "ImageStreamTag", | |||
| "namespace": "${NAMESPACE}", | |||
| "name": "python:${PYTHON_VERSION}" | |||
| }, | |||
| "env": [ | |||
| { | |||
| "name": "PIP_INDEX_URL", | |||
| "value": "${PIP_INDEX_URL}" | |||
| } | |||
| ] | |||
| } | |||
| }, | |||
| "output": { | |||
| "to": { | |||
| "kind": "ImageStreamTag", | |||
| "name": "${NAME}:latest" | |||
| } | |||
| }, | |||
| "triggers": [ | |||
| { | |||
| "type": "ImageChange" | |||
| }, | |||
| { | |||
| "type": "ConfigChange" | |||
| }, | |||
| { | |||
| "type": "GitHub", | |||
| "github": { | |||
| "secret": "${GITHUB_WEBHOOK_SECRET}" | |||
| } | |||
| } | |||
| ], | |||
| "postCommit": { | |||
| "script": "./manage.py test" | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "kind": "Deployment", | |||
| "apiVersion": "apps/v1", | |||
| "metadata": { | |||
| "name": "${NAME}", | |||
| "annotations": { | |||
| "description": "Defines how to deploy the application server", | |||
| "template.alpha.openshift.io/wait-for-ready": "true", | |||
| "image.openshift.io/triggers": "[{\"from\":{\"kind\":\"ImageStreamTag\",\"name\":\"${NAME}:latest\"},\"fieldPath\": \"spec.template.spec.containers[0].image\"}]" | |||
| } | |||
| }, | |||
| "spec": { | |||
| "strategy": { | |||
| "type": "Recreate" | |||
| }, | |||
| "replicas": 1, | |||
| "selector": { | |||
| "matchLabels":{ | |||
| "name": "${NAME}" | |||
| } | |||
| }, | |||
| "template": { | |||
| "metadata": { | |||
| "name": "${NAME}", | |||
| "labels": { | |||
| "name": "${NAME}" | |||
| } | |||
| }, | |||
| "spec": { | |||
| "containers": [ | |||
| { | |||
| "name": "django-psql-example", | |||
| "image": " ", | |||
| "ports": [ | |||
| { | |||
| "containerPort": 8080 | |||
| } | |||
| ], | |||
| "readinessProbe": { | |||
| "timeoutSeconds": 3, | |||
| "initialDelaySeconds": 3, | |||
| "httpGet": { | |||
| "path": "/health", | |||
| "port": 8080 | |||
| } | |||
| }, | |||
| "livenessProbe": { | |||
| "timeoutSeconds": 3, | |||
| "initialDelaySeconds": 30, | |||
| "httpGet": { | |||
| "path": "/health", | |||
| "port": 8080 | |||
| } | |||
| }, | |||
| "env": [ | |||
| { | |||
| "name": "DATABASE_SERVICE_NAME", | |||
| "value": "${DATABASE_SERVICE_NAME}" | |||
| }, | |||
| { | |||
| "name": "DATABASE_ENGINE", | |||
| "value": "${DATABASE_ENGINE}" | |||
| }, | |||
| { | |||
| "name": "DATABASE_NAME", | |||
| "value": "${DATABASE_NAME}" | |||
| }, | |||
| { | |||
| "name": "DATABASE_USER", | |||
| "valueFrom": { | |||
| "secretKeyRef" : { | |||
| "name" : "${NAME}", | |||
| "key" : "database-user" | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "name": "DATABASE_PASSWORD", | |||
| "valueFrom": { | |||
| "secretKeyRef" : { | |||
| "name" : "${NAME}", | |||
| "key" : "database-password" | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "name": "APP_CONFIG", | |||
| "value": "${APP_CONFIG}" | |||
| }, | |||
| { | |||
| "name": "DJANGO_SECRET_KEY", | |||
| "valueFrom": { | |||
| "secretKeyRef" : { | |||
| "name" : "${NAME}", | |||
| "key" : "django-secret-key" | |||
| } | |||
| } | |||
| } | |||
| ], | |||
| "resources": { | |||
| "limits": { | |||
| "memory": "${MEMORY_LIMIT}" | |||
| } | |||
| } | |||
| } | |||
| ] | |||
| } | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "kind": "Service", | |||
| "apiVersion": "v1", | |||
| "metadata": { | |||
| "name": "${DATABASE_SERVICE_NAME}", | |||
| "annotations": { | |||
| "description": "Exposes the database server" | |||
| } | |||
| }, | |||
| "spec": { | |||
| "ports": [ | |||
| { | |||
| "name": "postgresql", | |||
| "port": 5432, | |||
| "targetPort": 5432 | |||
| } | |||
| ], | |||
| "selector": { | |||
| "name": "${DATABASE_SERVICE_NAME}" | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "kind": "Deployment", | |||
| "apiVersion": "apps/v1", | |||
| "metadata": { | |||
| "name": "${DATABASE_SERVICE_NAME}", | |||
| "annotations": { | |||
| "description": "Defines how to deploy the database", | |||
| "template.alpha.openshift.io/wait-for-ready": "true", | |||
| "image.openshift.io/triggers": "[{\"from\":{\"kind\":\"ImageStreamTag\",\"name\":\"postgresql:${POSTGRESQL_VERSION}\"},\"fieldPath\": \"spec.template.spec.containers[0].image\"}]" | |||
| } | |||
| }, | |||
| "spec": { | |||
| "strategy": { | |||
| "type": "Recreate" | |||
| }, | |||
| "replicas": 1, | |||
| "selector": { | |||
| "matchLabels":{ | |||
| "name": "${DATABASE_SERVICE_NAME}" | |||
| } | |||
| }, | |||
| "template": { | |||
| "metadata": { | |||
| "name": "${DATABASE_SERVICE_NAME}", | |||
| "labels": { | |||
| "name": "${DATABASE_SERVICE_NAME}" | |||
| } | |||
| }, | |||
| "spec": { | |||
| "volumes": [ | |||
| { | |||
| "name": "data", | |||
| "emptyDir": {} | |||
| } | |||
| ], | |||
| "containers": [ | |||
| { | |||
| "name": "postgresql", | |||
| "image": " ", | |||
| "ports": [ | |||
| { | |||
| "containerPort": 5432 | |||
| } | |||
| ], | |||
| "env": [ | |||
| { | |||
| "name": "POSTGRESQL_USER", | |||
| "valueFrom": { | |||
| "secretKeyRef" : { | |||
| "name" : "${NAME}", | |||
| "key" : "database-user" | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "name": "POSTGRESQL_PASSWORD", | |||
| "valueFrom": { | |||
| "secretKeyRef" : { | |||
| "name" : "${NAME}", | |||
| "key" : "database-password" | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "name": "POSTGRESQL_DATABASE", | |||
| "value": "${DATABASE_NAME}" | |||
| } | |||
| ], | |||
| "volumeMounts": [ | |||
| { | |||
| "name": "data", | |||
| "mountPath": "/var/lib/pgsql/data" | |||
| } | |||
| ], | |||
| "readinessProbe": { | |||
| "timeoutSeconds": 1, | |||
| "initialDelaySeconds": 5, | |||
| "exec": { | |||
| "command": [ "/usr/libexec/check-container" ] | |||
| } | |||
| }, | |||
| "livenessProbe": { | |||
| "timeoutSeconds": 10, | |||
| "initialDelaySeconds": 120, | |||
| "exec": { | |||
| "command": [ "/usr/libexec/check-container", "--live" ] | |||
| } | |||
| }, | |||
| "resources": { | |||
| "limits": { | |||
| "memory": "${MEMORY_POSTGRESQL_LIMIT}" | |||
| } | |||
| } | |||
| } | |||
| ] | |||
| } | |||
| } | |||
| } | |||
| } | |||
| ], | |||
| "parameters": [ | |||
| { | |||
| "name": "NAME", | |||
| "displayName": "Name", | |||
| "description": "The name assigned to all of the frontend objects defined in this template.", | |||
| "required": true, | |||
| "value": "django-psql-example" | |||
| }, | |||
| { | |||
| "name": "NAMESPACE", | |||
| "displayName": "Namespace", | |||
| "required": true, | |||
| "description": "The OpenShift Namespace where the ImageStream resides.", | |||
| "value": "openshift" | |||
| }, | |||
| { | |||
| "name": "PYTHON_VERSION", | |||
| "displayName": "Version of Python Image", | |||
| "description": "Version of Python image to be used (3.6-ubi8, 3.8-ubi7, 3.8-ubi8, or latest).", | |||
| "value": "3.8-ubi8", | |||
| "required": true | |||
| }, | |||
| { | |||
| "name": "POSTGRESQL_VERSION", | |||
| "displayName": "Version of PostgreSQL Image", | |||
| "description": "Version of PostgreSQL image to be used (10-el8, 12-el8, or latest).", | |||
| "value": "12-el8", | |||
| "required": true | |||
| }, | |||
| { | |||
| "name": "MEMORY_LIMIT", | |||
| "displayName": "Memory Limit", | |||
| "required": true, | |||
| "description": "Maximum amount of memory the Django container can use.", | |||
| "value": "512Mi" | |||
| }, | |||
| { | |||
| "name": "MEMORY_POSTGRESQL_LIMIT", | |||
| "displayName": "Memory Limit (PostgreSQL)", | |||
| "required": true, | |||
| "description": "Maximum amount of memory the PostgreSQL container can use.", | |||
| "value": "512Mi" | |||
| }, | |||
| { | |||
| "name": "SOURCE_REPOSITORY_URL", | |||
| "displayName": "Git Repository URL", | |||
| "required": true, | |||
| "description": "The URL of the repository with your application source code.", | |||
| "value": "https://github.com/sclorg/django-ex.git" | |||
| }, | |||
| { | |||
| "name": "SOURCE_REPOSITORY_REF", | |||
| "displayName": "Git Reference", | |||
| "description": "Set this to a branch name, tag or other ref of your repository if you are not using the default branch." | |||
| }, | |||
| { | |||
| "name": "CONTEXT_DIR", | |||
| "displayName": "Context Directory", | |||
| "description": "Set this to the relative path to your project if it is not in the root of your repository." | |||
| }, | |||
| { | |||
| "name": "APPLICATION_DOMAIN", | |||
| "displayName": "Application Hostname", | |||
| "description": "The exposed hostname that will route to the Django service, if left blank a value will be defaulted.", | |||
| "value": "" | |||
| }, | |||
| { | |||
| "name": "GITHUB_WEBHOOK_SECRET", | |||
| "displayName": "GitHub Webhook Secret", | |||
| "description": "Github trigger secret. A difficult to guess string encoded as part of the webhook URL. Not encrypted.", | |||
| "generate": "expression", | |||
| "from": "[a-zA-Z0-9]{40}" | |||
| }, | |||
| { | |||
| "name": "DATABASE_SERVICE_NAME", | |||
| "displayName": "Database Service Name", | |||
| "required": true, | |||
| "value": "postgresql" | |||
| }, | |||
| { | |||
| "name": "DATABASE_ENGINE", | |||
| "displayName": "Database Engine", | |||
| "required": true, | |||
| "description": "Database engine: postgresql, mysql or sqlite (default).", | |||
| "value": "postgresql" | |||
| }, | |||
| { | |||
| "name": "DATABASE_NAME", | |||
| "displayName": "Database Name", | |||
| "required": true, | |||
| "value": "default" | |||
| }, | |||
| { | |||
| "name": "DATABASE_USER", | |||
| "displayName": "Database Username", | |||
| "required": true, | |||
| "value": "django" | |||
| }, | |||
| { | |||
| "name": "DATABASE_PASSWORD", | |||
| "displayName": "Database User Password", | |||
| "generate": "expression", | |||
| "from": "[a-zA-Z0-9]{16}" | |||
| }, | |||
| { | |||
| "name": "APP_CONFIG", | |||
| "displayName": "Application Configuration File Path", | |||
| "description": "Relative path to Gunicorn configuration file (optional)." | |||
| }, | |||
| { | |||
| "name": "DJANGO_SECRET_KEY", | |||
| "displayName": "Django Secret Key", | |||
| "description": "Set this to a long random string.", | |||
| "generate": "expression", | |||
| "from": "[\\w]{50}" | |||
| }, | |||
| { | |||
| "name": "PIP_INDEX_URL", | |||
| "displayName": "Custom PyPi Index URL", | |||
| "description": "The custom PyPi index URL", | |||
| "value": "" | |||
| } | |||
| ] | |||
| } | |||
| @ -1,299 +0,0 @@ | |||
| { | |||
| "kind": "Template", | |||
| "apiVersion": "template.openshift.io/v1", | |||
| "metadata": { | |||
| "name": "polls", | |||
| "annotations": { | |||
| "openshift.io/display-name": "Django", | |||
| "description": "Aplicación sacada del tutorial de Django: https://docs.djangoproject.com/en/5.1/intro/tutorial01/.", | |||
| "tags": "quickstart,python,django", | |||
| "iconClass": "icon-python", | |||
| "openshift.io/long-description": "This template defines resources needed to develop a Django based application, including a build configuration and application deployment configuration. It does not include a database.", | |||
| "openshift.io/provider-display-name": "ReyMota.", | |||
| "openshift.io/documentation-url": "http://gitea.reymota.es/creylopez/djangotutorial", | |||
| "openshift.io/support-url": "https://reymota.es", | |||
| "template.openshift.io/bindable": "false" | |||
| } | |||
| }, | |||
| "labels": { | |||
| "template": "polls", | |||
| "app": "polls" | |||
| }, | |||
| "message": "The following service(s) have been created in your project: ${NAME}.\n\nFor more information about using this template, including OpenShift considerations, see https://github.com/sclorg/django-ex/blob/master/README.md.", | |||
| "objects": [ | |||
| { | |||
| "kind": "Secret", | |||
| "apiVersion": "v1", | |||
| "metadata": { | |||
| "name": "${NAME}" | |||
| }, | |||
| "stringData" : { | |||
| "django-secret-key" : "${DJANGO_SECRET_KEY}" | |||
| } | |||
| }, | |||
| { | |||
| "kind": "Service", | |||
| "apiVersion": "v1", | |||
| "metadata": { | |||
| "name": "${NAME}", | |||
| "annotations": { | |||
| "description": "Exposes and load balances the application pods" | |||
| } | |||
| }, | |||
| "spec": { | |||
| "ports": [ | |||
| { | |||
| "name": "web", | |||
| "port": 8080, | |||
| "targetPort": 8080 | |||
| } | |||
| ], | |||
| "selector": { | |||
| "name": "${NAME}" | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "kind": "Route", | |||
| "apiVersion": "route.openshift.io/v1", | |||
| "metadata": { | |||
| "name": "${NAME}" | |||
| }, | |||
| "spec": { | |||
| "host": "${APPLICATION_DOMAIN}", | |||
| "to": { | |||
| "kind": "Service", | |||
| "name": "${NAME}" | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "kind": "ImageStream", | |||
| "apiVersion": "image.openshift.io/v1", | |||
| "metadata": { | |||
| "name": "${NAME}", | |||
| "annotations": { | |||
| "description": "Keeps track of changes in the application image" | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "kind": "BuildConfig", | |||
| "apiVersion": "build.openshift.io/v1", | |||
| "metadata": { | |||
| "name": "${NAME}", | |||
| "annotations": { | |||
| "description": "Defines how to build the application", | |||
| "template.alpha.openshift.io/wait-for-ready": "true" | |||
| } | |||
| }, | |||
| "spec": { | |||
| "source": { | |||
| "type": "Git", | |||
| "git": { | |||
| "uri": "${SOURCE_REPOSITORY_URL}", | |||
| "ref": "${SOURCE_REPOSITORY_REF}" | |||
| }, | |||
| "contextDir": "${CONTEXT_DIR}" | |||
| }, | |||
| "strategy": { | |||
| "type": "Source", | |||
| "sourceStrategy": { | |||
| "from": { | |||
| "kind": "ImageStreamTag", | |||
| "namespace": "${NAMESPACE}", | |||
| "name": "python:${PYTHON_VERSION}" | |||
| }, | |||
| "env": [ | |||
| { | |||
| "name": "PIP_INDEX_URL", | |||
| "value": "${PIP_INDEX_URL}" | |||
| } | |||
| ] | |||
| } | |||
| }, | |||
| "output": { | |||
| "to": { | |||
| "kind": "ImageStreamTag", | |||
| "name": "${NAME}:latest" | |||
| } | |||
| }, | |||
| "triggers": [ | |||
| { | |||
| "type": "ImageChange" | |||
| }, | |||
| { | |||
| "type": "ConfigChange" | |||
| }, | |||
| { | |||
| "type": "GitHub", | |||
| "github": { | |||
| "secret": "${GITHUB_WEBHOOK_SECRET}" | |||
| } | |||
| } | |||
| ], | |||
| "postCommit": { | |||
| "script": "./manage.py test" | |||
| } | |||
| } | |||
| }, | |||
| { | |||
| "kind": "Deployment", | |||
| "apiVersion": "apps/v1", | |||
| "metadata": { | |||
| "name": "${NAME}", | |||
| "annotations": { | |||
| "description": "Defines how to deploy the application server", | |||
| "template.alpha.openshift.io/wait-for-ready": "true", | |||
| "image.openshift.io/triggers": "[{\"from\":{\"kind\":\"ImageStreamTag\",\"name\":\"${NAME}:latest\"},\"fieldPath\": \"spec.template.spec.containers[0].image\"}]" | |||
| } | |||
| }, | |||
| "spec": { | |||
| "strategy": { | |||
| "type": "RollingUpdate" | |||
| }, | |||
| "replicas": 1, | |||
| "selector": { | |||
| "matchLabels":{ | |||
| "name": "${NAME}" | |||
| } | |||
| }, | |||
| "template": { | |||
| "metadata": { | |||
| "name": "${NAME}", | |||
| "labels": { | |||
| "name": "${NAME}" | |||
| } | |||
| }, | |||
| "spec": { | |||
| "containers": [ | |||
| { | |||
| "name": "polls", | |||
| "image": " ", | |||
| "ports": [ | |||
| { | |||
| "containerPort": 8080 | |||
| } | |||
| ], | |||
| "readinessProbe": { | |||
| "timeoutSeconds": 3, | |||
| "initialDelaySeconds": 3, | |||
| "httpGet": { | |||
| "path": "/", | |||
| "port": 8080 | |||
| } | |||
| }, | |||
| "livenessProbe": { | |||
| "timeoutSeconds": 3, | |||
| "initialDelaySeconds": 30, | |||
| "httpGet": { | |||
| "path": "/", | |||
| "port": 8080 | |||
| } | |||
| }, | |||
| "env": [ | |||
| { | |||
| "name": "APP_CONFIG", | |||
| "value": "${APP_CONFIG}" | |||
| }, | |||
| { | |||
| "name": "DJANGO_SECRET_KEY", | |||
| "valueFrom": { | |||
| "secretKeyRef" : { | |||
| "name" : "${NAME}", | |||
| "key" : "django-secret-key" | |||
| } | |||
| } | |||
| } | |||
| ], | |||
| "resources": { | |||
| "limits": { | |||
| "memory": "${MEMORY_LIMIT}" | |||
| } | |||
| } | |||
| } | |||
| ] | |||
| } | |||
| } | |||
| } | |||
| } | |||
| ], | |||
| "parameters": [ | |||
| { | |||
| "name": "NAME", | |||
| "displayName": "Name", | |||
| "description": "The name assigned to all of the frontend objects defined in this template.", | |||
| "required": true, | |||
| "value": "polls" | |||
| }, | |||
| { | |||
| "name": "NAMESPACE", | |||
| "displayName": "Namespace", | |||
| "required": true, | |||
| "description": "The OpenShift Namespace where the ImageStream resides.", | |||
| "value": "openshift" | |||
| }, | |||
| { | |||
| "name": "PYTHON_VERSION", | |||
| "displayName": "Version of Python Image", | |||
| "description": "Version of Python image to be used (3.6-ubi8, 3.8-ubi7, 3.8-ubi8, or latest).", | |||
| "value": "latest", | |||
| "required": true | |||
| }, | |||
| { | |||
| "name": "MEMORY_LIMIT", | |||
| "displayName": "Memory Limit", | |||
| "required": true, | |||
| "description": "Maximum amount of memory the container can use.", | |||
| "value": "512Mi" | |||
| }, | |||
| { | |||
| "name": "SOURCE_REPOSITORY_URL", | |||
| "displayName": "Git Repository URL", | |||
| "required": true, | |||
| "description": "The URL of the repository with your application source code.", | |||
| "value": "https://github.com/sclorg/django-ex.git" | |||
| }, | |||
| { | |||
| "name": "SOURCE_REPOSITORY_REF", | |||
| "displayName": "Git Reference", | |||
| "description": "Set this to a branch name, tag or other ref of your repository if you are not using the default branch." | |||
| }, | |||
| { | |||
| "name": "CONTEXT_DIR", | |||
| "displayName": "Context Directory", | |||
| "description": "Set this to the relative path to your project if it is not in the root of your repository." | |||
| }, | |||
| { | |||
| "name": "APPLICATION_DOMAIN", | |||
| "displayName": "Application Hostname", | |||
| "description": "The exposed hostname that will route to the Django service, if left blank a value will be defaulted.", | |||
| "value": "" | |||
| }, | |||
| { | |||
| "name": "GITHUB_WEBHOOK_SECRET", | |||
| "displayName": "GitHub Webhook Secret", | |||
| "description": "Github trigger secret. A difficult to guess string encoded as part of the webhook URL. Not encrypted.", | |||
| "generate": "expression", | |||
| "from": "[a-zA-Z0-9]{40}" | |||
| }, | |||
| { | |||
| "name": "APP_CONFIG", | |||
| "displayName": "Application Configuration File Path", | |||
| "description": "Relative path to Gunicorn configuration file (optional)." | |||
| }, | |||
| { | |||
| "name": "DJANGO_SECRET_KEY", | |||
| "displayName": "Django Secret Key", | |||
| "description": "Set this to a long random string.", | |||
| "generate": "expression", | |||
| "from": "[\\w]{50}" | |||
| }, | |||
| { | |||
| "name": "PIP_INDEX_URL", | |||
| "displayName": "Custom PyPi Index URL", | |||
| "description": "The custom PyPi index URL", | |||
| "value": "" | |||
| } | |||
| ] | |||
| } | |||
| @ -0,0 +1,9 @@ | |||
| #!/bin/bash | |||
| RUN_PORT="8000" | |||
| /opt/venv/bin/python manage.py migrate --no-input | |||
| /opt/venv/bin/python manage.py collectstatic --no-input | |||
| /opt/venv/bin/gunicorn mysite.wsgi:application --bind "0.0.0.0:${RUN_PORT}" --daemon | |||
| nginx -g 'daemon off;' | |||
| @ -0,0 +1,21 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <svg width="215px" height="215px" viewBox="0 0 215 215" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | |||
| <!-- Generator: Sketch 52.6 (67491) - http://www.bohemiancoding.com/sketch --> | |||
| <title>portal-logo</title> | |||
| <desc>Created with Sketch.</desc> | |||
| <defs> | |||
| <path d="M51.165,8.742 C54.505,12.619 56.876,17.365 57.892,22.588 C60.148,17.225 65.452,13.46 71.636,13.46 C79.867,13.46 86.541,20.134 86.541,28.365 C86.541,36.597 79.867,43.269 71.636,43.269 C63.404,43.269 56.728,36.597 56.728,28.365 C56.728,12.7 44.03,0 28.365,0 C12.7,0 0,12.7 0,28.365 C0,44.031 12.7,56.731 28.365,56.731 C36.419,56.731 43.695,53.393 48.858,48.003 C45.501,44.117 43.128,39.383 42.108,34.14 C39.852,39.504 34.548,43.269 28.365,43.269 C20.133,43.269 13.46,36.597 13.46,28.365 C13.46,20.134 20.133,13.46 28.365,13.46 C36.966,13.46 43.27,20.577 43.27,28.365 C43.27,44.031 55.97,56.731 71.636,56.731 C87.3,56.731 100,44.031 100,28.365 C100,12.7 87.3,0 71.636,0 C63.589,0 56.327,3.358 51.165,8.742 Z" id="path-1"></path> | |||
| </defs> | |||
| <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | |||
| <g id="portal-logo"> | |||
| <circle id="Oval" fill="#51B37F" fill-rule="nonzero" cx="107.5" cy="107.5" r="107.5"></circle> | |||
| <g id="logo" transform="translate(58.000000, 79.000000)"> | |||
| <mask id="mask-2" fill="white"> | |||
| <use xlink:href="#path-1"></use> | |||
| </mask> | |||
| <g id="Clip-2"></g> | |||
| <polygon id="Fill-1" fill="#FFFFFE" mask="url(#mask-2)" points="-5 61.73 105 61.73 105 -5 -5 -5"></polygon> | |||
| </g> | |||
| </g> | |||
| </g> | |||
| </svg> | |||
| @ -0,0 +1,50 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <!-- Generator: Adobe Illustrator 23.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> | |||
| <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" | |||
| viewBox="0 0 595.3 595.3" enable-background="new 0 0 595.3 595.3" xml:space="preserve"> | |||
| <g id="Capa_1"> | |||
| </g> | |||
| <g id="Capa_2"> | |||
| <g> | |||
| <path fill="none" stroke="#365954" stroke-width="5.9888" stroke-miterlimit="10" d="M283.6,554.1c8.2,14.1,32.6,14.6,41.4,0.8 | |||
| c4.7-7.3,5.1-16.7,10.3-23.6c6.8-9.1,19.4-11.3,30.8-12.8c9.3-1.2,18.5-2.4,27.8-3.7c6.8-0.9,13.8-1.9,19.4-5.6 | |||
| c4.1-2.7,14.1-7.9,18.2-10.5c13-8.2-4.9-20.2-21.3-13.8c-10.8,4.2-14.5,7.2-25.7,10.1c-15.5,4-29.2,14.3-37.3,28"/> | |||
| </g> | |||
| <path fill="#F7B855" stroke="#F7B855" stroke-width="1.9963" stroke-miterlimit="10" d="M282.2,27.2c0,0-183-13.6-137,166.4 | |||
| c0,0,22.2,65.9,71.9,126.7c0,0,41.4,64.7,42.7,67.9c0,0,8,8.5,4.5,62.8l-3.4,67c0,0-9,27.2-1.1,30.3c0,0,12.4,5.2,22.5,5.2 | |||
| c10.1,0,22.5-5.2,22.5-5.2c7.9-3.1-1.1-30.3-1.1-30.3l-3.4-67c-2.1-55.9,4.5-62.8,4.5-62.8c2.2-5,42.7-67.9,42.7-67.9 | |||
| c50.3-60.5,71.9-126.7,71.9-126.7C465.3,13.6,282.2,27.2,282.2,27.2z M194.4,134.4c4.7-4.9,13.3-4.9,18.2,0 | |||
| c4.9,4.9,4.9,13.5,0,18.2c-4.9,4.7-13.6,4.6-18.3-0.4C189.8,147.5,189.8,139.2,194.4,134.4z M212.2,191.9c-5,4.8-12.8,4.8-17.7,0.1 | |||
| c-4.8-4.7-4.8-13.4,0-18.3c5-5,13.1-4.9,18.1,0.3C217.7,179.2,217.6,186.9,212.2,191.9z M312.4,94.9c4.9-4.9,13.2-4.6,18.2,0.5 | |||
| c5,5.1,4.8,13.1-0.4,18c-4.9,4.6-13,4.6-17.7-0.1C307.8,108.6,307.7,99.6,312.4,94.9z M312.5,134.4c4.8-4.7,13-4.8,17.9-0.2 | |||
| c5,4.7,5,13.3,0.1,18.3c-5,4.9-12.6,4.9-17.6,0C307.6,147.3,307.4,139.4,312.5,134.4z M312.5,212.7c5.1-5.2,12.8-5.4,17.9-0.4 | |||
| c4.9,4.8,4.9,13.3,0.1,18.2c-4.7,4.7-12.9,4.8-17.7,0.2C307.6,225.8,307.5,217.9,312.5,212.7z M312.9,173.5 | |||
| c4.8-4.5,13.1-4.5,17.8,0.1c4.7,4.6,4.6,13.7-0.1,18.3c-5.1,5-13.1,4.8-18.1-0.3C307.5,186.4,307.7,178.4,312.9,173.5z M273.4,94.9 | |||
| c4.9-4.7,13-4.6,17.8,0.1c5.1,4.9,4.9,13-0.3,18.1c-5.1,5-12.4,4.9-17.5-0.2C268.2,107.8,268.2,99.9,273.4,94.9z M291.2,152.3 | |||
| c-5.1,5.2-12.9,5.2-18,0.1c-4.9-5-5-13.5-0.1-18.2c4.6-4.4,13.3-4.4,18-0.1C296.1,138.6,296.1,147.4,291.2,152.3z M273,173.9 | |||
| c4.7-4.9,13.4-5,18.2-0.2c4.9,4.8,4.8,13.3-0.2,18.2c-4.9,4.8-12.6,4.9-17.6,0.1C268.4,186.9,268.1,178.9,273,173.9z M291.1,231.4 | |||
| c-4.9,4.7-13.6,4.4-18.2-0.5c-4.8-5.1-4.4-13.3,0.8-18.1c5-4.6,13-4.4,17.7,0.4C296.2,218.1,296.1,226.6,291.1,231.4z M233.8,95 | |||
| c4.6-4.7,13.8-4.6,18.4,0.1c4.4,4.6,4.4,13.2-0.1,17.9c-4.8,5.1-13.1,5.2-18.1,0.2C229.1,108.2,229,99.9,233.8,95z M233.7,134.6 | |||
| c4.8-4.9,13.4-5.1,18.2-0.4c5,4.9,4.9,13-0.2,18.1c-5.2,5.1-12.9,5.1-17.9-0.2C229.1,147.3,229,139.5,233.7,134.6z M233.7,213.2 | |||
| c4.9-5.1,13-5.1,18.1-0.1c5.1,5,5.1,13,0,18c-4.9,4.8-13.5,4.7-18.2-0.2C229.1,226.3,229.1,217.9,233.7,213.2z M233.8,173.5 | |||
| c4.7-4.6,13.1-4.6,17.8,0c5.2,4.9,5.3,12.9,0.3,18c-5.1,5.2-13,5.3-18.1,0.3C229.1,187.1,229,178.2,233.8,173.5z M319.8,310 | |||
| c-11.6,14.9-24.6,29-31.4,46.8c-0.7,1.7-6.2,2.3-6.2,2.3s-6.8,0.3-7.6-2.5c-6.6-22.8-25.4-39.4-38.9-58.7c-2.8-4-6-7.9-8.6-13 | |||
| c41.5,17.6,69.1,17.8,110.2,1.3C332.7,295.2,325.8,302.4,319.8,310z M370.1,191.9c-4.9,4.9-13,4.7-18.1-0.4 | |||
| c-5.2-5.3-5.1-12.6,0.3-17.9c4.9-4.8,12.7-4.8,17.6-0.1C374.7,178.3,374.8,187.2,370.1,191.9z M369.8,152.7 | |||
| c-4.8,4.6-13,4.7-17.8,0.1c-4.9-4.7-5-13.3-0.2-18.2c5-5.1,13.1-5.1,18.1-0.1C374.8,139.5,374.8,147.8,369.8,152.7z"/> | |||
| <path fill="#D39A46" d="M278.1,392.8c-109.7-181.1-105.2-191-105.2-191C151.2,147.2,171.4,97,171.4,97s19.6-51.2,64.8-66.5l0,0 | |||
| c-50.8,9.4-121.6,43.4-91,163.2c0,0,19.1,59.9,71,128.3c0,0,42.2,63.1,43.5,66.4L278.1,392.8z"/> | |||
| <path fill="#61ADA6" stroke="#61ADA6" stroke-width="1.9963" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d=" | |||
| M304.7,388.3c0,0-6.6,6.9-4.5,62.8l3.4,67c0,0,9,27.2,1.1,30.3c0,0-12.4,5.2-22.5,5.2s-22.5-5.2-22.5-5.2 | |||
| c-7.9-3.1,1.1-30.3,1.1-30.3l3.4-67c3.5-54.3-4.5-62.8-4.5-62.8s8.4,4.6,22.5,4.6C282.2,392.9,300,392.6,304.7,388.3z"/> | |||
| <path fill="#42827A" stroke="#42827A" stroke-width="1.9963" stroke-miterlimit="10" d="M273.3,392.3l-1.8,160.1 | |||
| c0,0-8.8-1.5-11.7-3.5c-1-0.7-7.5-2.4-3.2-16.2c0,0,2.6-16.9,4.3-31.8c0,0,6.9-81.5,2.7-99.7l-3.7-12.8 | |||
| C259.8,388.3,266.9,391.5,273.3,392.3z"/> | |||
| <g> | |||
| <path fill="#42827A" d="M282.3,521.9c1.9,0.3,3.9,0.4,5.8,0.4c1.9,0,3.9-0.1,5.8-0.4c1.9-0.3,3.6-1,5.4-1.6 | |||
| c1.8-0.6,3.4-1.4,5.3-2.3l0,0c0.1,0,0.1,0,0.1,0c0,0,0,0.1,0,0.1c-1.1,1.7-2.8,3.1-4.6,4c-1.9,0.9-4,1.1-6,1.3c-2,0.1-4,0.1-6-0.1 | |||
| c-2-0.3-3.9-0.6-5.8-1.2c-0.1,0-0.1-0.1-0.1-0.1C282.2,521.9,282.2,521.9,282.3,521.9z"/> | |||
| </g> | |||
| </g> | |||
| </svg> | |||
| @ -0,0 +1,21 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <svg width="215px" height="215px" viewBox="0 0 215 215" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | |||
| <!-- Generator: Sketch 52.6 (67491) - http://www.bohemiancoding.com/sketch --> | |||
| <title>portal-logo</title> | |||
| <desc>Created with Sketch.</desc> | |||
| <defs> | |||
| <path d="M51.165,8.742 C54.505,12.619 56.876,17.365 57.892,22.588 C60.148,17.225 65.452,13.46 71.636,13.46 C79.867,13.46 86.541,20.134 86.541,28.365 C86.541,36.597 79.867,43.269 71.636,43.269 C63.404,43.269 56.728,36.597 56.728,28.365 C56.728,12.7 44.03,0 28.365,0 C12.7,0 0,12.7 0,28.365 C0,44.031 12.7,56.731 28.365,56.731 C36.419,56.731 43.695,53.393 48.858,48.003 C45.501,44.117 43.128,39.383 42.108,34.14 C39.852,39.504 34.548,43.269 28.365,43.269 C20.133,43.269 13.46,36.597 13.46,28.365 C13.46,20.134 20.133,13.46 28.365,13.46 C36.966,13.46 43.27,20.577 43.27,28.365 C43.27,44.031 55.97,56.731 71.636,56.731 C87.3,56.731 100,44.031 100,28.365 C100,12.7 87.3,0 71.636,0 C63.589,0 56.327,3.358 51.165,8.742 Z" id="path-1"></path> | |||
| </defs> | |||
| <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | |||
| <g id="portal-logo"> | |||
| <circle id="Oval" fill="#09B6CA" fill-rule="nonzero" cx="107.5" cy="107.5" r="107.5"></circle> | |||
| <g id="logo" transform="translate(58.000000, 79.000000)"> | |||
| <mask id="mask-2" fill="white"> | |||
| <use xlink:href="#path-1"></use> | |||
| </mask> | |||
| <g id="Clip-2"></g> | |||
| <polygon id="Fill-1" fill="#FFFFFE" mask="url(#mask-2)" points="-5 61.73 105 61.73 105 -5 -5 -5"></polygon> | |||
| </g> | |||
| </g> | |||
| </g> | |||
| </svg> | |||
| @ -0,0 +1,18 @@ | |||
| <svg width="400" height="400" xmlns="http://www.w3.org/2000/svg"> | |||
| <!-- Fondo --> | |||
| <rect width="400" height="400" fill="#ffffff" /> | |||
| <!-- Corona --> | |||
| <g transform="translate(100, 100) scale(2)"> | |||
| <polygon points="50,150 75,50 100,150" fill="#FFD700" /> | |||
| <polygon points="0,150 50,0 100,150" fill="#FFD700" /> | |||
| <polygon points="100,150 125,50 150,150" fill="#FFD700" /> | |||
| </g> | |||
| <!-- Letra R --> | |||
| <!-- | |||
| <text x="100" y="360" font-family="Arial, sans-serif" font-size="400" fill="#000000" font-weight="bold">R</text> | |||
| --> | |||
| <text x="100" y="360" font-family="Open Sans" font-size="400" fill="#000000" font-weight="bold">R</text> | |||
| </svg> | |||
| @ -0,0 +1,96 @@ | |||
| 'use strict'; | |||
| /* ===== Enable Bootstrap Popover (on element ====== */ | |||
| const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]') | |||
| const popoverList = [...popoverTriggerList].map(popoverTriggerEl => new bootstrap.Popover(popoverTriggerEl)) | |||
| /* ==== Enable Bootstrap Alert ====== */ | |||
| //var alertList = document.querySelectorAll('.alert') | |||
| //alertList.forEach(function (alert) { | |||
| // new bootstrap.Alert(alert) | |||
| //}); | |||
| const alertList = document.querySelectorAll('.alert') | |||
| const alerts = [...alertList].map(element => new bootstrap.Alert(element)) | |||
| /* ===== Responsive Sidepanel ====== */ | |||
| const sidePanelToggler = document.getElementById('sidepanel-toggler'); | |||
| const sidePanel = document.getElementById('app-sidepanel'); | |||
| const sidePanelDrop = document.getElementById('sidepanel-drop'); | |||
| const sidePanelClose = document.getElementById('sidepanel-close'); | |||
| window.addEventListener('load', function(){ | |||
| responsiveSidePanel(); | |||
| }); | |||
| window.addEventListener('resize', function(){ | |||
| responsiveSidePanel(); | |||
| }); | |||
| function responsiveSidePanel() { | |||
| let w = window.innerWidth; | |||
| if(w >= 1200) { | |||
| // if larger | |||
| //console.log('larger'); | |||
| sidePanel.classList.remove('sidepanel-hidden'); | |||
| sidePanel.classList.add('sidepanel-visible'); | |||
| } else { | |||
| // if smaller | |||
| //console.log('smaller'); | |||
| sidePanel.classList.remove('sidepanel-visible'); | |||
| sidePanel.classList.add('sidepanel-hidden'); | |||
| } | |||
| }; | |||
| sidePanelToggler.addEventListener('click', () => { | |||
| if (sidePanel.classList.contains('sidepanel-visible')) { | |||
| console.log('visible'); | |||
| sidePanel.classList.remove('sidepanel-visible'); | |||
| sidePanel.classList.add('sidepanel-hidden'); | |||
| } else { | |||
| console.log('hidden'); | |||
| sidePanel.classList.remove('sidepanel-hidden'); | |||
| sidePanel.classList.add('sidepanel-visible'); | |||
| } | |||
| }); | |||
| sidePanelClose.addEventListener('click', (e) => { | |||
| e.preventDefault(); | |||
| sidePanelToggler.click(); | |||
| }); | |||
| sidePanelDrop.addEventListener('click', (e) => { | |||
| sidePanelToggler.click(); | |||
| }); | |||
| /* ====== Mobile search ======= */ | |||
| const searchMobileTrigger = document.querySelector('.search-mobile-trigger'); | |||
| const searchBox = document.querySelector('.app-search-box'); | |||
| searchMobileTrigger.addEventListener('click', () => { | |||
| searchBox.classList.toggle('is-visible'); | |||
| let searchMobileTriggerIcon = document.querySelector('.search-mobile-trigger-icon'); | |||
| if(searchMobileTriggerIcon.classList.contains('fa-magnifying-glass')) { | |||
| searchMobileTriggerIcon.classList.remove('fa-magnifying-glass'); | |||
| searchMobileTriggerIcon.classList.add('fa-xmark'); | |||
| } else { | |||
| searchMobileTriggerIcon.classList.remove('fa-xmark'); | |||
| searchMobileTriggerIcon.classList.add('fa-magnifying-glass'); | |||
| } | |||
| }); | |||
| @ -0,0 +1,366 @@ | |||
| 'use strict'; | |||
| /* Chart.js docs: https://www.chartjs.org/ */ | |||
| window.chartColors = { | |||
| green: '#75c181', // rgba(117,193,129, 1) | |||
| blue: '#5b99ea', // rgba(91,153,234, 1) | |||
| gray: '#a9b5c9', | |||
| text: '#252930', | |||
| border: '#e7e9ed' | |||
| }; | |||
| /* Random number generator for demo purpose */ | |||
| var randomDataPoint = function(){ return Math.round(Math.random()*100)}; | |||
| //Area line Chart Demo | |||
| var lineChartConfig = { | |||
| type: 'line', | |||
| data: { | |||
| labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul'], | |||
| datasets: [{ | |||
| label: 'Dataset', | |||
| backgroundColor: "rgba(117,193,129,0.2)", | |||
| borderColor: "rgba(117,193,129, 0.8)", | |||
| data: [ | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint() | |||
| ], | |||
| }] | |||
| }, | |||
| options: { | |||
| responsive: true, | |||
| legend: { | |||
| display: true, | |||
| position: 'bottom', | |||
| align: 'end', | |||
| }, | |||
| tooltips: { | |||
| mode: 'index', | |||
| intersect: false, | |||
| titleMarginBottom: 10, | |||
| bodySpacing: 10, | |||
| xPadding: 16, | |||
| yPadding: 16, | |||
| borderColor: window.chartColors.border, | |||
| borderWidth: 1, | |||
| backgroundColor: '#fff', | |||
| bodyFontColor: window.chartColors.text, | |||
| titleFontColor: window.chartColors.text, | |||
| callbacks: { | |||
| label: function(tooltipItem, data) { | |||
| return tooltipItem.value + '%'; | |||
| } | |||
| }, | |||
| }, | |||
| hover: { | |||
| mode: 'nearest', | |||
| intersect: true | |||
| }, | |||
| scales: { | |||
| xAxes: [{ | |||
| display: true, | |||
| gridLines: { | |||
| drawBorder: false, | |||
| color: window.chartColors.border, | |||
| }, | |||
| scaleLabel: { | |||
| display: false, | |||
| } | |||
| }], | |||
| yAxes: [{ | |||
| display: true, | |||
| gridLines: { | |||
| drawBorder: false, | |||
| color: window.chartColors.border, | |||
| }, | |||
| scaleLabel: { | |||
| display: false, | |||
| }, | |||
| ticks: { | |||
| beginAtZero: true, | |||
| userCallback: function(value, index, values) { | |||
| return value.toLocaleString() + '%'; | |||
| } | |||
| }, | |||
| }] | |||
| } | |||
| } | |||
| }; | |||
| //Bar Chart Demo | |||
| var barChartConfig = { | |||
| type: 'bar', | |||
| data: { | |||
| labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul'], | |||
| datasets: [{ | |||
| label: 'Dataset 1', | |||
| backgroundColor: "rgba(117,193,129,0.8)", | |||
| hoverBackgroundColor: "rgba(117,193,129,1)", | |||
| data: [ | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint() | |||
| ] | |||
| }, | |||
| { | |||
| label: 'Dataset 2', | |||
| backgroundColor: "rgba(91,153,234,0.8)", | |||
| hoverBackgroundColor: "rgba(91,153,234,1)", | |||
| data: [ | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint() | |||
| ] | |||
| } | |||
| ] | |||
| }, | |||
| options: { | |||
| responsive: true, | |||
| legend: { | |||
| position: 'bottom', | |||
| align: 'end', | |||
| }, | |||
| tooltips: { | |||
| mode: 'index', | |||
| intersect: false, | |||
| titleMarginBottom: 10, | |||
| bodySpacing: 10, | |||
| xPadding: 16, | |||
| yPadding: 16, | |||
| borderColor: window.chartColors.border, | |||
| borderWidth: 1, | |||
| backgroundColor: '#fff', | |||
| bodyFontColor: window.chartColors.text, | |||
| titleFontColor: window.chartColors.text, | |||
| callbacks: { | |||
| label: function(tooltipItem, data) { | |||
| return tooltipItem.value + '%'; | |||
| } | |||
| }, | |||
| }, | |||
| scales: { | |||
| xAxes: [{ | |||
| display: true, | |||
| gridLines: { | |||
| drawBorder: false, | |||
| color: window.chartColors.border, | |||
| }, | |||
| }], | |||
| yAxes: [{ | |||
| display: true, | |||
| gridLines: { | |||
| drawBorder: false, | |||
| color: window.chartColors.borders, | |||
| }, | |||
| ticks: { | |||
| beginAtZero: true, | |||
| userCallback: function(value, index, values) { | |||
| return value + '%'; | |||
| } | |||
| }, | |||
| }] | |||
| } | |||
| } | |||
| } | |||
| // Pie Chart Demo | |||
| var pieChartConfig = { | |||
| type: 'pie', | |||
| data: { | |||
| datasets: [{ | |||
| data: [ | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| ], | |||
| backgroundColor: [ | |||
| window.chartColors.green, | |||
| window.chartColors.blue, | |||
| window.chartColors.gray, | |||
| ], | |||
| label: 'Dataset 1' | |||
| }], | |||
| labels: [ | |||
| 'Green', | |||
| 'Blue', | |||
| 'Gray', | |||
| ] | |||
| }, | |||
| options: { | |||
| responsive: true, | |||
| legend: { | |||
| display: true, | |||
| position: 'bottom', | |||
| align: 'center', | |||
| }, | |||
| tooltips: { | |||
| titleMarginBottom: 10, | |||
| bodySpacing: 10, | |||
| xPadding: 16, | |||
| yPadding: 16, | |||
| borderColor: window.chartColors.border, | |||
| borderWidth: 1, | |||
| backgroundColor: '#fff', | |||
| bodyFontColor: window.chartColors.text, | |||
| titleFontColor: window.chartColors.text, | |||
| /* Display % in tooltip - https://stackoverflow.com/questions/37257034/chart-js-2-0-doughnut-tooltip-percentages */ | |||
| callbacks: { | |||
| label: function(tooltipItem, data) { | |||
| //get the concerned dataset | |||
| var dataset = data.datasets[tooltipItem.datasetIndex]; | |||
| //calculate the total of this data set | |||
| var total = dataset.data.reduce(function(previousValue, currentValue, currentIndex, array) { | |||
| return previousValue + currentValue; | |||
| }); | |||
| //get the current items value | |||
| var currentValue = dataset.data[tooltipItem.index]; | |||
| //calculate the precentage based on the total and current item, also this does a rough rounding to give a whole number | |||
| var percentage = Math.floor(((currentValue/total) * 100)+0.5); | |||
| return percentage + "%"; | |||
| }, | |||
| }, | |||
| }, | |||
| } | |||
| }; | |||
| // Doughnut Chart Demo | |||
| var doughnutChartConfig = { | |||
| type: 'doughnut', | |||
| data: { | |||
| datasets: [{ | |||
| data: [ | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| ], | |||
| backgroundColor: [ | |||
| window.chartColors.green, | |||
| window.chartColors.blue, | |||
| window.chartColors.gray, | |||
| ], | |||
| label: 'Dataset 1' | |||
| }], | |||
| labels: [ | |||
| 'Green', | |||
| 'Blue', | |||
| 'Gray', | |||
| ] | |||
| }, | |||
| options: { | |||
| responsive: true, | |||
| legend: { | |||
| display: true, | |||
| position: 'bottom', | |||
| align: 'center', | |||
| }, | |||
| tooltips: { | |||
| titleMarginBottom: 10, | |||
| bodySpacing: 10, | |||
| xPadding: 16, | |||
| yPadding: 16, | |||
| borderColor: window.chartColors.border, | |||
| borderWidth: 1, | |||
| backgroundColor: '#fff', | |||
| bodyFontColor: window.chartColors.text, | |||
| titleFontColor: window.chartColors.text, | |||
| animation: { | |||
| animateScale: true, | |||
| animateRotate: true | |||
| }, | |||
| /* Display % in tooltip - https://stackoverflow.com/questions/37257034/chart-js-2-0-doughnut-tooltip-percentages */ | |||
| callbacks: { | |||
| label: function(tooltipItem, data) { | |||
| //get the concerned dataset | |||
| var dataset = data.datasets[tooltipItem.datasetIndex]; | |||
| //calculate the total of this data set | |||
| var total = dataset.data.reduce(function(previousValue, currentValue, currentIndex, array) { | |||
| return previousValue + currentValue; | |||
| }); | |||
| //get the current items value | |||
| var currentValue = dataset.data[tooltipItem.index]; | |||
| //calculate the precentage based on the total and current item, also this does a rough rounding to give a whole number | |||
| var percentage = Math.floor(((currentValue/total) * 100)+0.5); | |||
| return percentage + "%"; | |||
| }, | |||
| }, | |||
| }, | |||
| } | |||
| }; | |||
| // Generate charts on load | |||
| window.addEventListener('load', function(){ | |||
| var lineChart = document.getElementById('chart-line').getContext('2d'); | |||
| window.myLine = new Chart(lineChart, lineChartConfig); | |||
| var barChart = document.getElementById('chart-bar').getContext('2d'); | |||
| window.myBar = new Chart(barChart, barChartConfig); | |||
| var pieChart = document.getElementById('chart-pie').getContext('2d'); | |||
| window.myPie = new Chart(pieChart, pieChartConfig); | |||
| var doughnutChart = document.getElementById('chart-doughnut').getContext('2d'); | |||
| window.myDoughnut = new Chart(doughnutChart, doughnutChartConfig); | |||
| }); | |||
| @ -0,0 +1,224 @@ | |||
| 'use strict'; | |||
| /* Chart.js docs: https://www.chartjs.org/ */ | |||
| window.chartColors = { | |||
| green: '#75c181', | |||
| gray: '#a9b5c9', | |||
| text: '#252930', | |||
| border: '#e7e9ed' | |||
| }; | |||
| /* Random number generator for demo purpose */ | |||
| var randomDataPoint = function(){ return Math.round(Math.random()*10000)}; | |||
| //Chart.js Line Chart Example | |||
| var lineChartConfig = { | |||
| type: 'line', | |||
| data: { | |||
| labels: ['Day 1', 'Day 2', 'Day 3', 'Day 4', 'Day 5', 'Day 6', 'Day 7'], | |||
| datasets: [{ | |||
| label: 'Current week', | |||
| fill: false, | |||
| backgroundColor: window.chartColors.green, | |||
| borderColor: window.chartColors.green, | |||
| data: [ | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint() | |||
| ], | |||
| }, { | |||
| label: 'Previous week', | |||
| borderDash: [3, 5], | |||
| backgroundColor: window.chartColors.gray, | |||
| borderColor: window.chartColors.gray, | |||
| data: [ | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint(), | |||
| randomDataPoint() | |||
| ], | |||
| fill: false, | |||
| }] | |||
| }, | |||
| options: { | |||
| responsive: true, | |||
| aspectRatio: 1.5, | |||
| legend: { | |||
| display: true, | |||
| position: 'bottom', | |||
| align: 'end', | |||
| }, | |||
| title: { | |||
| display: true, | |||
| text: 'Chart.js Line Chart Example', | |||
| }, | |||
| tooltips: { | |||
| mode: 'index', | |||
| intersect: false, | |||
| titleMarginBottom: 10, | |||
| bodySpacing: 10, | |||
| xPadding: 16, | |||
| yPadding: 16, | |||
| borderColor: window.chartColors.border, | |||
| borderWidth: 1, | |||
| backgroundColor: '#fff', | |||
| bodyFontColor: window.chartColors.text, | |||
| titleFontColor: window.chartColors.text, | |||
| callbacks: { | |||
| //Ref: https://stackoverflow.com/questions/38800226/chart-js-add-commas-to-tooltip-and-y-axis | |||
| label: function(tooltipItem, data) { | |||
| if (parseInt(tooltipItem.value) >= 1000) { | |||
| return "$" + tooltipItem.value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); | |||
| } else { | |||
| return '$' + tooltipItem.value; | |||
| } | |||
| } | |||
| }, | |||
| }, | |||
| hover: { | |||
| mode: 'nearest', | |||
| intersect: true | |||
| }, | |||
| scales: { | |||
| xAxes: [{ | |||
| display: true, | |||
| gridLines: { | |||
| drawBorder: false, | |||
| color: window.chartColors.border, | |||
| }, | |||
| scaleLabel: { | |||
| display: false, | |||
| } | |||
| }], | |||
| yAxes: [{ | |||
| display: true, | |||
| gridLines: { | |||
| drawBorder: false, | |||
| color: window.chartColors.border, | |||
| }, | |||
| scaleLabel: { | |||
| display: false, | |||
| }, | |||
| ticks: { | |||
| beginAtZero: true, | |||
| userCallback: function(value, index, values) { | |||
| return '$' + value.toLocaleString(); //Ref: https://stackoverflow.com/questions/38800226/chart-js-add-commas-to-tooltip-and-y-axis | |||
| } | |||
| }, | |||
| }] | |||
| } | |||
| } | |||
| }; | |||
| // Chart.js Bar Chart Example | |||
| var barChartConfig = { | |||
| type: 'bar', | |||
| data: { | |||
| labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], | |||
| datasets: [{ | |||
| label: 'Orders', | |||
| backgroundColor: window.chartColors.green, | |||
| borderColor: window.chartColors.green, | |||
| borderWidth: 1, | |||
| maxBarThickness: 16, | |||
| data: [ | |||
| 23, | |||
| 45, | |||
| 76, | |||
| 75, | |||
| 62, | |||
| 37, | |||
| 83 | |||
| ] | |||
| }] | |||
| }, | |||
| options: { | |||
| responsive: true, | |||
| aspectRatio: 1.5, | |||
| legend: { | |||
| position: 'bottom', | |||
| align: 'end', | |||
| }, | |||
| title: { | |||
| display: true, | |||
| text: 'Chart.js Bar Chart Example' | |||
| }, | |||
| tooltips: { | |||
| mode: 'index', | |||
| intersect: false, | |||
| titleMarginBottom: 10, | |||
| bodySpacing: 10, | |||
| xPadding: 16, | |||
| yPadding: 16, | |||
| borderColor: window.chartColors.border, | |||
| borderWidth: 1, | |||
| backgroundColor: '#fff', | |||
| bodyFontColor: window.chartColors.text, | |||
| titleFontColor: window.chartColors.text, | |||
| }, | |||
| scales: { | |||
| xAxes: [{ | |||
| display: true, | |||
| gridLines: { | |||
| drawBorder: false, | |||
| color: window.chartColors.border, | |||
| }, | |||
| }], | |||
| yAxes: [{ | |||
| display: true, | |||
| gridLines: { | |||
| drawBorder: false, | |||
| color: window.chartColors.borders, | |||
| }, | |||
| }] | |||
| } | |||
| } | |||
| } | |||
| // Generate charts on load | |||
| window.addEventListener('load', function(){ | |||
| var lineChart = document.getElementById('canvas-linechart').getContext('2d'); | |||
| window.myLine = new Chart(lineChart, lineChartConfig); | |||
| var barChart = document.getElementById('canvas-barchart').getContext('2d'); | |||
| window.myBar = new Chart(barChart, barChartConfig); | |||
| }); | |||
| @ -0,0 +1,593 @@ | |||
| /*! | |||
| * Bootstrap Reboot v5.3.0 (https://getbootstrap.com/) | |||
| * Copyright 2011-2023 The Bootstrap Authors | |||
| * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) | |||
| */ | |||
| :root, | |||
| [data-bs-theme=light] { | |||
| --bs-blue: #0d6efd; | |||
| --bs-indigo: #6610f2; | |||
| --bs-purple: #6f42c1; | |||
| --bs-pink: #d63384; | |||
| --bs-red: #dc3545; | |||
| --bs-orange: #fd7e14; | |||
| --bs-yellow: #ffc107; | |||
| --bs-green: #198754; | |||
| --bs-teal: #20c997; | |||
| --bs-cyan: #0dcaf0; | |||
| --bs-black: #000; | |||
| --bs-white: #fff; | |||
| --bs-gray: #6c757d; | |||
| --bs-gray-dark: #343a40; | |||
| --bs-gray-100: #f8f9fa; | |||
| --bs-gray-200: #e9ecef; | |||
| --bs-gray-300: #dee2e6; | |||
| --bs-gray-400: #ced4da; | |||
| --bs-gray-500: #adb5bd; | |||
| --bs-gray-600: #6c757d; | |||
| --bs-gray-700: #495057; | |||
| --bs-gray-800: #343a40; | |||
| --bs-gray-900: #212529; | |||
| --bs-primary: #0d6efd; | |||
| --bs-secondary: #6c757d; | |||
| --bs-success: #198754; | |||
| --bs-info: #0dcaf0; | |||
| --bs-warning: #ffc107; | |||
| --bs-danger: #dc3545; | |||
| --bs-light: #f8f9fa; | |||
| --bs-dark: #212529; | |||
| --bs-primary-rgb: 13, 110, 253; | |||
| --bs-secondary-rgb: 108, 117, 125; | |||
| --bs-success-rgb: 25, 135, 84; | |||
| --bs-info-rgb: 13, 202, 240; | |||
| --bs-warning-rgb: 255, 193, 7; | |||
| --bs-danger-rgb: 220, 53, 69; | |||
| --bs-light-rgb: 248, 249, 250; | |||
| --bs-dark-rgb: 33, 37, 41; | |||
| --bs-primary-text-emphasis: #052c65; | |||
| --bs-secondary-text-emphasis: #2b2f32; | |||
| --bs-success-text-emphasis: #0a3622; | |||
| --bs-info-text-emphasis: #055160; | |||
| --bs-warning-text-emphasis: #664d03; | |||
| --bs-danger-text-emphasis: #58151c; | |||
| --bs-light-text-emphasis: #495057; | |||
| --bs-dark-text-emphasis: #495057; | |||
| --bs-primary-bg-subtle: #cfe2ff; | |||
| --bs-secondary-bg-subtle: #e2e3e5; | |||
| --bs-success-bg-subtle: #d1e7dd; | |||
| --bs-info-bg-subtle: #cff4fc; | |||
| --bs-warning-bg-subtle: #fff3cd; | |||
| --bs-danger-bg-subtle: #f8d7da; | |||
| --bs-light-bg-subtle: #fcfcfd; | |||
| --bs-dark-bg-subtle: #ced4da; | |||
| --bs-primary-border-subtle: #9ec5fe; | |||
| --bs-secondary-border-subtle: #c4c8cb; | |||
| --bs-success-border-subtle: #a3cfbb; | |||
| --bs-info-border-subtle: #9eeaf9; | |||
| --bs-warning-border-subtle: #ffe69c; | |||
| --bs-danger-border-subtle: #f1aeb5; | |||
| --bs-light-border-subtle: #e9ecef; | |||
| --bs-dark-border-subtle: #adb5bd; | |||
| --bs-white-rgb: 255, 255, 255; | |||
| --bs-black-rgb: 0, 0, 0; | |||
| --bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; | |||
| --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; | |||
| --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); | |||
| --bs-body-font-family: var(--bs-font-sans-serif); | |||
| --bs-body-font-size: 1rem; | |||
| --bs-body-font-weight: 400; | |||
| --bs-body-line-height: 1.5; | |||
| --bs-body-color: #212529; | |||
| --bs-body-color-rgb: 33, 37, 41; | |||
| --bs-body-bg: #fff; | |||
| --bs-body-bg-rgb: 255, 255, 255; | |||
| --bs-emphasis-color: #000; | |||
| --bs-emphasis-color-rgb: 0, 0, 0; | |||
| --bs-secondary-color: rgba(33, 37, 41, 0.75); | |||
| --bs-secondary-color-rgb: 33, 37, 41; | |||
| --bs-secondary-bg: #e9ecef; | |||
| --bs-secondary-bg-rgb: 233, 236, 239; | |||
| --bs-tertiary-color: rgba(33, 37, 41, 0.5); | |||
| --bs-tertiary-color-rgb: 33, 37, 41; | |||
| --bs-tertiary-bg: #f8f9fa; | |||
| --bs-tertiary-bg-rgb: 248, 249, 250; | |||
| --bs-heading-color: inherit; | |||
| --bs-link-color: #0d6efd; | |||
| --bs-link-color-rgb: 13, 110, 253; | |||
| --bs-link-decoration: underline; | |||
| --bs-link-hover-color: #0a58ca; | |||
| --bs-link-hover-color-rgb: 10, 88, 202; | |||
| --bs-code-color: #d63384; | |||
| --bs-highlight-bg: #fff3cd; | |||
| --bs-border-width: 1px; | |||
| --bs-border-style: solid; | |||
| --bs-border-color: #dee2e6; | |||
| --bs-border-color-translucent: rgba(0, 0, 0, 0.175); | |||
| --bs-border-radius: 0.375rem; | |||
| --bs-border-radius-sm: 0.25rem; | |||
| --bs-border-radius-lg: 0.5rem; | |||
| --bs-border-radius-xl: 1rem; | |||
| --bs-border-radius-xxl: 2rem; | |||
| --bs-border-radius-2xl: var(--bs-border-radius-xxl); | |||
| --bs-border-radius-pill: 50rem; | |||
| --bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); | |||
| --bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075); | |||
| --bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175); | |||
| --bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075); | |||
| --bs-focus-ring-width: 0.25rem; | |||
| --bs-focus-ring-opacity: 0.25; | |||
| --bs-focus-ring-color: rgba(13, 110, 253, 0.25); | |||
| --bs-form-valid-color: #198754; | |||
| --bs-form-valid-border-color: #198754; | |||
| --bs-form-invalid-color: #dc3545; | |||
| --bs-form-invalid-border-color: #dc3545; | |||
| } | |||
| [data-bs-theme=dark] { | |||
| color-scheme: dark; | |||
| --bs-body-color: #adb5bd; | |||
| --bs-body-color-rgb: 173, 181, 189; | |||
| --bs-body-bg: #212529; | |||
| --bs-body-bg-rgb: 33, 37, 41; | |||
| --bs-emphasis-color: #fff; | |||
| --bs-emphasis-color-rgb: 255, 255, 255; | |||
| --bs-secondary-color: rgba(173, 181, 189, 0.75); | |||
| --bs-secondary-color-rgb: 173, 181, 189; | |||
| --bs-secondary-bg: #343a40; | |||
| --bs-secondary-bg-rgb: 52, 58, 64; | |||
| --bs-tertiary-color: rgba(173, 181, 189, 0.5); | |||
| --bs-tertiary-color-rgb: 173, 181, 189; | |||
| --bs-tertiary-bg: #2b3035; | |||
| --bs-tertiary-bg-rgb: 43, 48, 53; | |||
| --bs-primary-text-emphasis: #6ea8fe; | |||
| --bs-secondary-text-emphasis: #a7acb1; | |||
| --bs-success-text-emphasis: #75b798; | |||
| --bs-info-text-emphasis: #6edff6; | |||
| --bs-warning-text-emphasis: #ffda6a; | |||
| --bs-danger-text-emphasis: #ea868f; | |||
| --bs-light-text-emphasis: #f8f9fa; | |||
| --bs-dark-text-emphasis: #dee2e6; | |||
| --bs-primary-bg-subtle: #031633; | |||
| --bs-secondary-bg-subtle: #161719; | |||
| --bs-success-bg-subtle: #051b11; | |||
| --bs-info-bg-subtle: #032830; | |||
| --bs-warning-bg-subtle: #332701; | |||
| --bs-danger-bg-subtle: #2c0b0e; | |||
| --bs-light-bg-subtle: #343a40; | |||
| --bs-dark-bg-subtle: #1a1d20; | |||
| --bs-primary-border-subtle: #084298; | |||
| --bs-secondary-border-subtle: #41464b; | |||
| --bs-success-border-subtle: #0f5132; | |||
| --bs-info-border-subtle: #087990; | |||
| --bs-warning-border-subtle: #997404; | |||
| --bs-danger-border-subtle: #842029; | |||
| --bs-light-border-subtle: #495057; | |||
| --bs-dark-border-subtle: #343a40; | |||
| --bs-heading-color: inherit; | |||
| --bs-link-color: #6ea8fe; | |||
| --bs-link-hover-color: #8bb9fe; | |||
| --bs-link-color-rgb: 110, 168, 254; | |||
| --bs-link-hover-color-rgb: 139, 185, 254; | |||
| --bs-code-color: #e685b5; | |||
| --bs-border-color: #495057; | |||
| --bs-border-color-translucent: rgba(255, 255, 255, 0.15); | |||
| --bs-form-valid-color: #75b798; | |||
| --bs-form-valid-border-color: #75b798; | |||
| --bs-form-invalid-color: #ea868f; | |||
| --bs-form-invalid-border-color: #ea868f; | |||
| } | |||
| *, | |||
| *::before, | |||
| *::after { | |||
| box-sizing: border-box; | |||
| } | |||
| @media (prefers-reduced-motion: no-preference) { | |||
| :root { | |||
| scroll-behavior: smooth; | |||
| } | |||
| } | |||
| body { | |||
| margin: 0; | |||
| font-family: var(--bs-body-font-family); | |||
| font-size: var(--bs-body-font-size); | |||
| font-weight: var(--bs-body-font-weight); | |||
| line-height: var(--bs-body-line-height); | |||
| color: var(--bs-body-color); | |||
| text-align: var(--bs-body-text-align); | |||
| background-color: var(--bs-body-bg); | |||
| -webkit-text-size-adjust: 100%; | |||
| -webkit-tap-highlight-color: rgba(0, 0, 0, 0); | |||
| } | |||
| hr { | |||
| margin: 1rem 0; | |||
| color: inherit; | |||
| border: 0; | |||
| border-top: var(--bs-border-width) solid; | |||
| opacity: 0.25; | |||
| } | |||
| h6, h5, h4, h3, h2, h1 { | |||
| margin-top: 0; | |||
| margin-bottom: 0.5rem; | |||
| font-weight: 500; | |||
| line-height: 1.2; | |||
| color: var(--bs-heading-color); | |||
| } | |||
| h1 { | |||
| font-size: calc(1.375rem + 1.5vw); | |||
| } | |||
| @media (min-width: 1200px) { | |||
| h1 { | |||
| font-size: 2.5rem; | |||
| } | |||
| } | |||
| h2 { | |||
| font-size: calc(1.325rem + 0.9vw); | |||
| } | |||
| @media (min-width: 1200px) { | |||
| h2 { | |||
| font-size: 2rem; | |||
| } | |||
| } | |||
| h3 { | |||
| font-size: calc(1.3rem + 0.6vw); | |||
| } | |||
| @media (min-width: 1200px) { | |||
| h3 { | |||
| font-size: 1.75rem; | |||
| } | |||
| } | |||
| h4 { | |||
| font-size: calc(1.275rem + 0.3vw); | |||
| } | |||
| @media (min-width: 1200px) { | |||
| h4 { | |||
| font-size: 1.5rem; | |||
| } | |||
| } | |||
| h5 { | |||
| font-size: 1.25rem; | |||
| } | |||
| h6 { | |||
| font-size: 1rem; | |||
| } | |||
| p { | |||
| margin-top: 0; | |||
| margin-bottom: 1rem; | |||
| } | |||
| abbr[title] { | |||
| -webkit-text-decoration: underline dotted; | |||
| text-decoration: underline dotted; | |||
| cursor: help; | |||
| -webkit-text-decoration-skip-ink: none; | |||
| text-decoration-skip-ink: none; | |||
| } | |||
| address { | |||
| margin-bottom: 1rem; | |||
| font-style: normal; | |||
| line-height: inherit; | |||
| } | |||
| ol, | |||
| ul { | |||
| padding-left: 2rem; | |||
| } | |||
| ol, | |||
| ul, | |||
| dl { | |||
| margin-top: 0; | |||
| margin-bottom: 1rem; | |||
| } | |||
| ol ol, | |||
| ul ul, | |||
| ol ul, | |||
| ul ol { | |||
| margin-bottom: 0; | |||
| } | |||
| dt { | |||
| font-weight: 700; | |||
| } | |||
| dd { | |||
| margin-bottom: 0.5rem; | |||
| margin-left: 0; | |||
| } | |||
| blockquote { | |||
| margin: 0 0 1rem; | |||
| } | |||
| b, | |||
| strong { | |||
| font-weight: bolder; | |||
| } | |||
| small { | |||
| font-size: 0.875em; | |||
| } | |||
| mark { | |||
| padding: 0.1875em; | |||
| background-color: var(--bs-highlight-bg); | |||
| } | |||
| sub, | |||
| sup { | |||
| position: relative; | |||
| font-size: 0.75em; | |||
| line-height: 0; | |||
| vertical-align: baseline; | |||
| } | |||
| sub { | |||
| bottom: -0.25em; | |||
| } | |||
| sup { | |||
| top: -0.5em; | |||
| } | |||
| a { | |||
| color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1)); | |||
| text-decoration: underline; | |||
| } | |||
| a:hover { | |||
| --bs-link-color-rgb: var(--bs-link-hover-color-rgb); | |||
| } | |||
| a:not([href]):not([class]), a:not([href]):not([class]):hover { | |||
| color: inherit; | |||
| text-decoration: none; | |||
| } | |||
| pre, | |||
| code, | |||
| kbd, | |||
| samp { | |||
| font-family: var(--bs-font-monospace); | |||
| font-size: 1em; | |||
| } | |||
| pre { | |||
| display: block; | |||
| margin-top: 0; | |||
| margin-bottom: 1rem; | |||
| overflow: auto; | |||
| font-size: 0.875em; | |||
| } | |||
| pre code { | |||
| font-size: inherit; | |||
| color: inherit; | |||
| word-break: normal; | |||
| } | |||
| code { | |||
| font-size: 0.875em; | |||
| color: var(--bs-code-color); | |||
| word-wrap: break-word; | |||
| } | |||
| a > code { | |||
| color: inherit; | |||
| } | |||
| kbd { | |||
| padding: 0.1875rem 0.375rem; | |||
| font-size: 0.875em; | |||
| color: var(--bs-body-bg); | |||
| background-color: var(--bs-body-color); | |||
| border-radius: 0.25rem; | |||
| } | |||
| kbd kbd { | |||
| padding: 0; | |||
| font-size: 1em; | |||
| } | |||
| figure { | |||
| margin: 0 0 1rem; | |||
| } | |||
| img, | |||
| svg { | |||
| vertical-align: middle; | |||
| } | |||
| table { | |||
| caption-side: bottom; | |||
| border-collapse: collapse; | |||
| } | |||
| caption { | |||
| padding-top: 0.5rem; | |||
| padding-bottom: 0.5rem; | |||
| color: var(--bs-secondary-color); | |||
| text-align: left; | |||
| } | |||
| th { | |||
| text-align: inherit; | |||
| text-align: -webkit-match-parent; | |||
| } | |||
| thead, | |||
| tbody, | |||
| tfoot, | |||
| tr, | |||
| td, | |||
| th { | |||
| border-color: inherit; | |||
| border-style: solid; | |||
| border-width: 0; | |||
| } | |||
| label { | |||
| display: inline-block; | |||
| } | |||
| button { | |||
| border-radius: 0; | |||
| } | |||
| button:focus:not(:focus-visible) { | |||
| outline: 0; | |||
| } | |||
| input, | |||
| button, | |||
| select, | |||
| optgroup, | |||
| textarea { | |||
| margin: 0; | |||
| font-family: inherit; | |||
| font-size: inherit; | |||
| line-height: inherit; | |||
| } | |||
| button, | |||
| select { | |||
| text-transform: none; | |||
| } | |||
| [role=button] { | |||
| cursor: pointer; | |||
| } | |||
| select { | |||
| word-wrap: normal; | |||
| } | |||
| select:disabled { | |||
| opacity: 1; | |||
| } | |||
| [list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator { | |||
| display: none !important; | |||
| } | |||
| button, | |||
| [type=button], | |||
| [type=reset], | |||
| [type=submit] { | |||
| -webkit-appearance: button; | |||
| } | |||
| button:not(:disabled), | |||
| [type=button]:not(:disabled), | |||
| [type=reset]:not(:disabled), | |||
| [type=submit]:not(:disabled) { | |||
| cursor: pointer; | |||
| } | |||
| ::-moz-focus-inner { | |||
| padding: 0; | |||
| border-style: none; | |||
| } | |||
| textarea { | |||
| resize: vertical; | |||
| } | |||
| fieldset { | |||
| min-width: 0; | |||
| padding: 0; | |||
| margin: 0; | |||
| border: 0; | |||
| } | |||
| legend { | |||
| float: left; | |||
| width: 100%; | |||
| padding: 0; | |||
| margin-bottom: 0.5rem; | |||
| font-size: calc(1.275rem + 0.3vw); | |||
| line-height: inherit; | |||
| } | |||
| @media (min-width: 1200px) { | |||
| legend { | |||
| font-size: 1.5rem; | |||
| } | |||
| } | |||
| legend + * { | |||
| clear: left; | |||
| } | |||
| ::-webkit-datetime-edit-fields-wrapper, | |||
| ::-webkit-datetime-edit-text, | |||
| ::-webkit-datetime-edit-minute, | |||
| ::-webkit-datetime-edit-hour-field, | |||
| ::-webkit-datetime-edit-day-field, | |||
| ::-webkit-datetime-edit-month-field, | |||
| ::-webkit-datetime-edit-year-field { | |||
| padding: 0; | |||
| } | |||
| ::-webkit-inner-spin-button { | |||
| height: auto; | |||
| } | |||
| [type=search] { | |||
| outline-offset: -2px; | |||
| -webkit-appearance: textfield; | |||
| } | |||
| /* rtl:raw: | |||
| [type="tel"], | |||
| [type="url"], | |||
| [type="email"], | |||
| [type="number"] { | |||
| direction: ltr; | |||
| } | |||
| */ | |||
| ::-webkit-search-decoration { | |||
| -webkit-appearance: none; | |||
| } | |||
| ::-webkit-color-swatch-wrapper { | |||
| padding: 0; | |||
| } | |||
| ::-webkit-file-upload-button { | |||
| font: inherit; | |||
| -webkit-appearance: button; | |||
| } | |||
| ::file-selector-button { | |||
| font: inherit; | |||
| -webkit-appearance: button; | |||
| } | |||
| output { | |||
| display: inline-block; | |||
| } | |||
| iframe { | |||
| border: 0; | |||
| } | |||
| summary { | |||
| display: list-item; | |||
| cursor: pointer; | |||
| } | |||
| progress { | |||
| vertical-align: baseline; | |||
| } | |||
| [hidden] { | |||
| display: none !important; | |||
| } | |||
| /*# sourceMappingURL=bootstrap-reboot.css.map */ | |||
| @ -0,0 +1,590 @@ | |||
| /*! | |||
| * Bootstrap Reboot v5.3.0 (https://getbootstrap.com/) | |||
| * Copyright 2011-2023 The Bootstrap Authors | |||
| * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) | |||
| */ | |||
| :root, | |||
| [data-bs-theme=light] { | |||
| --bs-blue: #0d6efd; | |||
| --bs-indigo: #6610f2; | |||
| --bs-purple: #6f42c1; | |||
| --bs-pink: #d63384; | |||
| --bs-red: #dc3545; | |||
| --bs-orange: #fd7e14; | |||
| --bs-yellow: #ffc107; | |||
| --bs-green: #198754; | |||
| --bs-teal: #20c997; | |||
| --bs-cyan: #0dcaf0; | |||
| --bs-black: #000; | |||
| --bs-white: #fff; | |||
| --bs-gray: #6c757d; | |||
| --bs-gray-dark: #343a40; | |||
| --bs-gray-100: #f8f9fa; | |||
| --bs-gray-200: #e9ecef; | |||
| --bs-gray-300: #dee2e6; | |||
| --bs-gray-400: #ced4da; | |||
| --bs-gray-500: #adb5bd; | |||
| --bs-gray-600: #6c757d; | |||
| --bs-gray-700: #495057; | |||
| --bs-gray-800: #343a40; | |||
| --bs-gray-900: #212529; | |||
| --bs-primary: #0d6efd; | |||
| --bs-secondary: #6c757d; | |||
| --bs-success: #198754; | |||
| --bs-info: #0dcaf0; | |||
| --bs-warning: #ffc107; | |||
| --bs-danger: #dc3545; | |||
| --bs-light: #f8f9fa; | |||
| --bs-dark: #212529; | |||
| --bs-primary-rgb: 13, 110, 253; | |||
| --bs-secondary-rgb: 108, 117, 125; | |||
| --bs-success-rgb: 25, 135, 84; | |||
| --bs-info-rgb: 13, 202, 240; | |||
| --bs-warning-rgb: 255, 193, 7; | |||
| --bs-danger-rgb: 220, 53, 69; | |||
| --bs-light-rgb: 248, 249, 250; | |||
| --bs-dark-rgb: 33, 37, 41; | |||
| --bs-primary-text-emphasis: #052c65; | |||
| --bs-secondary-text-emphasis: #2b2f32; | |||
| --bs-success-text-emphasis: #0a3622; | |||
| --bs-info-text-emphasis: #055160; | |||
| --bs-warning-text-emphasis: #664d03; | |||
| --bs-danger-text-emphasis: #58151c; | |||
| --bs-light-text-emphasis: #495057; | |||
| --bs-dark-text-emphasis: #495057; | |||
| --bs-primary-bg-subtle: #cfe2ff; | |||
| --bs-secondary-bg-subtle: #e2e3e5; | |||
| --bs-success-bg-subtle: #d1e7dd; | |||
| --bs-info-bg-subtle: #cff4fc; | |||
| --bs-warning-bg-subtle: #fff3cd; | |||
| --bs-danger-bg-subtle: #f8d7da; | |||
| --bs-light-bg-subtle: #fcfcfd; | |||
| --bs-dark-bg-subtle: #ced4da; | |||
| --bs-primary-border-subtle: #9ec5fe; | |||
| --bs-secondary-border-subtle: #c4c8cb; | |||
| --bs-success-border-subtle: #a3cfbb; | |||
| --bs-info-border-subtle: #9eeaf9; | |||
| --bs-warning-border-subtle: #ffe69c; | |||
| --bs-danger-border-subtle: #f1aeb5; | |||
| --bs-light-border-subtle: #e9ecef; | |||
| --bs-dark-border-subtle: #adb5bd; | |||
| --bs-white-rgb: 255, 255, 255; | |||
| --bs-black-rgb: 0, 0, 0; | |||
| --bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; | |||
| --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; | |||
| --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); | |||
| --bs-body-font-family: var(--bs-font-sans-serif); | |||
| --bs-body-font-size: 1rem; | |||
| --bs-body-font-weight: 400; | |||
| --bs-body-line-height: 1.5; | |||
| --bs-body-color: #212529; | |||
| --bs-body-color-rgb: 33, 37, 41; | |||
| --bs-body-bg: #fff; | |||
| --bs-body-bg-rgb: 255, 255, 255; | |||
| --bs-emphasis-color: #000; | |||
| --bs-emphasis-color-rgb: 0, 0, 0; | |||
| --bs-secondary-color: rgba(33, 37, 41, 0.75); | |||
| --bs-secondary-color-rgb: 33, 37, 41; | |||
| --bs-secondary-bg: #e9ecef; | |||
| --bs-secondary-bg-rgb: 233, 236, 239; | |||
| --bs-tertiary-color: rgba(33, 37, 41, 0.5); | |||
| --bs-tertiary-color-rgb: 33, 37, 41; | |||
| --bs-tertiary-bg: #f8f9fa; | |||
| --bs-tertiary-bg-rgb: 248, 249, 250; | |||
| --bs-heading-color: inherit; | |||
| --bs-link-color: #0d6efd; | |||
| --bs-link-color-rgb: 13, 110, 253; | |||
| --bs-link-decoration: underline; | |||
| --bs-link-hover-color: #0a58ca; | |||
| --bs-link-hover-color-rgb: 10, 88, 202; | |||
| --bs-code-color: #d63384; | |||
| --bs-highlight-bg: #fff3cd; | |||
| --bs-border-width: 1px; | |||
| --bs-border-style: solid; | |||
| --bs-border-color: #dee2e6; | |||
| --bs-border-color-translucent: rgba(0, 0, 0, 0.175); | |||
| --bs-border-radius: 0.375rem; | |||
| --bs-border-radius-sm: 0.25rem; | |||
| --bs-border-radius-lg: 0.5rem; | |||
| --bs-border-radius-xl: 1rem; | |||
| --bs-border-radius-xxl: 2rem; | |||
| --bs-border-radius-2xl: var(--bs-border-radius-xxl); | |||
| --bs-border-radius-pill: 50rem; | |||
| --bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); | |||
| --bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075); | |||
| --bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175); | |||
| --bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075); | |||
| --bs-focus-ring-width: 0.25rem; | |||
| --bs-focus-ring-opacity: 0.25; | |||
| --bs-focus-ring-color: rgba(13, 110, 253, 0.25); | |||
| --bs-form-valid-color: #198754; | |||
| --bs-form-valid-border-color: #198754; | |||
| --bs-form-invalid-color: #dc3545; | |||
| --bs-form-invalid-border-color: #dc3545; | |||
| } | |||
| [data-bs-theme=dark] { | |||
| color-scheme: dark; | |||
| --bs-body-color: #adb5bd; | |||
| --bs-body-color-rgb: 173, 181, 189; | |||
| --bs-body-bg: #212529; | |||
| --bs-body-bg-rgb: 33, 37, 41; | |||
| --bs-emphasis-color: #fff; | |||
| --bs-emphasis-color-rgb: 255, 255, 255; | |||
| --bs-secondary-color: rgba(173, 181, 189, 0.75); | |||
| --bs-secondary-color-rgb: 173, 181, 189; | |||
| --bs-secondary-bg: #343a40; | |||
| --bs-secondary-bg-rgb: 52, 58, 64; | |||
| --bs-tertiary-color: rgba(173, 181, 189, 0.5); | |||
| --bs-tertiary-color-rgb: 173, 181, 189; | |||
| --bs-tertiary-bg: #2b3035; | |||
| --bs-tertiary-bg-rgb: 43, 48, 53; | |||
| --bs-primary-text-emphasis: #6ea8fe; | |||
| --bs-secondary-text-emphasis: #a7acb1; | |||
| --bs-success-text-emphasis: #75b798; | |||
| --bs-info-text-emphasis: #6edff6; | |||
| --bs-warning-text-emphasis: #ffda6a; | |||
| --bs-danger-text-emphasis: #ea868f; | |||
| --bs-light-text-emphasis: #f8f9fa; | |||
| --bs-dark-text-emphasis: #dee2e6; | |||
| --bs-primary-bg-subtle: #031633; | |||
| --bs-secondary-bg-subtle: #161719; | |||
| --bs-success-bg-subtle: #051b11; | |||
| --bs-info-bg-subtle: #032830; | |||
| --bs-warning-bg-subtle: #332701; | |||
| --bs-danger-bg-subtle: #2c0b0e; | |||
| --bs-light-bg-subtle: #343a40; | |||
| --bs-dark-bg-subtle: #1a1d20; | |||
| --bs-primary-border-subtle: #084298; | |||
| --bs-secondary-border-subtle: #41464b; | |||
| --bs-success-border-subtle: #0f5132; | |||
| --bs-info-border-subtle: #087990; | |||
| --bs-warning-border-subtle: #997404; | |||
| --bs-danger-border-subtle: #842029; | |||
| --bs-light-border-subtle: #495057; | |||
| --bs-dark-border-subtle: #343a40; | |||
| --bs-heading-color: inherit; | |||
| --bs-link-color: #6ea8fe; | |||
| --bs-link-hover-color: #8bb9fe; | |||
| --bs-link-color-rgb: 110, 168, 254; | |||
| --bs-link-hover-color-rgb: 139, 185, 254; | |||
| --bs-code-color: #e685b5; | |||
| --bs-border-color: #495057; | |||
| --bs-border-color-translucent: rgba(255, 255, 255, 0.15); | |||
| --bs-form-valid-color: #75b798; | |||
| --bs-form-valid-border-color: #75b798; | |||
| --bs-form-invalid-color: #ea868f; | |||
| --bs-form-invalid-border-color: #ea868f; | |||
| } | |||
| *, | |||
| *::before, | |||
| *::after { | |||
| box-sizing: border-box; | |||
| } | |||
| @media (prefers-reduced-motion: no-preference) { | |||
| :root { | |||
| scroll-behavior: smooth; | |||
| } | |||
| } | |||
| body { | |||
| margin: 0; | |||
| font-family: var(--bs-body-font-family); | |||
| font-size: var(--bs-body-font-size); | |||
| font-weight: var(--bs-body-font-weight); | |||
| line-height: var(--bs-body-line-height); | |||
| color: var(--bs-body-color); | |||
| text-align: var(--bs-body-text-align); | |||
| background-color: var(--bs-body-bg); | |||
| -webkit-text-size-adjust: 100%; | |||
| -webkit-tap-highlight-color: rgba(0, 0, 0, 0); | |||
| } | |||
| hr { | |||
| margin: 1rem 0; | |||
| color: inherit; | |||
| border: 0; | |||
| border-top: var(--bs-border-width) solid; | |||
| opacity: 0.25; | |||
| } | |||
| h6, h5, h4, h3, h2, h1 { | |||
| margin-top: 0; | |||
| margin-bottom: 0.5rem; | |||
| font-weight: 500; | |||
| line-height: 1.2; | |||
| color: var(--bs-heading-color); | |||
| } | |||
| h1 { | |||
| font-size: calc(1.375rem + 1.5vw); | |||
| } | |||
| @media (min-width: 1200px) { | |||
| h1 { | |||
| font-size: 2.5rem; | |||
| } | |||
| } | |||
| h2 { | |||
| font-size: calc(1.325rem + 0.9vw); | |||
| } | |||
| @media (min-width: 1200px) { | |||
| h2 { | |||
| font-size: 2rem; | |||
| } | |||
| } | |||
| h3 { | |||
| font-size: calc(1.3rem + 0.6vw); | |||
| } | |||
| @media (min-width: 1200px) { | |||
| h3 { | |||
| font-size: 1.75rem; | |||
| } | |||
| } | |||
| h4 { | |||
| font-size: calc(1.275rem + 0.3vw); | |||
| } | |||
| @media (min-width: 1200px) { | |||
| h4 { | |||
| font-size: 1.5rem; | |||
| } | |||
| } | |||
| h5 { | |||
| font-size: 1.25rem; | |||
| } | |||
| h6 { | |||
| font-size: 1rem; | |||
| } | |||
| p { | |||
| margin-top: 0; | |||
| margin-bottom: 1rem; | |||
| } | |||
| abbr[title] { | |||
| -webkit-text-decoration: underline dotted; | |||
| text-decoration: underline dotted; | |||
| cursor: help; | |||
| -webkit-text-decoration-skip-ink: none; | |||
| text-decoration-skip-ink: none; | |||
| } | |||
| address { | |||
| margin-bottom: 1rem; | |||
| font-style: normal; | |||
| line-height: inherit; | |||
| } | |||
| ol, | |||
| ul { | |||
| padding-right: 2rem; | |||
| } | |||
| ol, | |||
| ul, | |||
| dl { | |||
| margin-top: 0; | |||
| margin-bottom: 1rem; | |||
| } | |||
| ol ol, | |||
| ul ul, | |||
| ol ul, | |||
| ul ol { | |||
| margin-bottom: 0; | |||
| } | |||
| dt { | |||
| font-weight: 700; | |||
| } | |||
| dd { | |||
| margin-bottom: 0.5rem; | |||
| margin-right: 0; | |||
| } | |||
| blockquote { | |||
| margin: 0 0 1rem; | |||
| } | |||
| b, | |||
| strong { | |||
| font-weight: bolder; | |||
| } | |||
| small { | |||
| font-size: 0.875em; | |||
| } | |||
| mark { | |||
| padding: 0.1875em; | |||
| background-color: var(--bs-highlight-bg); | |||
| } | |||
| sub, | |||
| sup { | |||
| position: relative; | |||
| font-size: 0.75em; | |||
| line-height: 0; | |||
| vertical-align: baseline; | |||
| } | |||
| sub { | |||
| bottom: -0.25em; | |||
| } | |||
| sup { | |||
| top: -0.5em; | |||
| } | |||
| a { | |||
| color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1)); | |||
| text-decoration: underline; | |||
| } | |||
| a:hover { | |||
| --bs-link-color-rgb: var(--bs-link-hover-color-rgb); | |||
| } | |||
| a:not([href]):not([class]), a:not([href]):not([class]):hover { | |||
| color: inherit; | |||
| text-decoration: none; | |||
| } | |||
| pre, | |||
| code, | |||
| kbd, | |||
| samp { | |||
| font-family: var(--bs-font-monospace); | |||
| font-size: 1em; | |||
| } | |||
| pre { | |||
| display: block; | |||
| margin-top: 0; | |||
| margin-bottom: 1rem; | |||
| overflow: auto; | |||
| font-size: 0.875em; | |||
| } | |||
| pre code { | |||
| font-size: inherit; | |||
| color: inherit; | |||
| word-break: normal; | |||
| } | |||
| code { | |||
| font-size: 0.875em; | |||
| color: var(--bs-code-color); | |||
| word-wrap: break-word; | |||
| } | |||
| a > code { | |||
| color: inherit; | |||
| } | |||
| kbd { | |||
| padding: 0.1875rem 0.375rem; | |||
| font-size: 0.875em; | |||
| color: var(--bs-body-bg); | |||
| background-color: var(--bs-body-color); | |||
| border-radius: 0.25rem; | |||
| } | |||
| kbd kbd { | |||
| padding: 0; | |||
| font-size: 1em; | |||
| } | |||
| figure { | |||
| margin: 0 0 1rem; | |||
| } | |||
| img, | |||
| svg { | |||
| vertical-align: middle; | |||
| } | |||
| table { | |||
| caption-side: bottom; | |||
| border-collapse: collapse; | |||
| } | |||
| caption { | |||
| padding-top: 0.5rem; | |||
| padding-bottom: 0.5rem; | |||
| color: var(--bs-secondary-color); | |||
| text-align: right; | |||
| } | |||
| th { | |||
| text-align: inherit; | |||
| text-align: -webkit-match-parent; | |||
| } | |||
| thead, | |||
| tbody, | |||
| tfoot, | |||
| tr, | |||
| td, | |||
| th { | |||
| border-color: inherit; | |||
| border-style: solid; | |||
| border-width: 0; | |||
| } | |||
| label { | |||
| display: inline-block; | |||
| } | |||
| button { | |||
| border-radius: 0; | |||
| } | |||
| button:focus:not(:focus-visible) { | |||
| outline: 0; | |||
| } | |||
| input, | |||
| button, | |||
| select, | |||
| optgroup, | |||
| textarea { | |||
| margin: 0; | |||
| font-family: inherit; | |||
| font-size: inherit; | |||
| line-height: inherit; | |||
| } | |||
| button, | |||
| select { | |||
| text-transform: none; | |||
| } | |||
| [role=button] { | |||
| cursor: pointer; | |||
| } | |||
| select { | |||
| word-wrap: normal; | |||
| } | |||
| select:disabled { | |||
| opacity: 1; | |||
| } | |||
| [list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator { | |||
| display: none !important; | |||
| } | |||
| button, | |||
| [type=button], | |||
| [type=reset], | |||
| [type=submit] { | |||
| -webkit-appearance: button; | |||
| } | |||
| button:not(:disabled), | |||
| [type=button]:not(:disabled), | |||
| [type=reset]:not(:disabled), | |||
| [type=submit]:not(:disabled) { | |||
| cursor: pointer; | |||
| } | |||
| ::-moz-focus-inner { | |||
| padding: 0; | |||
| border-style: none; | |||
| } | |||
| textarea { | |||
| resize: vertical; | |||
| } | |||
| fieldset { | |||
| min-width: 0; | |||
| padding: 0; | |||
| margin: 0; | |||
| border: 0; | |||
| } | |||
| legend { | |||
| float: right; | |||
| width: 100%; | |||
| padding: 0; | |||
| margin-bottom: 0.5rem; | |||
| font-size: calc(1.275rem + 0.3vw); | |||
| line-height: inherit; | |||
| } | |||
| @media (min-width: 1200px) { | |||
| legend { | |||
| font-size: 1.5rem; | |||
| } | |||
| } | |||
| legend + * { | |||
| clear: right; | |||
| } | |||
| ::-webkit-datetime-edit-fields-wrapper, | |||
| ::-webkit-datetime-edit-text, | |||
| ::-webkit-datetime-edit-minute, | |||
| ::-webkit-datetime-edit-hour-field, | |||
| ::-webkit-datetime-edit-day-field, | |||
| ::-webkit-datetime-edit-month-field, | |||
| ::-webkit-datetime-edit-year-field { | |||
| padding: 0; | |||
| } | |||
| ::-webkit-inner-spin-button { | |||
| height: auto; | |||
| } | |||
| [type=search] { | |||
| outline-offset: -2px; | |||
| -webkit-appearance: textfield; | |||
| } | |||
| [type="tel"], | |||
| [type="url"], | |||
| [type="email"], | |||
| [type="number"] { | |||
| direction: ltr; | |||
| } | |||
| ::-webkit-search-decoration { | |||
| -webkit-appearance: none; | |||
| } | |||
| ::-webkit-color-swatch-wrapper { | |||
| padding: 0; | |||
| } | |||
| ::-webkit-file-upload-button { | |||
| font: inherit; | |||
| -webkit-appearance: button; | |||
| } | |||
| ::file-selector-button { | |||
| font: inherit; | |||
| -webkit-appearance: button; | |||
| } | |||
| output { | |||
| display: inline-block; | |||
| } | |||
| iframe { | |||
| border: 0; | |||
| } | |||
| summary { | |||
| display: list-item; | |||
| cursor: pointer; | |||
| } | |||
| progress { | |||
| vertical-align: baseline; | |||
| } | |||
| [hidden] { | |||
| display: none !important; | |||
| } | |||
| /*# sourceMappingURL=bootstrap-reboot.rtl.css.map */ | |||