Spaces:
Sleeping
Sleeping
Upload 34 files
Browse files- Dockerfile +34 -0
- app.py +664 -0
- makecsv.py +34 -0
- models.db +0 -0
- models/bert_finetuned/config.json +40 -0
- models/bert_finetuned/model.safetensors +3 -0
- models/bert_finetuned/special_tokens_map.json +7 -0
- models/bert_finetuned/tokenizer.json +0 -0
- models/bert_finetuned/tokenizer_config.json +56 -0
- models/bert_finetuned/training_args.bin +3 -0
- models/bert_finetuned/vocab.txt +0 -0
- models/chatbot_t5/config.json +60 -0
- models/chatbot_t5/generation_config.json +9 -0
- models/chatbot_t5/model.safetensors +3 -0
- models/chatbot_t5/special_tokens_map.json +125 -0
- models/chatbot_t5/spiece.model +3 -0
- models/chatbot_t5/tokenizer.json +0 -0
- models/chatbot_t5/tokenizer_config.json +939 -0
- models/chatbot_t5/training_args.bin +3 -0
- models/complaint_classifier_rf.pkl +3 -0
- models/tfidf_vectorizer.pkl +3 -0
- proejectremember_andnote.txt +111 -0
- requirements.txt +17 -0
- static/script.js +97 -0
- static/style.css +31 -0
- templates/admin_negatives.html +21 -0
- templates/base.html +47 -0
- templates/chat.html +38 -0
- templates/dashboard.html +7 -0
- templates/forgot.html +9 -0
- templates/index.html +30 -0
- templates/login.html +120 -0
- templates/register.html +112 -0
- templates/reset.html +10 -0
Dockerfile
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Use official Python base image
|
| 2 |
+
FROM python:3.10-slim
|
| 3 |
+
|
| 4 |
+
# Prevent Python from writing .pyc files & enable buffered output
|
| 5 |
+
ENV PYTHONDONTWRITEBYTECODE=1
|
| 6 |
+
ENV PYTHONUNBUFFERED=1
|
| 7 |
+
|
| 8 |
+
# Set working directory
|
| 9 |
+
WORKDIR /app
|
| 10 |
+
|
| 11 |
+
# Install system dependencies (useful for pandas, numpy, etc.)
|
| 12 |
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
| 13 |
+
build-essential \
|
| 14 |
+
git \
|
| 15 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 16 |
+
|
| 17 |
+
# Copy requirement file
|
| 18 |
+
COPY requirements.txt .
|
| 19 |
+
|
| 20 |
+
# Install Python dependencies
|
| 21 |
+
RUN pip install --no-cache-dir -r requirements.txt
|
| 22 |
+
|
| 23 |
+
# Copy application files
|
| 24 |
+
COPY . .
|
| 25 |
+
|
| 26 |
+
# Expose Flask default port
|
| 27 |
+
EXPOSE 5000
|
| 28 |
+
|
| 29 |
+
# Set Flask environment variables
|
| 30 |
+
ENV FLASK_APP=app.py
|
| 31 |
+
ENV FLASK_RUN_HOST=0.0.0.0
|
| 32 |
+
|
| 33 |
+
# Run Flask application
|
| 34 |
+
CMD ["flask", "run"]
|
app.py
ADDED
|
@@ -0,0 +1,664 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# from flask import Flask, render_template, request, jsonify
|
| 2 |
+
# import joblib
|
| 3 |
+
# import numpy as np
|
| 4 |
+
# from transformers import pipeline, AutoTokenizer, AutoModelForSequenceClassification, AutoModelForSeq2SeqLM
|
| 5 |
+
# from datetime import datetime
|
| 6 |
+
|
| 7 |
+
# app = Flask(__name__)
|
| 8 |
+
|
| 9 |
+
# # -----------------------------
|
| 10 |
+
# # Load Models
|
| 11 |
+
# # -----------------------------
|
| 12 |
+
# print("⏳ Loading models...")
|
| 13 |
+
|
| 14 |
+
# # 1️⃣ Category Classifier
|
| 15 |
+
# clf_model = joblib.load("models/complaint_classifier_rf.pkl")
|
| 16 |
+
# vectorizer = joblib.load("models/tfidf_vectorizer.pkl")
|
| 17 |
+
|
| 18 |
+
# # 2️⃣ Fine-Tuned BERT Sentiment Model
|
| 19 |
+
# sentiment_path = "models/bert_finetuned"
|
| 20 |
+
# sent_tokenizer = AutoTokenizer.from_pretrained(sentiment_path)
|
| 21 |
+
# sent_model = AutoModelForSequenceClassification.from_pretrained(sentiment_path)
|
| 22 |
+
# sentiment_pipe = pipeline("text-classification", model=sent_model, tokenizer=sent_tokenizer)
|
| 23 |
+
|
| 24 |
+
# # 3️⃣ Chatbot (T5)
|
| 25 |
+
# chatbot_path = "models/chatbot_t5"
|
| 26 |
+
# chat_tokenizer = AutoTokenizer.from_pretrained(chatbot_path)
|
| 27 |
+
# chat_model = AutoModelForSeq2SeqLM.from_pretrained(chatbot_path)
|
| 28 |
+
# chatbot = pipeline("text2text-generation", model=chat_model, tokenizer=chat_tokenizer)
|
| 29 |
+
|
| 30 |
+
# print("✅ All models loaded successfully!")
|
| 31 |
+
|
| 32 |
+
# # In-memory sentiment data (for analytics)
|
| 33 |
+
# sentiment_log = {"Positive": 0, "Negative": 0, "Neutral": 0}
|
| 34 |
+
# time_log = []
|
| 35 |
+
|
| 36 |
+
# # -----------------------------
|
| 37 |
+
# # Helper Functions
|
| 38 |
+
# # -----------------------------
|
| 39 |
+
# def predict_category(text):
|
| 40 |
+
# vec = vectorizer.transform([text])
|
| 41 |
+
# return clf_model.predict(vec)[0]
|
| 42 |
+
|
| 43 |
+
# def predict_sentiment(text):
|
| 44 |
+
# result = sentiment_pipe(text, truncation=True, max_length=128)[0]
|
| 45 |
+
# label = result["label"]
|
| 46 |
+
# score = round(result["score"] * 100, 2)
|
| 47 |
+
# if "NEG" in label.upper():
|
| 48 |
+
# sentiment = "Negative"
|
| 49 |
+
# elif "POS" in label.upper():
|
| 50 |
+
# sentiment = "Positive"
|
| 51 |
+
# else:
|
| 52 |
+
# sentiment = "Neutral"
|
| 53 |
+
# return sentiment, score
|
| 54 |
+
|
| 55 |
+
# def chatbot_reply(msg, category, sentiment):
|
| 56 |
+
# prompt = f"User: {msg} | Category: {category} | Sentiment: {sentiment}"
|
| 57 |
+
# reply = chatbot(prompt, max_new_tokens=80, num_return_sequences=1)[0]["generated_text"]
|
| 58 |
+
# return reply
|
| 59 |
+
|
| 60 |
+
# # -----------------------------
|
| 61 |
+
# # Routes
|
| 62 |
+
# # -----------------------------
|
| 63 |
+
# @app.route('/')
|
| 64 |
+
# def home():
|
| 65 |
+
# return render_template('index.html')
|
| 66 |
+
|
| 67 |
+
# @app.route('/analyze', methods=['POST'])
|
| 68 |
+
# def analyze():
|
| 69 |
+
# user_text = request.form['user_input'].strip().lower()
|
| 70 |
+
|
| 71 |
+
# # 🧠 1️⃣ Check for simple greetings or small talk
|
| 72 |
+
# smalltalk_responses = {
|
| 73 |
+
# "hi": "Hey there 👋 How can I help you today?",
|
| 74 |
+
# "hello": "Hello! How’s your day going?",
|
| 75 |
+
# "hey": "Hey! What can I do for you?",
|
| 76 |
+
# "thanks": "You're welcome 😊 Always happy to help!",
|
| 77 |
+
# "thank you": "No problem! Glad to assist 🙌",
|
| 78 |
+
# "good morning": "Good morning ☀️ Ready to get your deliveries moving?",
|
| 79 |
+
# "good evening": "Good evening 🌙 How can I assist?",
|
| 80 |
+
# "bye": "Goodbye 👋 Take care!",
|
| 81 |
+
# }
|
| 82 |
+
|
| 83 |
+
# for phrase, reply in smalltalk_responses.items():
|
| 84 |
+
# if user_text.startswith(phrase):
|
| 85 |
+
# return jsonify({
|
| 86 |
+
# "category": "Small Talk",
|
| 87 |
+
# "sentiment": "Neutral",
|
| 88 |
+
# "confidence": 100,
|
| 89 |
+
# "reply": reply
|
| 90 |
+
# })
|
| 91 |
+
|
| 92 |
+
# # 🧩 2️⃣ Continue with complaint classification
|
| 93 |
+
# category = predict_category(user_text)
|
| 94 |
+
# sentiment, confidence = predict_sentiment(user_text)
|
| 95 |
+
# bot_reply = chatbot_reply(user_text, category, sentiment)
|
| 96 |
+
|
| 97 |
+
# # 🧠 Log analytics
|
| 98 |
+
# sentiment_log[sentiment] += 1
|
| 99 |
+
# time_log.append({
|
| 100 |
+
# "time": datetime.now().strftime("%H:%M:%S"),
|
| 101 |
+
# "sentiment": sentiment
|
| 102 |
+
# })
|
| 103 |
+
|
| 104 |
+
# return jsonify({
|
| 105 |
+
# "category": category,
|
| 106 |
+
# "sentiment": sentiment,
|
| 107 |
+
# "confidence": confidence,
|
| 108 |
+
# "reply": bot_reply
|
| 109 |
+
# })
|
| 110 |
+
|
| 111 |
+
# @app.route('/analytics', methods=['GET'])
|
| 112 |
+
# def analytics():
|
| 113 |
+
# """Return sentiment distribution for chart"""
|
| 114 |
+
# return jsonify({
|
| 115 |
+
# "labels": list(sentiment_log.keys()),
|
| 116 |
+
# "values": list(sentiment_log.values()),
|
| 117 |
+
# "timeline": time_log[-20:]
|
| 118 |
+
# })
|
| 119 |
+
|
| 120 |
+
|
| 121 |
+
# if __name__ == "__main__":
|
| 122 |
+
# app.run(debug=True)
|
| 123 |
+
# app.py -- merged app (auth + DB + ML + chat + debug)
|
| 124 |
+
# app.py -- merged app (auth + DB + ML + chat + debug) - NO SMALL-TALK
|
| 125 |
+
import os
|
| 126 |
+
import random
|
| 127 |
+
import string
|
| 128 |
+
import threading
|
| 129 |
+
from datetime import datetime, timedelta
|
| 130 |
+
|
| 131 |
+
from flask import Flask, render_template, request, redirect, url_for, flash, jsonify
|
| 132 |
+
from flask_sqlalchemy import SQLAlchemy
|
| 133 |
+
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user
|
| 134 |
+
from flask_mail import Mail, Message
|
| 135 |
+
from werkzeug.security import generate_password_hash, check_password_hash
|
| 136 |
+
|
| 137 |
+
# ML imports
|
| 138 |
+
import joblib
|
| 139 |
+
from transformers import pipeline, AutoTokenizer, AutoModelForSequenceClassification, AutoModelForSeq2SeqLM
|
| 140 |
+
|
| 141 |
+
# ---------------------------
|
| 142 |
+
# Config
|
| 143 |
+
# ---------------------------
|
| 144 |
+
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
| 145 |
+
DB_PATH = os.path.join(BASE_DIR, "models.db")
|
| 146 |
+
|
| 147 |
+
app = Flask(__name__)
|
| 148 |
+
app.config['SECRET_KEY'] = os.environ.get("FLASK_SECRET", "super-secret-key")
|
| 149 |
+
app.config['SQLALCHEMY_DATABASE_URI'] = f"sqlite:///{DB_PATH}"
|
| 150 |
+
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
| 151 |
+
|
| 152 |
+
# Mail config (dev defaults)
|
| 153 |
+
app.config['MAIL_SERVER'] = os.environ.get("MAIL_SERVER", "localhost")
|
| 154 |
+
app.config['MAIL_PORT'] = int(os.environ.get("MAIL_PORT", 1025))
|
| 155 |
+
app.config['MAIL_USERNAME'] = os.environ.get("MAIL_USERNAME", "")
|
| 156 |
+
app.config['MAIL_PASSWORD'] = os.environ.get("MAIL_PASSWORD", "")
|
| 157 |
+
app.config['MAIL_USE_TLS'] = os.environ.get("MAIL_USE_TLS", "False") == "True"
|
| 158 |
+
app.config['MAIL_USE_SSL'] = os.environ.get("MAIL_USE_SSL", "False") == "True"
|
| 159 |
+
app.config['MAIL_DEFAULT_SENDER'] = os.environ.get("MAIL_DEFAULT_SENDER", "noreply@fastship.ai")
|
| 160 |
+
|
| 161 |
+
# ---------------------------
|
| 162 |
+
# Extensions
|
| 163 |
+
# ---------------------------
|
| 164 |
+
db = SQLAlchemy(app)
|
| 165 |
+
login_manager = LoginManager(app)
|
| 166 |
+
login_manager.login_view = "login"
|
| 167 |
+
mail = Mail(app)
|
| 168 |
+
|
| 169 |
+
# ---------------------------
|
| 170 |
+
# DB Models
|
| 171 |
+
# ---------------------------
|
| 172 |
+
class User(UserMixin, db.Model):
|
| 173 |
+
id = db.Column(db.Integer, primary_key=True)
|
| 174 |
+
fullname = db.Column(db.String(120))
|
| 175 |
+
email = db.Column(db.String(120), unique=True, nullable=False)
|
| 176 |
+
password_hash = db.Column(db.String(256), nullable=False)
|
| 177 |
+
phone = db.Column(db.String(32))
|
| 178 |
+
address = db.Column(db.String(256))
|
| 179 |
+
is_admin = db.Column(db.Boolean, default=False)
|
| 180 |
+
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
| 181 |
+
|
| 182 |
+
def set_password(self, password):
|
| 183 |
+
self.password_hash = generate_password_hash(password)
|
| 184 |
+
|
| 185 |
+
def check_password(self, password):
|
| 186 |
+
return check_password_hash(self.password_hash, password)
|
| 187 |
+
|
| 188 |
+
|
| 189 |
+
class OTP(db.Model):
|
| 190 |
+
id = db.Column(db.Integer, primary_key=True)
|
| 191 |
+
email = db.Column(db.String(120), nullable=False)
|
| 192 |
+
code = db.Column(db.String(8), nullable=False)
|
| 193 |
+
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
| 194 |
+
expires_at = db.Column(db.DateTime, nullable=False)
|
| 195 |
+
|
| 196 |
+
|
| 197 |
+
class ChatMessage(db.Model):
|
| 198 |
+
id = db.Column(db.Integer, primary_key=True)
|
| 199 |
+
user_id = db.Column(db.Integer, nullable=True)
|
| 200 |
+
username = db.Column(db.String(120))
|
| 201 |
+
address = db.Column(db.String(256))
|
| 202 |
+
order_id = db.Column(db.String(64), nullable=True)
|
| 203 |
+
message = db.Column(db.Text, nullable=False)
|
| 204 |
+
category = db.Column(db.String(120))
|
| 205 |
+
sentiment = db.Column(db.String(32))
|
| 206 |
+
status = db.Column(db.String(32), default="Pending")
|
| 207 |
+
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
| 208 |
+
|
| 209 |
+
with app.app_context():
|
| 210 |
+
db.create_all()
|
| 211 |
+
|
| 212 |
+
# ---------------------------
|
| 213 |
+
# Login loader
|
| 214 |
+
# ---------------------------
|
| 215 |
+
@login_manager.user_loader
|
| 216 |
+
def load_user(user_id):
|
| 217 |
+
return User.query.get(int(user_id))
|
| 218 |
+
|
| 219 |
+
# ---------------------------
|
| 220 |
+
# Utilities
|
| 221 |
+
# ---------------------------
|
| 222 |
+
def gen_otp_code(length=6):
|
| 223 |
+
return "".join(random.choices(string.digits, k=length))
|
| 224 |
+
|
| 225 |
+
def send_email(to_email, subject, body):
|
| 226 |
+
"""Try to send email. If SMTP not configured, fallback to printing to console."""
|
| 227 |
+
try:
|
| 228 |
+
msg = Message(subject, recipients=[to_email], html=body)
|
| 229 |
+
mail.send(msg)
|
| 230 |
+
app.logger.info("Email sent to %s", to_email)
|
| 231 |
+
return True
|
| 232 |
+
except Exception as e:
|
| 233 |
+
app.logger.warning("Could not send email (fallback). Exception: %s", e)
|
| 234 |
+
print("=== EMAIL Fallback ===")
|
| 235 |
+
print("To:", to_email)
|
| 236 |
+
print("Subject:", subject)
|
| 237 |
+
print(body)
|
| 238 |
+
print("======================")
|
| 239 |
+
return False
|
| 240 |
+
|
| 241 |
+
# ---------------------------
|
| 242 |
+
# ML model loading (attempt) - uses variable names matching your simple script
|
| 243 |
+
# ---------------------------
|
| 244 |
+
models_lock = threading.Lock()
|
| 245 |
+
|
| 246 |
+
clf_model = None
|
| 247 |
+
vectorizer = None
|
| 248 |
+
sentiment_pipe = None
|
| 249 |
+
sent_model = None
|
| 250 |
+
chatbot = None
|
| 251 |
+
chatbot_model = None
|
| 252 |
+
|
| 253 |
+
def load_models():
|
| 254 |
+
global clf_model, vectorizer, sentiment_pipe, sent_model, chatbot, chatbot_model
|
| 255 |
+
app.logger.info("Loading models from models/ ...")
|
| 256 |
+
|
| 257 |
+
# classifier + vectorizer (joblib)
|
| 258 |
+
try:
|
| 259 |
+
clf_model = joblib.load(os.path.join("models", "complaint_classifier_rf.pkl"))
|
| 260 |
+
vectorizer = joblib.load(os.path.join("models", "tfidf_vectorizer.pkl"))
|
| 261 |
+
app.logger.info("Classifier & vectorizer loaded.")
|
| 262 |
+
except Exception as e:
|
| 263 |
+
app.logger.warning("Classifier/vectorizer not loaded: %s", e)
|
| 264 |
+
clf_model = None
|
| 265 |
+
vectorizer = None
|
| 266 |
+
|
| 267 |
+
# sentiment (transformers)
|
| 268 |
+
try:
|
| 269 |
+
sentiment_path = os.path.join("models", "bert_finetuned")
|
| 270 |
+
sent_tokenizer = AutoTokenizer.from_pretrained(sentiment_path)
|
| 271 |
+
sent_model = AutoModelForSequenceClassification.from_pretrained(sentiment_path)
|
| 272 |
+
sentiment_pipe_local = pipeline("text-classification", model=sent_model, tokenizer=sent_tokenizer)
|
| 273 |
+
sentiment_pipe = sentiment_pipe_local
|
| 274 |
+
globals()['sentiment_pipe'] = sentiment_pipe
|
| 275 |
+
globals()['sent_model'] = sent_model
|
| 276 |
+
app.logger.info("Sentiment model loaded.")
|
| 277 |
+
except Exception as e:
|
| 278 |
+
app.logger.warning("Sentiment model not loaded: %s", e)
|
| 279 |
+
globals()['sentiment_pipe'] = None
|
| 280 |
+
globals()['sent_model'] = None
|
| 281 |
+
|
| 282 |
+
# chatbot (t5)
|
| 283 |
+
try:
|
| 284 |
+
chatbot_path = os.path.join("models", "chatbot_t5")
|
| 285 |
+
chat_tokenizer = AutoTokenizer.from_pretrained(chatbot_path)
|
| 286 |
+
chatbot_model_local = AutoModelForSeq2SeqLM.from_pretrained(chatbot_path)
|
| 287 |
+
chatbot_pipe = pipeline("text2text-generation", model=chatbot_model_local, tokenizer=chat_tokenizer)
|
| 288 |
+
globals()['chatbot'] = chatbot_pipe
|
| 289 |
+
globals()['chatbot_model'] = chatbot_model_local
|
| 290 |
+
app.logger.info("Chatbot model loaded.")
|
| 291 |
+
except Exception as e:
|
| 292 |
+
app.logger.warning("Chatbot model not loaded: %s", e)
|
| 293 |
+
globals()['chatbot'] = None
|
| 294 |
+
globals()['chatbot_model'] = None
|
| 295 |
+
|
| 296 |
+
with app.app_context():
|
| 297 |
+
load_models()
|
| 298 |
+
|
| 299 |
+
# -----------------------------
|
| 300 |
+
# Model functions (model-driven, no heuristics / no small-talk)
|
| 301 |
+
# -----------------------------
|
| 302 |
+
def predict_category(text):
|
| 303 |
+
"""
|
| 304 |
+
Return predicted category string if model available,
|
| 305 |
+
otherwise return None (so caller returns models_missing).
|
| 306 |
+
"""
|
| 307 |
+
if clf_model is None or vectorizer is None:
|
| 308 |
+
return None
|
| 309 |
+
try:
|
| 310 |
+
vec = vectorizer.transform([text])
|
| 311 |
+
return clf_model.predict(vec)[0]
|
| 312 |
+
except Exception as e:
|
| 313 |
+
app.logger.error("Classifier predict error: %s", e)
|
| 314 |
+
return None
|
| 315 |
+
|
| 316 |
+
def predict_sentiment(text):
|
| 317 |
+
"""
|
| 318 |
+
Robust model mapping. Returns (sentiment_label, confidence_score) or (None, None) if model missing/error.
|
| 319 |
+
"""
|
| 320 |
+
if sentiment_pipe is None:
|
| 321 |
+
return None, None
|
| 322 |
+
try:
|
| 323 |
+
with models_lock:
|
| 324 |
+
out = sentiment_pipe(text, truncation=True, max_length=128)[0]
|
| 325 |
+
raw_label = out.get("label", "")
|
| 326 |
+
score = round(out.get("score", 0.0) * 100, 2)
|
| 327 |
+
|
| 328 |
+
# Map LABEL_0 style to real labels if model.config.id2label exists
|
| 329 |
+
try:
|
| 330 |
+
cfg = getattr(sent_model, "config", None)
|
| 331 |
+
if cfg is not None and hasattr(cfg, "id2label"):
|
| 332 |
+
if raw_label.upper().startswith("LABEL_"):
|
| 333 |
+
try:
|
| 334 |
+
idx = int(raw_label.split("_")[-1])
|
| 335 |
+
mapped = cfg.id2label.get(idx, raw_label)
|
| 336 |
+
raw_label = mapped
|
| 337 |
+
except Exception:
|
| 338 |
+
pass
|
| 339 |
+
except Exception:
|
| 340 |
+
pass
|
| 341 |
+
|
| 342 |
+
rl = raw_label.upper()
|
| 343 |
+
if "NEG" in rl:
|
| 344 |
+
return "Negative", score
|
| 345 |
+
if "POS" in rl:
|
| 346 |
+
return "Positive", score
|
| 347 |
+
if "NEU" in rl:
|
| 348 |
+
return "Neutral", score
|
| 349 |
+
|
| 350 |
+
# default to Neutral to stay model-driven
|
| 351 |
+
return "Neutral", score
|
| 352 |
+
|
| 353 |
+
except Exception as e:
|
| 354 |
+
app.logger.error("Sentiment pipeline error: %s", e)
|
| 355 |
+
return None, None
|
| 356 |
+
|
| 357 |
+
def chatbot_reply(msg, category, sentiment):
|
| 358 |
+
"""
|
| 359 |
+
Return chatbot-generated string if model exists, otherwise None.
|
| 360 |
+
"""
|
| 361 |
+
if chatbot is None:
|
| 362 |
+
return None
|
| 363 |
+
try:
|
| 364 |
+
prompt = f"User: {msg} | Category: {category} | Sentiment: {sentiment}"
|
| 365 |
+
with models_lock:
|
| 366 |
+
out = chatbot(prompt, max_new_tokens=80, num_return_sequences=1)[0]
|
| 367 |
+
return out.get("generated_text") or out.get("text") or str(out)
|
| 368 |
+
except Exception as e:
|
| 369 |
+
app.logger.error("Chatbot pipeline error: %s", e)
|
| 370 |
+
return None
|
| 371 |
+
|
| 372 |
+
# -----------------------------
|
| 373 |
+
# In-memory analytics (optional)
|
| 374 |
+
# -----------------------------
|
| 375 |
+
sentiment_log = {"Positive": 0, "Negative": 0, "Neutral": 0}
|
| 376 |
+
time_log = []
|
| 377 |
+
|
| 378 |
+
# ---------------------------
|
| 379 |
+
# Debug / Health endpoints
|
| 380 |
+
# ---------------------------
|
| 381 |
+
@app.route('/health')
|
| 382 |
+
def health():
|
| 383 |
+
return jsonify({
|
| 384 |
+
"classifier_loaded": clf_model is not None,
|
| 385 |
+
"vectorizer_loaded": vectorizer is not None,
|
| 386 |
+
"sentiment_loaded": sentiment_pipe is not None,
|
| 387 |
+
"chatbot_loaded": chatbot is not None
|
| 388 |
+
})
|
| 389 |
+
|
| 390 |
+
@app.route('/debug/sentiment', methods=['GET'])
|
| 391 |
+
def debug_sentiment():
|
| 392 |
+
text = request.args.get('text', None)
|
| 393 |
+
if not text:
|
| 394 |
+
return jsonify({"error": "provide ?text=..."}), 400
|
| 395 |
+
pipeline_output = None
|
| 396 |
+
pipeline_error = None
|
| 397 |
+
id2label = None
|
| 398 |
+
if sentiment_pipe is not None:
|
| 399 |
+
try:
|
| 400 |
+
with models_lock:
|
| 401 |
+
pipeline_output = sentiment_pipe(text, truncation=True, max_length=128)
|
| 402 |
+
except Exception as e:
|
| 403 |
+
pipeline_error = str(e)
|
| 404 |
+
try:
|
| 405 |
+
model_obj = sent_model
|
| 406 |
+
if model_obj is not None and hasattr(model_obj.config, "id2label"):
|
| 407 |
+
id2label = dict(model_obj.config.id2label)
|
| 408 |
+
except Exception:
|
| 409 |
+
id2label = None
|
| 410 |
+
return jsonify({
|
| 411 |
+
"text": text,
|
| 412 |
+
"pipeline_output": pipeline_output,
|
| 413 |
+
"pipeline_error": pipeline_error,
|
| 414 |
+
"id2label": id2label
|
| 415 |
+
})
|
| 416 |
+
|
| 417 |
+
# ---------------------------
|
| 418 |
+
# Routes: Auth pages
|
| 419 |
+
# ---------------------------
|
| 420 |
+
@app.route('/')
|
| 421 |
+
def index():
|
| 422 |
+
return redirect(url_for('login'))
|
| 423 |
+
|
| 424 |
+
@app.route('/register', methods=['GET', 'POST'])
|
| 425 |
+
def register():
|
| 426 |
+
if request.method == "POST":
|
| 427 |
+
fullname = request.form.get("fullname", "").strip()
|
| 428 |
+
email = request.form.get("email", "").strip().lower()
|
| 429 |
+
password = request.form.get("password", "")
|
| 430 |
+
phone = request.form.get("phone", "")
|
| 431 |
+
address = request.form.get("address", "")
|
| 432 |
+
|
| 433 |
+
if not fullname or not email or not password:
|
| 434 |
+
flash("Please fill required fields", "warning")
|
| 435 |
+
return redirect(url_for("register"))
|
| 436 |
+
|
| 437 |
+
if User.query.filter_by(email=email).first():
|
| 438 |
+
flash("Email already registered. Try logging in.", "warning")
|
| 439 |
+
return redirect(url_for("login"))
|
| 440 |
+
|
| 441 |
+
user = User(fullname=fullname, email=email, phone=phone, address=address)
|
| 442 |
+
user.set_password(password)
|
| 443 |
+
db.session.add(user)
|
| 444 |
+
db.session.commit()
|
| 445 |
+
flash("Registered successfully. Please log in.", "success")
|
| 446 |
+
return redirect(url_for("login"))
|
| 447 |
+
return render_template("register.html")
|
| 448 |
+
|
| 449 |
+
@app.route('/login', methods=['GET', 'POST'])
|
| 450 |
+
def login():
|
| 451 |
+
if request.method == "POST":
|
| 452 |
+
email = request.form.get("email", "").strip().lower()
|
| 453 |
+
password = request.form.get("password", "")
|
| 454 |
+
user = User.query.filter_by(email=email).first()
|
| 455 |
+
if not user or not user.check_password(password):
|
| 456 |
+
flash("Invalid credentials", "danger")
|
| 457 |
+
return redirect(url_for("login"))
|
| 458 |
+
login_user(user)
|
| 459 |
+
flash("Logged in successfully", "success")
|
| 460 |
+
return redirect(url_for("chat"))
|
| 461 |
+
return render_template("login.html")
|
| 462 |
+
|
| 463 |
+
@app.route('/logout')
|
| 464 |
+
@login_required
|
| 465 |
+
def logout():
|
| 466 |
+
logout_user()
|
| 467 |
+
flash("Logged out", "info")
|
| 468 |
+
return redirect(url_for("login"))
|
| 469 |
+
|
| 470 |
+
# ---------------------------
|
| 471 |
+
# Forgot / Reset
|
| 472 |
+
# ---------------------------
|
| 473 |
+
@app.route('/forgot', methods=['GET', 'POST'])
|
| 474 |
+
def forgot():
|
| 475 |
+
if request.method == "POST":
|
| 476 |
+
email = request.form.get("email", "").strip().lower()
|
| 477 |
+
user = User.query.filter_by(email=email).first()
|
| 478 |
+
if not user:
|
| 479 |
+
flash("Email not registered", "warning")
|
| 480 |
+
return redirect(url_for("forgot"))
|
| 481 |
+
code = gen_otp_code()
|
| 482 |
+
expires = datetime.utcnow() + timedelta(minutes=10)
|
| 483 |
+
otp = OTP(email=email, code=code, expires_at=expires)
|
| 484 |
+
db.session.add(otp)
|
| 485 |
+
db.session.commit()
|
| 486 |
+
|
| 487 |
+
body = f"<p>Your FastShip OTP to reset password is <b>{code}</b>. It expires in 10 minutes.</p>"
|
| 488 |
+
send_email(email, "Your FastShip Password Reset OTP", body)
|
| 489 |
+
flash("OTP sent to your email (check console if SMTP is not configured).", "info")
|
| 490 |
+
return redirect(url_for("reset"))
|
| 491 |
+
return render_template("forgot.html")
|
| 492 |
+
|
| 493 |
+
@app.route('/reset', methods=['GET', 'POST'])
|
| 494 |
+
def reset():
|
| 495 |
+
if request.method == "POST":
|
| 496 |
+
email = request.form.get("email", "").strip().lower()
|
| 497 |
+
code = request.form.get("otp", "").strip()
|
| 498 |
+
new_password = request.form.get("password", "")
|
| 499 |
+
|
| 500 |
+
otp = OTP.query.filter_by(email=email, code=code).order_by(OTP.created_at.desc()).first()
|
| 501 |
+
if not otp:
|
| 502 |
+
flash("Invalid OTP", "danger")
|
| 503 |
+
return redirect(url_for("reset"))
|
| 504 |
+
if datetime.utcnow() > otp.expires_at:
|
| 505 |
+
flash("OTP expired", "danger")
|
| 506 |
+
return redirect(url_for("forgot"))
|
| 507 |
+
|
| 508 |
+
user = User.query.filter_by(email=email).first()
|
| 509 |
+
if not user:
|
| 510 |
+
flash("User not found", "danger")
|
| 511 |
+
return redirect(url_for("register"))
|
| 512 |
+
|
| 513 |
+
user.set_password(new_password)
|
| 514 |
+
db.session.commit()
|
| 515 |
+
|
| 516 |
+
OTP.query.filter_by(email=email).delete()
|
| 517 |
+
db.session.commit()
|
| 518 |
+
|
| 519 |
+
flash("Password reset successful. Please login.", "success")
|
| 520 |
+
return redirect(url_for("login"))
|
| 521 |
+
return render_template("reset.html")
|
| 522 |
+
|
| 523 |
+
# ---------------------------
|
| 524 |
+
# Chat page & analyze (direct model flow, NO small-talk)
|
| 525 |
+
# ---------------------------
|
| 526 |
+
@app.route('/chat', methods=['GET', 'POST'])
|
| 527 |
+
@login_required
|
| 528 |
+
def chat():
|
| 529 |
+
if request.method == "GET":
|
| 530 |
+
return render_template("chat.html", username=current_user.fullname)
|
| 531 |
+
|
| 532 |
+
user_text = request.form.get("user_input", "").strip()
|
| 533 |
+
order_id = request.form.get("order_id", "").strip()
|
| 534 |
+
username = current_user.fullname
|
| 535 |
+
address = current_user.address or ""
|
| 536 |
+
|
| 537 |
+
if not user_text:
|
| 538 |
+
return jsonify({"error": "empty"}), 400
|
| 539 |
+
|
| 540 |
+
category = predict_category(user_text)
|
| 541 |
+
sentiment, confidence = predict_sentiment(user_text)
|
| 542 |
+
bot_reply = chatbot_reply(user_text, category, sentiment)
|
| 543 |
+
|
| 544 |
+
missing = []
|
| 545 |
+
if category is None:
|
| 546 |
+
missing.append("category classifier")
|
| 547 |
+
if sentiment is None:
|
| 548 |
+
missing.append("sentiment model")
|
| 549 |
+
if bot_reply is None:
|
| 550 |
+
missing.append("chatbot model")
|
| 551 |
+
if missing:
|
| 552 |
+
return jsonify({
|
| 553 |
+
"error": "models_missing",
|
| 554 |
+
"message": f"Required model(s) not loaded: {', '.join(missing)}"
|
| 555 |
+
}), 503
|
| 556 |
+
|
| 557 |
+
# Save message
|
| 558 |
+
msg = ChatMessage(user_id=current_user.id, username=username, address=address,
|
| 559 |
+
order_id=order_id, message=user_text, category=category,
|
| 560 |
+
sentiment=sentiment, status="Pending")
|
| 561 |
+
db.session.add(msg)
|
| 562 |
+
db.session.commit()
|
| 563 |
+
|
| 564 |
+
# Escalate if negative
|
| 565 |
+
if sentiment == "Negative":
|
| 566 |
+
if "delivery" in (category or "").lower():
|
| 567 |
+
assigned = "Delivery Team"
|
| 568 |
+
elif "refund" in (category or "").lower():
|
| 569 |
+
assigned = "Finance"
|
| 570 |
+
elif "damage" in (category or "").lower():
|
| 571 |
+
assigned = "Warehouse"
|
| 572 |
+
else:
|
| 573 |
+
assigned = "Customer Care"
|
| 574 |
+
msg.status = f"Escalated to {assigned}"
|
| 575 |
+
db.session.commit()
|
| 576 |
+
|
| 577 |
+
sentiment_log.setdefault(sentiment, 0)
|
| 578 |
+
sentiment_log[sentiment] += 1
|
| 579 |
+
time_log.append({"time": datetime.now().strftime("%H:%M:%S"), "sentiment": sentiment})
|
| 580 |
+
|
| 581 |
+
return jsonify({
|
| 582 |
+
"category": category,
|
| 583 |
+
"sentiment": sentiment,
|
| 584 |
+
"confidence": confidence,
|
| 585 |
+
"reply": bot_reply
|
| 586 |
+
})
|
| 587 |
+
|
| 588 |
+
@app.route('/analyze', methods=['POST'])
|
| 589 |
+
def analyze():
|
| 590 |
+
user_text = request.form.get('user_input', '').strip()
|
| 591 |
+
if not user_text:
|
| 592 |
+
return jsonify({"error": "empty"}), 400
|
| 593 |
+
|
| 594 |
+
category = predict_category(user_text)
|
| 595 |
+
sentiment, confidence = predict_sentiment(user_text)
|
| 596 |
+
reply = chatbot_reply(user_text, category, sentiment)
|
| 597 |
+
|
| 598 |
+
missing = []
|
| 599 |
+
if category is None:
|
| 600 |
+
missing.append("category classifier")
|
| 601 |
+
if sentiment is None:
|
| 602 |
+
missing.append("sentiment model")
|
| 603 |
+
if reply is None:
|
| 604 |
+
missing.append("chatbot model")
|
| 605 |
+
if missing:
|
| 606 |
+
return jsonify({
|
| 607 |
+
"error": "models_missing",
|
| 608 |
+
"message": f"Required model(s) not loaded: {', '.join(missing)}"
|
| 609 |
+
}), 503
|
| 610 |
+
|
| 611 |
+
sentiment_log.setdefault(sentiment, 0)
|
| 612 |
+
sentiment_log[sentiment] += 1
|
| 613 |
+
time_log.append({"time": datetime.now().strftime("%H:%M:%S"), "sentiment": sentiment})
|
| 614 |
+
|
| 615 |
+
return jsonify({
|
| 616 |
+
"category": category,
|
| 617 |
+
"sentiment": sentiment,
|
| 618 |
+
"confidence": confidence,
|
| 619 |
+
"reply": reply
|
| 620 |
+
})
|
| 621 |
+
|
| 622 |
+
# ---------------------------
|
| 623 |
+
# Admin / Dashboard / Analytics
|
| 624 |
+
# ---------------------------
|
| 625 |
+
@app.route('/analytics', methods=['GET'])
|
| 626 |
+
def analytics():
|
| 627 |
+
return jsonify({
|
| 628 |
+
"labels": list(sentiment_log.keys()),
|
| 629 |
+
"values": list(sentiment_log.values()),
|
| 630 |
+
"timeline": time_log[-20:]
|
| 631 |
+
})
|
| 632 |
+
|
| 633 |
+
@app.route('/dashboard')
|
| 634 |
+
@login_required
|
| 635 |
+
def dashboard():
|
| 636 |
+
total = ChatMessage.query.count()
|
| 637 |
+
neg = ChatMessage.query.filter_by(sentiment="Negative").count()
|
| 638 |
+
pos = ChatMessage.query.filter_by(sentiment="Positive").count()
|
| 639 |
+
neu = ChatMessage.query.filter_by(sentiment="Neutral").count()
|
| 640 |
+
return render_template("dashboard.html", total=total, neg=neg, pos=pos, neu=neu)
|
| 641 |
+
|
| 642 |
+
@app.route('/admin/negatives')
|
| 643 |
+
@login_required
|
| 644 |
+
def admin_negatives():
|
| 645 |
+
if not current_user.is_admin:
|
| 646 |
+
flash("Admin access required", "danger")
|
| 647 |
+
return redirect(url_for("chat"))
|
| 648 |
+
negatives = ChatMessage.query.filter_by(sentiment="Negative").order_by(ChatMessage.created_at.desc()).limit(200).all()
|
| 649 |
+
return render_template("admin_negatives.html", negatives=negatives)
|
| 650 |
+
|
| 651 |
+
# ---------------------------
|
| 652 |
+
# Run
|
| 653 |
+
# ---------------------------
|
| 654 |
+
if __name__ == "__main__":
|
| 655 |
+
with app.app_context():
|
| 656 |
+
if User.query.filter_by(is_admin=True).count() == 0:
|
| 657 |
+
admin = User(fullname="Admin", email="admin@fastship.ai", phone="", address="")
|
| 658 |
+
admin.set_password("admin123")
|
| 659 |
+
admin.is_admin = True
|
| 660 |
+
db.session.add(admin)
|
| 661 |
+
db.session.commit()
|
| 662 |
+
print("Admin user created: admin@fastship.ai / admin123")
|
| 663 |
+
|
| 664 |
+
app.run(debug=True)
|
makecsv.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import pandas as pd
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
# Define file paths
|
| 5 |
+
raw_file = os.path.join('data', 'complaints_dataset.txt')
|
| 6 |
+
clean_csv = os.path.join('data', 'complaints_dataset.csv')
|
| 7 |
+
|
| 8 |
+
# Load text data
|
| 9 |
+
df = pd.read_csv(raw_file,
|
| 10 |
+
names=['complaint_text', 'category', 'sentiment', 'urgency'])
|
| 11 |
+
|
| 12 |
+
# Clean data
|
| 13 |
+
df['complaint_text'] = df['complaint_text'].astype(str).str.strip()
|
| 14 |
+
df['category'] = df['category'].astype(str).str.title().str.strip()
|
| 15 |
+
df['sentiment'] = df['sentiment'].astype(str).str.capitalize().str.strip()
|
| 16 |
+
df['urgency'] = df['urgency'].astype(str).str.capitalize().str.strip()
|
| 17 |
+
|
| 18 |
+
# Remove blanks & duplicates
|
| 19 |
+
df = df.dropna().drop_duplicates()
|
| 20 |
+
|
| 21 |
+
# Print summary
|
| 22 |
+
print("✅ Dataset cleaned successfully!")
|
| 23 |
+
print("Total Rows:", df.shape[0])
|
| 24 |
+
print("Categories:", df['category'].unique())
|
| 25 |
+
print("Sentiments:", df['sentiment'].unique())
|
| 26 |
+
print("Urgency Levels:", df['urgency'].unique())
|
| 27 |
+
|
| 28 |
+
# Save clean CSV
|
| 29 |
+
df.to_csv(clean_csv, index=False, encoding='utf-8')
|
| 30 |
+
print(f"\n💾 Clean CSV saved to: {clean_csv}")
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
|
models.db
ADDED
|
Binary file (20.5 kB). View file
|
|
|
models/bert_finetuned/config.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"activation": "gelu",
|
| 3 |
+
"architectures": [
|
| 4 |
+
"DistilBertForSequenceClassification"
|
| 5 |
+
],
|
| 6 |
+
"attention_dropout": 0.1,
|
| 7 |
+
"dim": 768,
|
| 8 |
+
"dropout": 0.1,
|
| 9 |
+
"dtype": "float32",
|
| 10 |
+
"hidden_dim": 3072,
|
| 11 |
+
"id2label": {
|
| 12 |
+
"0": "High",
|
| 13 |
+
"1": "Mixed",
|
| 14 |
+
"2": "Nan",
|
| 15 |
+
"3": "Negative",
|
| 16 |
+
"4": "Neutral",
|
| 17 |
+
"5": "Positive"
|
| 18 |
+
},
|
| 19 |
+
"initializer_range": 0.02,
|
| 20 |
+
"label2id": {
|
| 21 |
+
"High": 0,
|
| 22 |
+
"Mixed": 1,
|
| 23 |
+
"Nan": 2,
|
| 24 |
+
"Negative": 3,
|
| 25 |
+
"Neutral": 4,
|
| 26 |
+
"Positive": 5
|
| 27 |
+
},
|
| 28 |
+
"max_position_embeddings": 512,
|
| 29 |
+
"model_type": "distilbert",
|
| 30 |
+
"n_heads": 12,
|
| 31 |
+
"n_layers": 6,
|
| 32 |
+
"pad_token_id": 0,
|
| 33 |
+
"problem_type": "single_label_classification",
|
| 34 |
+
"qa_dropout": 0.1,
|
| 35 |
+
"seq_classif_dropout": 0.2,
|
| 36 |
+
"sinusoidal_pos_embds": false,
|
| 37 |
+
"tie_weights_": true,
|
| 38 |
+
"transformers_version": "4.57.1",
|
| 39 |
+
"vocab_size": 30522
|
| 40 |
+
}
|
models/bert_finetuned/model.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:f52bec55cee880cd15a3b5d7fd34cdb39fda37687a3ff2effe6fb5ff913066d1
|
| 3 |
+
size 267844872
|
models/bert_finetuned/special_tokens_map.json
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cls_token": "[CLS]",
|
| 3 |
+
"mask_token": "[MASK]",
|
| 4 |
+
"pad_token": "[PAD]",
|
| 5 |
+
"sep_token": "[SEP]",
|
| 6 |
+
"unk_token": "[UNK]"
|
| 7 |
+
}
|
models/bert_finetuned/tokenizer.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
models/bert_finetuned/tokenizer_config.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"added_tokens_decoder": {
|
| 3 |
+
"0": {
|
| 4 |
+
"content": "[PAD]",
|
| 5 |
+
"lstrip": false,
|
| 6 |
+
"normalized": false,
|
| 7 |
+
"rstrip": false,
|
| 8 |
+
"single_word": false,
|
| 9 |
+
"special": true
|
| 10 |
+
},
|
| 11 |
+
"100": {
|
| 12 |
+
"content": "[UNK]",
|
| 13 |
+
"lstrip": false,
|
| 14 |
+
"normalized": false,
|
| 15 |
+
"rstrip": false,
|
| 16 |
+
"single_word": false,
|
| 17 |
+
"special": true
|
| 18 |
+
},
|
| 19 |
+
"101": {
|
| 20 |
+
"content": "[CLS]",
|
| 21 |
+
"lstrip": false,
|
| 22 |
+
"normalized": false,
|
| 23 |
+
"rstrip": false,
|
| 24 |
+
"single_word": false,
|
| 25 |
+
"special": true
|
| 26 |
+
},
|
| 27 |
+
"102": {
|
| 28 |
+
"content": "[SEP]",
|
| 29 |
+
"lstrip": false,
|
| 30 |
+
"normalized": false,
|
| 31 |
+
"rstrip": false,
|
| 32 |
+
"single_word": false,
|
| 33 |
+
"special": true
|
| 34 |
+
},
|
| 35 |
+
"103": {
|
| 36 |
+
"content": "[MASK]",
|
| 37 |
+
"lstrip": false,
|
| 38 |
+
"normalized": false,
|
| 39 |
+
"rstrip": false,
|
| 40 |
+
"single_word": false,
|
| 41 |
+
"special": true
|
| 42 |
+
}
|
| 43 |
+
},
|
| 44 |
+
"clean_up_tokenization_spaces": false,
|
| 45 |
+
"cls_token": "[CLS]",
|
| 46 |
+
"do_lower_case": true,
|
| 47 |
+
"extra_special_tokens": {},
|
| 48 |
+
"mask_token": "[MASK]",
|
| 49 |
+
"model_max_length": 512,
|
| 50 |
+
"pad_token": "[PAD]",
|
| 51 |
+
"sep_token": "[SEP]",
|
| 52 |
+
"strip_accents": null,
|
| 53 |
+
"tokenize_chinese_chars": true,
|
| 54 |
+
"tokenizer_class": "DistilBertTokenizer",
|
| 55 |
+
"unk_token": "[UNK]"
|
| 56 |
+
}
|
models/bert_finetuned/training_args.bin
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d8cbecec005080b4bbac951219f279f5417b9bc24736fbc1bb182fa59d8e7abf
|
| 3 |
+
size 5777
|
models/bert_finetuned/vocab.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
models/chatbot_t5/config.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"architectures": [
|
| 3 |
+
"T5ForConditionalGeneration"
|
| 4 |
+
],
|
| 5 |
+
"classifier_dropout": 0.0,
|
| 6 |
+
"d_ff": 2048,
|
| 7 |
+
"d_kv": 64,
|
| 8 |
+
"d_model": 512,
|
| 9 |
+
"decoder_start_token_id": 0,
|
| 10 |
+
"dense_act_fn": "relu",
|
| 11 |
+
"dropout_rate": 0.1,
|
| 12 |
+
"dtype": "float32",
|
| 13 |
+
"eos_token_id": 1,
|
| 14 |
+
"feed_forward_proj": "relu",
|
| 15 |
+
"initializer_factor": 1.0,
|
| 16 |
+
"is_encoder_decoder": true,
|
| 17 |
+
"is_gated_act": false,
|
| 18 |
+
"layer_norm_epsilon": 1e-06,
|
| 19 |
+
"model_type": "t5",
|
| 20 |
+
"n_positions": 512,
|
| 21 |
+
"num_decoder_layers": 6,
|
| 22 |
+
"num_heads": 8,
|
| 23 |
+
"num_layers": 6,
|
| 24 |
+
"output_past": true,
|
| 25 |
+
"pad_token_id": 0,
|
| 26 |
+
"relative_attention_max_distance": 128,
|
| 27 |
+
"relative_attention_num_buckets": 32,
|
| 28 |
+
"task_specific_params": {
|
| 29 |
+
"summarization": {
|
| 30 |
+
"early_stopping": true,
|
| 31 |
+
"length_penalty": 2.0,
|
| 32 |
+
"max_length": 200,
|
| 33 |
+
"min_length": 30,
|
| 34 |
+
"no_repeat_ngram_size": 3,
|
| 35 |
+
"num_beams": 4,
|
| 36 |
+
"prefix": "summarize: "
|
| 37 |
+
},
|
| 38 |
+
"translation_en_to_de": {
|
| 39 |
+
"early_stopping": true,
|
| 40 |
+
"max_length": 300,
|
| 41 |
+
"num_beams": 4,
|
| 42 |
+
"prefix": "translate English to German: "
|
| 43 |
+
},
|
| 44 |
+
"translation_en_to_fr": {
|
| 45 |
+
"early_stopping": true,
|
| 46 |
+
"max_length": 300,
|
| 47 |
+
"num_beams": 4,
|
| 48 |
+
"prefix": "translate English to French: "
|
| 49 |
+
},
|
| 50 |
+
"translation_en_to_ro": {
|
| 51 |
+
"early_stopping": true,
|
| 52 |
+
"max_length": 300,
|
| 53 |
+
"num_beams": 4,
|
| 54 |
+
"prefix": "translate English to Romanian: "
|
| 55 |
+
}
|
| 56 |
+
},
|
| 57 |
+
"transformers_version": "4.57.1",
|
| 58 |
+
"use_cache": true,
|
| 59 |
+
"vocab_size": 32128
|
| 60 |
+
}
|
models/chatbot_t5/generation_config.json
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"_from_model_config": true,
|
| 3 |
+
"decoder_start_token_id": 0,
|
| 4 |
+
"eos_token_id": [
|
| 5 |
+
1
|
| 6 |
+
],
|
| 7 |
+
"pad_token_id": 0,
|
| 8 |
+
"transformers_version": "4.57.1"
|
| 9 |
+
}
|
models/chatbot_t5/model.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:f4a4bb4927a4d4fb0ea1af56ebef9466d28864e6dcdfbc41daa28f47e2b3226b
|
| 3 |
+
size 242041896
|
models/chatbot_t5/special_tokens_map.json
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"additional_special_tokens": [
|
| 3 |
+
"<extra_id_0>",
|
| 4 |
+
"<extra_id_1>",
|
| 5 |
+
"<extra_id_2>",
|
| 6 |
+
"<extra_id_3>",
|
| 7 |
+
"<extra_id_4>",
|
| 8 |
+
"<extra_id_5>",
|
| 9 |
+
"<extra_id_6>",
|
| 10 |
+
"<extra_id_7>",
|
| 11 |
+
"<extra_id_8>",
|
| 12 |
+
"<extra_id_9>",
|
| 13 |
+
"<extra_id_10>",
|
| 14 |
+
"<extra_id_11>",
|
| 15 |
+
"<extra_id_12>",
|
| 16 |
+
"<extra_id_13>",
|
| 17 |
+
"<extra_id_14>",
|
| 18 |
+
"<extra_id_15>",
|
| 19 |
+
"<extra_id_16>",
|
| 20 |
+
"<extra_id_17>",
|
| 21 |
+
"<extra_id_18>",
|
| 22 |
+
"<extra_id_19>",
|
| 23 |
+
"<extra_id_20>",
|
| 24 |
+
"<extra_id_21>",
|
| 25 |
+
"<extra_id_22>",
|
| 26 |
+
"<extra_id_23>",
|
| 27 |
+
"<extra_id_24>",
|
| 28 |
+
"<extra_id_25>",
|
| 29 |
+
"<extra_id_26>",
|
| 30 |
+
"<extra_id_27>",
|
| 31 |
+
"<extra_id_28>",
|
| 32 |
+
"<extra_id_29>",
|
| 33 |
+
"<extra_id_30>",
|
| 34 |
+
"<extra_id_31>",
|
| 35 |
+
"<extra_id_32>",
|
| 36 |
+
"<extra_id_33>",
|
| 37 |
+
"<extra_id_34>",
|
| 38 |
+
"<extra_id_35>",
|
| 39 |
+
"<extra_id_36>",
|
| 40 |
+
"<extra_id_37>",
|
| 41 |
+
"<extra_id_38>",
|
| 42 |
+
"<extra_id_39>",
|
| 43 |
+
"<extra_id_40>",
|
| 44 |
+
"<extra_id_41>",
|
| 45 |
+
"<extra_id_42>",
|
| 46 |
+
"<extra_id_43>",
|
| 47 |
+
"<extra_id_44>",
|
| 48 |
+
"<extra_id_45>",
|
| 49 |
+
"<extra_id_46>",
|
| 50 |
+
"<extra_id_47>",
|
| 51 |
+
"<extra_id_48>",
|
| 52 |
+
"<extra_id_49>",
|
| 53 |
+
"<extra_id_50>",
|
| 54 |
+
"<extra_id_51>",
|
| 55 |
+
"<extra_id_52>",
|
| 56 |
+
"<extra_id_53>",
|
| 57 |
+
"<extra_id_54>",
|
| 58 |
+
"<extra_id_55>",
|
| 59 |
+
"<extra_id_56>",
|
| 60 |
+
"<extra_id_57>",
|
| 61 |
+
"<extra_id_58>",
|
| 62 |
+
"<extra_id_59>",
|
| 63 |
+
"<extra_id_60>",
|
| 64 |
+
"<extra_id_61>",
|
| 65 |
+
"<extra_id_62>",
|
| 66 |
+
"<extra_id_63>",
|
| 67 |
+
"<extra_id_64>",
|
| 68 |
+
"<extra_id_65>",
|
| 69 |
+
"<extra_id_66>",
|
| 70 |
+
"<extra_id_67>",
|
| 71 |
+
"<extra_id_68>",
|
| 72 |
+
"<extra_id_69>",
|
| 73 |
+
"<extra_id_70>",
|
| 74 |
+
"<extra_id_71>",
|
| 75 |
+
"<extra_id_72>",
|
| 76 |
+
"<extra_id_73>",
|
| 77 |
+
"<extra_id_74>",
|
| 78 |
+
"<extra_id_75>",
|
| 79 |
+
"<extra_id_76>",
|
| 80 |
+
"<extra_id_77>",
|
| 81 |
+
"<extra_id_78>",
|
| 82 |
+
"<extra_id_79>",
|
| 83 |
+
"<extra_id_80>",
|
| 84 |
+
"<extra_id_81>",
|
| 85 |
+
"<extra_id_82>",
|
| 86 |
+
"<extra_id_83>",
|
| 87 |
+
"<extra_id_84>",
|
| 88 |
+
"<extra_id_85>",
|
| 89 |
+
"<extra_id_86>",
|
| 90 |
+
"<extra_id_87>",
|
| 91 |
+
"<extra_id_88>",
|
| 92 |
+
"<extra_id_89>",
|
| 93 |
+
"<extra_id_90>",
|
| 94 |
+
"<extra_id_91>",
|
| 95 |
+
"<extra_id_92>",
|
| 96 |
+
"<extra_id_93>",
|
| 97 |
+
"<extra_id_94>",
|
| 98 |
+
"<extra_id_95>",
|
| 99 |
+
"<extra_id_96>",
|
| 100 |
+
"<extra_id_97>",
|
| 101 |
+
"<extra_id_98>",
|
| 102 |
+
"<extra_id_99>"
|
| 103 |
+
],
|
| 104 |
+
"eos_token": {
|
| 105 |
+
"content": "</s>",
|
| 106 |
+
"lstrip": false,
|
| 107 |
+
"normalized": false,
|
| 108 |
+
"rstrip": false,
|
| 109 |
+
"single_word": false
|
| 110 |
+
},
|
| 111 |
+
"pad_token": {
|
| 112 |
+
"content": "<pad>",
|
| 113 |
+
"lstrip": false,
|
| 114 |
+
"normalized": false,
|
| 115 |
+
"rstrip": false,
|
| 116 |
+
"single_word": false
|
| 117 |
+
},
|
| 118 |
+
"unk_token": {
|
| 119 |
+
"content": "<unk>",
|
| 120 |
+
"lstrip": false,
|
| 121 |
+
"normalized": false,
|
| 122 |
+
"rstrip": false,
|
| 123 |
+
"single_word": false
|
| 124 |
+
}
|
| 125 |
+
}
|
models/chatbot_t5/spiece.model
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d60acb128cf7b7f2536e8f38a5b18a05535c9e14c7a355904270e15b0945ea86
|
| 3 |
+
size 791656
|
models/chatbot_t5/tokenizer.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
models/chatbot_t5/tokenizer_config.json
ADDED
|
@@ -0,0 +1,939 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"add_prefix_space": null,
|
| 3 |
+
"added_tokens_decoder": {
|
| 4 |
+
"0": {
|
| 5 |
+
"content": "<pad>",
|
| 6 |
+
"lstrip": false,
|
| 7 |
+
"normalized": false,
|
| 8 |
+
"rstrip": false,
|
| 9 |
+
"single_word": false,
|
| 10 |
+
"special": true
|
| 11 |
+
},
|
| 12 |
+
"1": {
|
| 13 |
+
"content": "</s>",
|
| 14 |
+
"lstrip": false,
|
| 15 |
+
"normalized": false,
|
| 16 |
+
"rstrip": false,
|
| 17 |
+
"single_word": false,
|
| 18 |
+
"special": true
|
| 19 |
+
},
|
| 20 |
+
"2": {
|
| 21 |
+
"content": "<unk>",
|
| 22 |
+
"lstrip": false,
|
| 23 |
+
"normalized": false,
|
| 24 |
+
"rstrip": false,
|
| 25 |
+
"single_word": false,
|
| 26 |
+
"special": true
|
| 27 |
+
},
|
| 28 |
+
"32000": {
|
| 29 |
+
"content": "<extra_id_99>",
|
| 30 |
+
"lstrip": false,
|
| 31 |
+
"normalized": false,
|
| 32 |
+
"rstrip": false,
|
| 33 |
+
"single_word": false,
|
| 34 |
+
"special": true
|
| 35 |
+
},
|
| 36 |
+
"32001": {
|
| 37 |
+
"content": "<extra_id_98>",
|
| 38 |
+
"lstrip": false,
|
| 39 |
+
"normalized": false,
|
| 40 |
+
"rstrip": false,
|
| 41 |
+
"single_word": false,
|
| 42 |
+
"special": true
|
| 43 |
+
},
|
| 44 |
+
"32002": {
|
| 45 |
+
"content": "<extra_id_97>",
|
| 46 |
+
"lstrip": false,
|
| 47 |
+
"normalized": false,
|
| 48 |
+
"rstrip": false,
|
| 49 |
+
"single_word": false,
|
| 50 |
+
"special": true
|
| 51 |
+
},
|
| 52 |
+
"32003": {
|
| 53 |
+
"content": "<extra_id_96>",
|
| 54 |
+
"lstrip": false,
|
| 55 |
+
"normalized": false,
|
| 56 |
+
"rstrip": false,
|
| 57 |
+
"single_word": false,
|
| 58 |
+
"special": true
|
| 59 |
+
},
|
| 60 |
+
"32004": {
|
| 61 |
+
"content": "<extra_id_95>",
|
| 62 |
+
"lstrip": false,
|
| 63 |
+
"normalized": false,
|
| 64 |
+
"rstrip": false,
|
| 65 |
+
"single_word": false,
|
| 66 |
+
"special": true
|
| 67 |
+
},
|
| 68 |
+
"32005": {
|
| 69 |
+
"content": "<extra_id_94>",
|
| 70 |
+
"lstrip": false,
|
| 71 |
+
"normalized": false,
|
| 72 |
+
"rstrip": false,
|
| 73 |
+
"single_word": false,
|
| 74 |
+
"special": true
|
| 75 |
+
},
|
| 76 |
+
"32006": {
|
| 77 |
+
"content": "<extra_id_93>",
|
| 78 |
+
"lstrip": false,
|
| 79 |
+
"normalized": false,
|
| 80 |
+
"rstrip": false,
|
| 81 |
+
"single_word": false,
|
| 82 |
+
"special": true
|
| 83 |
+
},
|
| 84 |
+
"32007": {
|
| 85 |
+
"content": "<extra_id_92>",
|
| 86 |
+
"lstrip": false,
|
| 87 |
+
"normalized": false,
|
| 88 |
+
"rstrip": false,
|
| 89 |
+
"single_word": false,
|
| 90 |
+
"special": true
|
| 91 |
+
},
|
| 92 |
+
"32008": {
|
| 93 |
+
"content": "<extra_id_91>",
|
| 94 |
+
"lstrip": false,
|
| 95 |
+
"normalized": false,
|
| 96 |
+
"rstrip": false,
|
| 97 |
+
"single_word": false,
|
| 98 |
+
"special": true
|
| 99 |
+
},
|
| 100 |
+
"32009": {
|
| 101 |
+
"content": "<extra_id_90>",
|
| 102 |
+
"lstrip": false,
|
| 103 |
+
"normalized": false,
|
| 104 |
+
"rstrip": false,
|
| 105 |
+
"single_word": false,
|
| 106 |
+
"special": true
|
| 107 |
+
},
|
| 108 |
+
"32010": {
|
| 109 |
+
"content": "<extra_id_89>",
|
| 110 |
+
"lstrip": false,
|
| 111 |
+
"normalized": false,
|
| 112 |
+
"rstrip": false,
|
| 113 |
+
"single_word": false,
|
| 114 |
+
"special": true
|
| 115 |
+
},
|
| 116 |
+
"32011": {
|
| 117 |
+
"content": "<extra_id_88>",
|
| 118 |
+
"lstrip": false,
|
| 119 |
+
"normalized": false,
|
| 120 |
+
"rstrip": false,
|
| 121 |
+
"single_word": false,
|
| 122 |
+
"special": true
|
| 123 |
+
},
|
| 124 |
+
"32012": {
|
| 125 |
+
"content": "<extra_id_87>",
|
| 126 |
+
"lstrip": false,
|
| 127 |
+
"normalized": false,
|
| 128 |
+
"rstrip": false,
|
| 129 |
+
"single_word": false,
|
| 130 |
+
"special": true
|
| 131 |
+
},
|
| 132 |
+
"32013": {
|
| 133 |
+
"content": "<extra_id_86>",
|
| 134 |
+
"lstrip": false,
|
| 135 |
+
"normalized": false,
|
| 136 |
+
"rstrip": false,
|
| 137 |
+
"single_word": false,
|
| 138 |
+
"special": true
|
| 139 |
+
},
|
| 140 |
+
"32014": {
|
| 141 |
+
"content": "<extra_id_85>",
|
| 142 |
+
"lstrip": false,
|
| 143 |
+
"normalized": false,
|
| 144 |
+
"rstrip": false,
|
| 145 |
+
"single_word": false,
|
| 146 |
+
"special": true
|
| 147 |
+
},
|
| 148 |
+
"32015": {
|
| 149 |
+
"content": "<extra_id_84>",
|
| 150 |
+
"lstrip": false,
|
| 151 |
+
"normalized": false,
|
| 152 |
+
"rstrip": false,
|
| 153 |
+
"single_word": false,
|
| 154 |
+
"special": true
|
| 155 |
+
},
|
| 156 |
+
"32016": {
|
| 157 |
+
"content": "<extra_id_83>",
|
| 158 |
+
"lstrip": false,
|
| 159 |
+
"normalized": false,
|
| 160 |
+
"rstrip": false,
|
| 161 |
+
"single_word": false,
|
| 162 |
+
"special": true
|
| 163 |
+
},
|
| 164 |
+
"32017": {
|
| 165 |
+
"content": "<extra_id_82>",
|
| 166 |
+
"lstrip": false,
|
| 167 |
+
"normalized": false,
|
| 168 |
+
"rstrip": false,
|
| 169 |
+
"single_word": false,
|
| 170 |
+
"special": true
|
| 171 |
+
},
|
| 172 |
+
"32018": {
|
| 173 |
+
"content": "<extra_id_81>",
|
| 174 |
+
"lstrip": false,
|
| 175 |
+
"normalized": false,
|
| 176 |
+
"rstrip": false,
|
| 177 |
+
"single_word": false,
|
| 178 |
+
"special": true
|
| 179 |
+
},
|
| 180 |
+
"32019": {
|
| 181 |
+
"content": "<extra_id_80>",
|
| 182 |
+
"lstrip": false,
|
| 183 |
+
"normalized": false,
|
| 184 |
+
"rstrip": false,
|
| 185 |
+
"single_word": false,
|
| 186 |
+
"special": true
|
| 187 |
+
},
|
| 188 |
+
"32020": {
|
| 189 |
+
"content": "<extra_id_79>",
|
| 190 |
+
"lstrip": false,
|
| 191 |
+
"normalized": false,
|
| 192 |
+
"rstrip": false,
|
| 193 |
+
"single_word": false,
|
| 194 |
+
"special": true
|
| 195 |
+
},
|
| 196 |
+
"32021": {
|
| 197 |
+
"content": "<extra_id_78>",
|
| 198 |
+
"lstrip": false,
|
| 199 |
+
"normalized": false,
|
| 200 |
+
"rstrip": false,
|
| 201 |
+
"single_word": false,
|
| 202 |
+
"special": true
|
| 203 |
+
},
|
| 204 |
+
"32022": {
|
| 205 |
+
"content": "<extra_id_77>",
|
| 206 |
+
"lstrip": false,
|
| 207 |
+
"normalized": false,
|
| 208 |
+
"rstrip": false,
|
| 209 |
+
"single_word": false,
|
| 210 |
+
"special": true
|
| 211 |
+
},
|
| 212 |
+
"32023": {
|
| 213 |
+
"content": "<extra_id_76>",
|
| 214 |
+
"lstrip": false,
|
| 215 |
+
"normalized": false,
|
| 216 |
+
"rstrip": false,
|
| 217 |
+
"single_word": false,
|
| 218 |
+
"special": true
|
| 219 |
+
},
|
| 220 |
+
"32024": {
|
| 221 |
+
"content": "<extra_id_75>",
|
| 222 |
+
"lstrip": false,
|
| 223 |
+
"normalized": false,
|
| 224 |
+
"rstrip": false,
|
| 225 |
+
"single_word": false,
|
| 226 |
+
"special": true
|
| 227 |
+
},
|
| 228 |
+
"32025": {
|
| 229 |
+
"content": "<extra_id_74>",
|
| 230 |
+
"lstrip": false,
|
| 231 |
+
"normalized": false,
|
| 232 |
+
"rstrip": false,
|
| 233 |
+
"single_word": false,
|
| 234 |
+
"special": true
|
| 235 |
+
},
|
| 236 |
+
"32026": {
|
| 237 |
+
"content": "<extra_id_73>",
|
| 238 |
+
"lstrip": false,
|
| 239 |
+
"normalized": false,
|
| 240 |
+
"rstrip": false,
|
| 241 |
+
"single_word": false,
|
| 242 |
+
"special": true
|
| 243 |
+
},
|
| 244 |
+
"32027": {
|
| 245 |
+
"content": "<extra_id_72>",
|
| 246 |
+
"lstrip": false,
|
| 247 |
+
"normalized": false,
|
| 248 |
+
"rstrip": false,
|
| 249 |
+
"single_word": false,
|
| 250 |
+
"special": true
|
| 251 |
+
},
|
| 252 |
+
"32028": {
|
| 253 |
+
"content": "<extra_id_71>",
|
| 254 |
+
"lstrip": false,
|
| 255 |
+
"normalized": false,
|
| 256 |
+
"rstrip": false,
|
| 257 |
+
"single_word": false,
|
| 258 |
+
"special": true
|
| 259 |
+
},
|
| 260 |
+
"32029": {
|
| 261 |
+
"content": "<extra_id_70>",
|
| 262 |
+
"lstrip": false,
|
| 263 |
+
"normalized": false,
|
| 264 |
+
"rstrip": false,
|
| 265 |
+
"single_word": false,
|
| 266 |
+
"special": true
|
| 267 |
+
},
|
| 268 |
+
"32030": {
|
| 269 |
+
"content": "<extra_id_69>",
|
| 270 |
+
"lstrip": false,
|
| 271 |
+
"normalized": false,
|
| 272 |
+
"rstrip": false,
|
| 273 |
+
"single_word": false,
|
| 274 |
+
"special": true
|
| 275 |
+
},
|
| 276 |
+
"32031": {
|
| 277 |
+
"content": "<extra_id_68>",
|
| 278 |
+
"lstrip": false,
|
| 279 |
+
"normalized": false,
|
| 280 |
+
"rstrip": false,
|
| 281 |
+
"single_word": false,
|
| 282 |
+
"special": true
|
| 283 |
+
},
|
| 284 |
+
"32032": {
|
| 285 |
+
"content": "<extra_id_67>",
|
| 286 |
+
"lstrip": false,
|
| 287 |
+
"normalized": false,
|
| 288 |
+
"rstrip": false,
|
| 289 |
+
"single_word": false,
|
| 290 |
+
"special": true
|
| 291 |
+
},
|
| 292 |
+
"32033": {
|
| 293 |
+
"content": "<extra_id_66>",
|
| 294 |
+
"lstrip": false,
|
| 295 |
+
"normalized": false,
|
| 296 |
+
"rstrip": false,
|
| 297 |
+
"single_word": false,
|
| 298 |
+
"special": true
|
| 299 |
+
},
|
| 300 |
+
"32034": {
|
| 301 |
+
"content": "<extra_id_65>",
|
| 302 |
+
"lstrip": false,
|
| 303 |
+
"normalized": false,
|
| 304 |
+
"rstrip": false,
|
| 305 |
+
"single_word": false,
|
| 306 |
+
"special": true
|
| 307 |
+
},
|
| 308 |
+
"32035": {
|
| 309 |
+
"content": "<extra_id_64>",
|
| 310 |
+
"lstrip": false,
|
| 311 |
+
"normalized": false,
|
| 312 |
+
"rstrip": false,
|
| 313 |
+
"single_word": false,
|
| 314 |
+
"special": true
|
| 315 |
+
},
|
| 316 |
+
"32036": {
|
| 317 |
+
"content": "<extra_id_63>",
|
| 318 |
+
"lstrip": false,
|
| 319 |
+
"normalized": false,
|
| 320 |
+
"rstrip": false,
|
| 321 |
+
"single_word": false,
|
| 322 |
+
"special": true
|
| 323 |
+
},
|
| 324 |
+
"32037": {
|
| 325 |
+
"content": "<extra_id_62>",
|
| 326 |
+
"lstrip": false,
|
| 327 |
+
"normalized": false,
|
| 328 |
+
"rstrip": false,
|
| 329 |
+
"single_word": false,
|
| 330 |
+
"special": true
|
| 331 |
+
},
|
| 332 |
+
"32038": {
|
| 333 |
+
"content": "<extra_id_61>",
|
| 334 |
+
"lstrip": false,
|
| 335 |
+
"normalized": false,
|
| 336 |
+
"rstrip": false,
|
| 337 |
+
"single_word": false,
|
| 338 |
+
"special": true
|
| 339 |
+
},
|
| 340 |
+
"32039": {
|
| 341 |
+
"content": "<extra_id_60>",
|
| 342 |
+
"lstrip": false,
|
| 343 |
+
"normalized": false,
|
| 344 |
+
"rstrip": false,
|
| 345 |
+
"single_word": false,
|
| 346 |
+
"special": true
|
| 347 |
+
},
|
| 348 |
+
"32040": {
|
| 349 |
+
"content": "<extra_id_59>",
|
| 350 |
+
"lstrip": false,
|
| 351 |
+
"normalized": false,
|
| 352 |
+
"rstrip": false,
|
| 353 |
+
"single_word": false,
|
| 354 |
+
"special": true
|
| 355 |
+
},
|
| 356 |
+
"32041": {
|
| 357 |
+
"content": "<extra_id_58>",
|
| 358 |
+
"lstrip": false,
|
| 359 |
+
"normalized": false,
|
| 360 |
+
"rstrip": false,
|
| 361 |
+
"single_word": false,
|
| 362 |
+
"special": true
|
| 363 |
+
},
|
| 364 |
+
"32042": {
|
| 365 |
+
"content": "<extra_id_57>",
|
| 366 |
+
"lstrip": false,
|
| 367 |
+
"normalized": false,
|
| 368 |
+
"rstrip": false,
|
| 369 |
+
"single_word": false,
|
| 370 |
+
"special": true
|
| 371 |
+
},
|
| 372 |
+
"32043": {
|
| 373 |
+
"content": "<extra_id_56>",
|
| 374 |
+
"lstrip": false,
|
| 375 |
+
"normalized": false,
|
| 376 |
+
"rstrip": false,
|
| 377 |
+
"single_word": false,
|
| 378 |
+
"special": true
|
| 379 |
+
},
|
| 380 |
+
"32044": {
|
| 381 |
+
"content": "<extra_id_55>",
|
| 382 |
+
"lstrip": false,
|
| 383 |
+
"normalized": false,
|
| 384 |
+
"rstrip": false,
|
| 385 |
+
"single_word": false,
|
| 386 |
+
"special": true
|
| 387 |
+
},
|
| 388 |
+
"32045": {
|
| 389 |
+
"content": "<extra_id_54>",
|
| 390 |
+
"lstrip": false,
|
| 391 |
+
"normalized": false,
|
| 392 |
+
"rstrip": false,
|
| 393 |
+
"single_word": false,
|
| 394 |
+
"special": true
|
| 395 |
+
},
|
| 396 |
+
"32046": {
|
| 397 |
+
"content": "<extra_id_53>",
|
| 398 |
+
"lstrip": false,
|
| 399 |
+
"normalized": false,
|
| 400 |
+
"rstrip": false,
|
| 401 |
+
"single_word": false,
|
| 402 |
+
"special": true
|
| 403 |
+
},
|
| 404 |
+
"32047": {
|
| 405 |
+
"content": "<extra_id_52>",
|
| 406 |
+
"lstrip": false,
|
| 407 |
+
"normalized": false,
|
| 408 |
+
"rstrip": false,
|
| 409 |
+
"single_word": false,
|
| 410 |
+
"special": true
|
| 411 |
+
},
|
| 412 |
+
"32048": {
|
| 413 |
+
"content": "<extra_id_51>",
|
| 414 |
+
"lstrip": false,
|
| 415 |
+
"normalized": false,
|
| 416 |
+
"rstrip": false,
|
| 417 |
+
"single_word": false,
|
| 418 |
+
"special": true
|
| 419 |
+
},
|
| 420 |
+
"32049": {
|
| 421 |
+
"content": "<extra_id_50>",
|
| 422 |
+
"lstrip": false,
|
| 423 |
+
"normalized": false,
|
| 424 |
+
"rstrip": false,
|
| 425 |
+
"single_word": false,
|
| 426 |
+
"special": true
|
| 427 |
+
},
|
| 428 |
+
"32050": {
|
| 429 |
+
"content": "<extra_id_49>",
|
| 430 |
+
"lstrip": false,
|
| 431 |
+
"normalized": false,
|
| 432 |
+
"rstrip": false,
|
| 433 |
+
"single_word": false,
|
| 434 |
+
"special": true
|
| 435 |
+
},
|
| 436 |
+
"32051": {
|
| 437 |
+
"content": "<extra_id_48>",
|
| 438 |
+
"lstrip": false,
|
| 439 |
+
"normalized": false,
|
| 440 |
+
"rstrip": false,
|
| 441 |
+
"single_word": false,
|
| 442 |
+
"special": true
|
| 443 |
+
},
|
| 444 |
+
"32052": {
|
| 445 |
+
"content": "<extra_id_47>",
|
| 446 |
+
"lstrip": false,
|
| 447 |
+
"normalized": false,
|
| 448 |
+
"rstrip": false,
|
| 449 |
+
"single_word": false,
|
| 450 |
+
"special": true
|
| 451 |
+
},
|
| 452 |
+
"32053": {
|
| 453 |
+
"content": "<extra_id_46>",
|
| 454 |
+
"lstrip": false,
|
| 455 |
+
"normalized": false,
|
| 456 |
+
"rstrip": false,
|
| 457 |
+
"single_word": false,
|
| 458 |
+
"special": true
|
| 459 |
+
},
|
| 460 |
+
"32054": {
|
| 461 |
+
"content": "<extra_id_45>",
|
| 462 |
+
"lstrip": false,
|
| 463 |
+
"normalized": false,
|
| 464 |
+
"rstrip": false,
|
| 465 |
+
"single_word": false,
|
| 466 |
+
"special": true
|
| 467 |
+
},
|
| 468 |
+
"32055": {
|
| 469 |
+
"content": "<extra_id_44>",
|
| 470 |
+
"lstrip": false,
|
| 471 |
+
"normalized": false,
|
| 472 |
+
"rstrip": false,
|
| 473 |
+
"single_word": false,
|
| 474 |
+
"special": true
|
| 475 |
+
},
|
| 476 |
+
"32056": {
|
| 477 |
+
"content": "<extra_id_43>",
|
| 478 |
+
"lstrip": false,
|
| 479 |
+
"normalized": false,
|
| 480 |
+
"rstrip": false,
|
| 481 |
+
"single_word": false,
|
| 482 |
+
"special": true
|
| 483 |
+
},
|
| 484 |
+
"32057": {
|
| 485 |
+
"content": "<extra_id_42>",
|
| 486 |
+
"lstrip": false,
|
| 487 |
+
"normalized": false,
|
| 488 |
+
"rstrip": false,
|
| 489 |
+
"single_word": false,
|
| 490 |
+
"special": true
|
| 491 |
+
},
|
| 492 |
+
"32058": {
|
| 493 |
+
"content": "<extra_id_41>",
|
| 494 |
+
"lstrip": false,
|
| 495 |
+
"normalized": false,
|
| 496 |
+
"rstrip": false,
|
| 497 |
+
"single_word": false,
|
| 498 |
+
"special": true
|
| 499 |
+
},
|
| 500 |
+
"32059": {
|
| 501 |
+
"content": "<extra_id_40>",
|
| 502 |
+
"lstrip": false,
|
| 503 |
+
"normalized": false,
|
| 504 |
+
"rstrip": false,
|
| 505 |
+
"single_word": false,
|
| 506 |
+
"special": true
|
| 507 |
+
},
|
| 508 |
+
"32060": {
|
| 509 |
+
"content": "<extra_id_39>",
|
| 510 |
+
"lstrip": false,
|
| 511 |
+
"normalized": false,
|
| 512 |
+
"rstrip": false,
|
| 513 |
+
"single_word": false,
|
| 514 |
+
"special": true
|
| 515 |
+
},
|
| 516 |
+
"32061": {
|
| 517 |
+
"content": "<extra_id_38>",
|
| 518 |
+
"lstrip": false,
|
| 519 |
+
"normalized": false,
|
| 520 |
+
"rstrip": false,
|
| 521 |
+
"single_word": false,
|
| 522 |
+
"special": true
|
| 523 |
+
},
|
| 524 |
+
"32062": {
|
| 525 |
+
"content": "<extra_id_37>",
|
| 526 |
+
"lstrip": false,
|
| 527 |
+
"normalized": false,
|
| 528 |
+
"rstrip": false,
|
| 529 |
+
"single_word": false,
|
| 530 |
+
"special": true
|
| 531 |
+
},
|
| 532 |
+
"32063": {
|
| 533 |
+
"content": "<extra_id_36>",
|
| 534 |
+
"lstrip": false,
|
| 535 |
+
"normalized": false,
|
| 536 |
+
"rstrip": false,
|
| 537 |
+
"single_word": false,
|
| 538 |
+
"special": true
|
| 539 |
+
},
|
| 540 |
+
"32064": {
|
| 541 |
+
"content": "<extra_id_35>",
|
| 542 |
+
"lstrip": false,
|
| 543 |
+
"normalized": false,
|
| 544 |
+
"rstrip": false,
|
| 545 |
+
"single_word": false,
|
| 546 |
+
"special": true
|
| 547 |
+
},
|
| 548 |
+
"32065": {
|
| 549 |
+
"content": "<extra_id_34>",
|
| 550 |
+
"lstrip": false,
|
| 551 |
+
"normalized": false,
|
| 552 |
+
"rstrip": false,
|
| 553 |
+
"single_word": false,
|
| 554 |
+
"special": true
|
| 555 |
+
},
|
| 556 |
+
"32066": {
|
| 557 |
+
"content": "<extra_id_33>",
|
| 558 |
+
"lstrip": false,
|
| 559 |
+
"normalized": false,
|
| 560 |
+
"rstrip": false,
|
| 561 |
+
"single_word": false,
|
| 562 |
+
"special": true
|
| 563 |
+
},
|
| 564 |
+
"32067": {
|
| 565 |
+
"content": "<extra_id_32>",
|
| 566 |
+
"lstrip": false,
|
| 567 |
+
"normalized": false,
|
| 568 |
+
"rstrip": false,
|
| 569 |
+
"single_word": false,
|
| 570 |
+
"special": true
|
| 571 |
+
},
|
| 572 |
+
"32068": {
|
| 573 |
+
"content": "<extra_id_31>",
|
| 574 |
+
"lstrip": false,
|
| 575 |
+
"normalized": false,
|
| 576 |
+
"rstrip": false,
|
| 577 |
+
"single_word": false,
|
| 578 |
+
"special": true
|
| 579 |
+
},
|
| 580 |
+
"32069": {
|
| 581 |
+
"content": "<extra_id_30>",
|
| 582 |
+
"lstrip": false,
|
| 583 |
+
"normalized": false,
|
| 584 |
+
"rstrip": false,
|
| 585 |
+
"single_word": false,
|
| 586 |
+
"special": true
|
| 587 |
+
},
|
| 588 |
+
"32070": {
|
| 589 |
+
"content": "<extra_id_29>",
|
| 590 |
+
"lstrip": false,
|
| 591 |
+
"normalized": false,
|
| 592 |
+
"rstrip": false,
|
| 593 |
+
"single_word": false,
|
| 594 |
+
"special": true
|
| 595 |
+
},
|
| 596 |
+
"32071": {
|
| 597 |
+
"content": "<extra_id_28>",
|
| 598 |
+
"lstrip": false,
|
| 599 |
+
"normalized": false,
|
| 600 |
+
"rstrip": false,
|
| 601 |
+
"single_word": false,
|
| 602 |
+
"special": true
|
| 603 |
+
},
|
| 604 |
+
"32072": {
|
| 605 |
+
"content": "<extra_id_27>",
|
| 606 |
+
"lstrip": false,
|
| 607 |
+
"normalized": false,
|
| 608 |
+
"rstrip": false,
|
| 609 |
+
"single_word": false,
|
| 610 |
+
"special": true
|
| 611 |
+
},
|
| 612 |
+
"32073": {
|
| 613 |
+
"content": "<extra_id_26>",
|
| 614 |
+
"lstrip": false,
|
| 615 |
+
"normalized": false,
|
| 616 |
+
"rstrip": false,
|
| 617 |
+
"single_word": false,
|
| 618 |
+
"special": true
|
| 619 |
+
},
|
| 620 |
+
"32074": {
|
| 621 |
+
"content": "<extra_id_25>",
|
| 622 |
+
"lstrip": false,
|
| 623 |
+
"normalized": false,
|
| 624 |
+
"rstrip": false,
|
| 625 |
+
"single_word": false,
|
| 626 |
+
"special": true
|
| 627 |
+
},
|
| 628 |
+
"32075": {
|
| 629 |
+
"content": "<extra_id_24>",
|
| 630 |
+
"lstrip": false,
|
| 631 |
+
"normalized": false,
|
| 632 |
+
"rstrip": false,
|
| 633 |
+
"single_word": false,
|
| 634 |
+
"special": true
|
| 635 |
+
},
|
| 636 |
+
"32076": {
|
| 637 |
+
"content": "<extra_id_23>",
|
| 638 |
+
"lstrip": false,
|
| 639 |
+
"normalized": false,
|
| 640 |
+
"rstrip": false,
|
| 641 |
+
"single_word": false,
|
| 642 |
+
"special": true
|
| 643 |
+
},
|
| 644 |
+
"32077": {
|
| 645 |
+
"content": "<extra_id_22>",
|
| 646 |
+
"lstrip": false,
|
| 647 |
+
"normalized": false,
|
| 648 |
+
"rstrip": false,
|
| 649 |
+
"single_word": false,
|
| 650 |
+
"special": true
|
| 651 |
+
},
|
| 652 |
+
"32078": {
|
| 653 |
+
"content": "<extra_id_21>",
|
| 654 |
+
"lstrip": false,
|
| 655 |
+
"normalized": false,
|
| 656 |
+
"rstrip": false,
|
| 657 |
+
"single_word": false,
|
| 658 |
+
"special": true
|
| 659 |
+
},
|
| 660 |
+
"32079": {
|
| 661 |
+
"content": "<extra_id_20>",
|
| 662 |
+
"lstrip": false,
|
| 663 |
+
"normalized": false,
|
| 664 |
+
"rstrip": false,
|
| 665 |
+
"single_word": false,
|
| 666 |
+
"special": true
|
| 667 |
+
},
|
| 668 |
+
"32080": {
|
| 669 |
+
"content": "<extra_id_19>",
|
| 670 |
+
"lstrip": false,
|
| 671 |
+
"normalized": false,
|
| 672 |
+
"rstrip": false,
|
| 673 |
+
"single_word": false,
|
| 674 |
+
"special": true
|
| 675 |
+
},
|
| 676 |
+
"32081": {
|
| 677 |
+
"content": "<extra_id_18>",
|
| 678 |
+
"lstrip": false,
|
| 679 |
+
"normalized": false,
|
| 680 |
+
"rstrip": false,
|
| 681 |
+
"single_word": false,
|
| 682 |
+
"special": true
|
| 683 |
+
},
|
| 684 |
+
"32082": {
|
| 685 |
+
"content": "<extra_id_17>",
|
| 686 |
+
"lstrip": false,
|
| 687 |
+
"normalized": false,
|
| 688 |
+
"rstrip": false,
|
| 689 |
+
"single_word": false,
|
| 690 |
+
"special": true
|
| 691 |
+
},
|
| 692 |
+
"32083": {
|
| 693 |
+
"content": "<extra_id_16>",
|
| 694 |
+
"lstrip": false,
|
| 695 |
+
"normalized": false,
|
| 696 |
+
"rstrip": false,
|
| 697 |
+
"single_word": false,
|
| 698 |
+
"special": true
|
| 699 |
+
},
|
| 700 |
+
"32084": {
|
| 701 |
+
"content": "<extra_id_15>",
|
| 702 |
+
"lstrip": false,
|
| 703 |
+
"normalized": false,
|
| 704 |
+
"rstrip": false,
|
| 705 |
+
"single_word": false,
|
| 706 |
+
"special": true
|
| 707 |
+
},
|
| 708 |
+
"32085": {
|
| 709 |
+
"content": "<extra_id_14>",
|
| 710 |
+
"lstrip": false,
|
| 711 |
+
"normalized": false,
|
| 712 |
+
"rstrip": false,
|
| 713 |
+
"single_word": false,
|
| 714 |
+
"special": true
|
| 715 |
+
},
|
| 716 |
+
"32086": {
|
| 717 |
+
"content": "<extra_id_13>",
|
| 718 |
+
"lstrip": false,
|
| 719 |
+
"normalized": false,
|
| 720 |
+
"rstrip": false,
|
| 721 |
+
"single_word": false,
|
| 722 |
+
"special": true
|
| 723 |
+
},
|
| 724 |
+
"32087": {
|
| 725 |
+
"content": "<extra_id_12>",
|
| 726 |
+
"lstrip": false,
|
| 727 |
+
"normalized": false,
|
| 728 |
+
"rstrip": false,
|
| 729 |
+
"single_word": false,
|
| 730 |
+
"special": true
|
| 731 |
+
},
|
| 732 |
+
"32088": {
|
| 733 |
+
"content": "<extra_id_11>",
|
| 734 |
+
"lstrip": false,
|
| 735 |
+
"normalized": false,
|
| 736 |
+
"rstrip": false,
|
| 737 |
+
"single_word": false,
|
| 738 |
+
"special": true
|
| 739 |
+
},
|
| 740 |
+
"32089": {
|
| 741 |
+
"content": "<extra_id_10>",
|
| 742 |
+
"lstrip": false,
|
| 743 |
+
"normalized": false,
|
| 744 |
+
"rstrip": false,
|
| 745 |
+
"single_word": false,
|
| 746 |
+
"special": true
|
| 747 |
+
},
|
| 748 |
+
"32090": {
|
| 749 |
+
"content": "<extra_id_9>",
|
| 750 |
+
"lstrip": false,
|
| 751 |
+
"normalized": false,
|
| 752 |
+
"rstrip": false,
|
| 753 |
+
"single_word": false,
|
| 754 |
+
"special": true
|
| 755 |
+
},
|
| 756 |
+
"32091": {
|
| 757 |
+
"content": "<extra_id_8>",
|
| 758 |
+
"lstrip": false,
|
| 759 |
+
"normalized": false,
|
| 760 |
+
"rstrip": false,
|
| 761 |
+
"single_word": false,
|
| 762 |
+
"special": true
|
| 763 |
+
},
|
| 764 |
+
"32092": {
|
| 765 |
+
"content": "<extra_id_7>",
|
| 766 |
+
"lstrip": false,
|
| 767 |
+
"normalized": false,
|
| 768 |
+
"rstrip": false,
|
| 769 |
+
"single_word": false,
|
| 770 |
+
"special": true
|
| 771 |
+
},
|
| 772 |
+
"32093": {
|
| 773 |
+
"content": "<extra_id_6>",
|
| 774 |
+
"lstrip": false,
|
| 775 |
+
"normalized": false,
|
| 776 |
+
"rstrip": false,
|
| 777 |
+
"single_word": false,
|
| 778 |
+
"special": true
|
| 779 |
+
},
|
| 780 |
+
"32094": {
|
| 781 |
+
"content": "<extra_id_5>",
|
| 782 |
+
"lstrip": false,
|
| 783 |
+
"normalized": false,
|
| 784 |
+
"rstrip": false,
|
| 785 |
+
"single_word": false,
|
| 786 |
+
"special": true
|
| 787 |
+
},
|
| 788 |
+
"32095": {
|
| 789 |
+
"content": "<extra_id_4>",
|
| 790 |
+
"lstrip": false,
|
| 791 |
+
"normalized": false,
|
| 792 |
+
"rstrip": false,
|
| 793 |
+
"single_word": false,
|
| 794 |
+
"special": true
|
| 795 |
+
},
|
| 796 |
+
"32096": {
|
| 797 |
+
"content": "<extra_id_3>",
|
| 798 |
+
"lstrip": false,
|
| 799 |
+
"normalized": false,
|
| 800 |
+
"rstrip": false,
|
| 801 |
+
"single_word": false,
|
| 802 |
+
"special": true
|
| 803 |
+
},
|
| 804 |
+
"32097": {
|
| 805 |
+
"content": "<extra_id_2>",
|
| 806 |
+
"lstrip": false,
|
| 807 |
+
"normalized": false,
|
| 808 |
+
"rstrip": false,
|
| 809 |
+
"single_word": false,
|
| 810 |
+
"special": true
|
| 811 |
+
},
|
| 812 |
+
"32098": {
|
| 813 |
+
"content": "<extra_id_1>",
|
| 814 |
+
"lstrip": false,
|
| 815 |
+
"normalized": false,
|
| 816 |
+
"rstrip": false,
|
| 817 |
+
"single_word": false,
|
| 818 |
+
"special": true
|
| 819 |
+
},
|
| 820 |
+
"32099": {
|
| 821 |
+
"content": "<extra_id_0>",
|
| 822 |
+
"lstrip": false,
|
| 823 |
+
"normalized": false,
|
| 824 |
+
"rstrip": false,
|
| 825 |
+
"single_word": false,
|
| 826 |
+
"special": true
|
| 827 |
+
}
|
| 828 |
+
},
|
| 829 |
+
"additional_special_tokens": [
|
| 830 |
+
"<extra_id_0>",
|
| 831 |
+
"<extra_id_1>",
|
| 832 |
+
"<extra_id_2>",
|
| 833 |
+
"<extra_id_3>",
|
| 834 |
+
"<extra_id_4>",
|
| 835 |
+
"<extra_id_5>",
|
| 836 |
+
"<extra_id_6>",
|
| 837 |
+
"<extra_id_7>",
|
| 838 |
+
"<extra_id_8>",
|
| 839 |
+
"<extra_id_9>",
|
| 840 |
+
"<extra_id_10>",
|
| 841 |
+
"<extra_id_11>",
|
| 842 |
+
"<extra_id_12>",
|
| 843 |
+
"<extra_id_13>",
|
| 844 |
+
"<extra_id_14>",
|
| 845 |
+
"<extra_id_15>",
|
| 846 |
+
"<extra_id_16>",
|
| 847 |
+
"<extra_id_17>",
|
| 848 |
+
"<extra_id_18>",
|
| 849 |
+
"<extra_id_19>",
|
| 850 |
+
"<extra_id_20>",
|
| 851 |
+
"<extra_id_21>",
|
| 852 |
+
"<extra_id_22>",
|
| 853 |
+
"<extra_id_23>",
|
| 854 |
+
"<extra_id_24>",
|
| 855 |
+
"<extra_id_25>",
|
| 856 |
+
"<extra_id_26>",
|
| 857 |
+
"<extra_id_27>",
|
| 858 |
+
"<extra_id_28>",
|
| 859 |
+
"<extra_id_29>",
|
| 860 |
+
"<extra_id_30>",
|
| 861 |
+
"<extra_id_31>",
|
| 862 |
+
"<extra_id_32>",
|
| 863 |
+
"<extra_id_33>",
|
| 864 |
+
"<extra_id_34>",
|
| 865 |
+
"<extra_id_35>",
|
| 866 |
+
"<extra_id_36>",
|
| 867 |
+
"<extra_id_37>",
|
| 868 |
+
"<extra_id_38>",
|
| 869 |
+
"<extra_id_39>",
|
| 870 |
+
"<extra_id_40>",
|
| 871 |
+
"<extra_id_41>",
|
| 872 |
+
"<extra_id_42>",
|
| 873 |
+
"<extra_id_43>",
|
| 874 |
+
"<extra_id_44>",
|
| 875 |
+
"<extra_id_45>",
|
| 876 |
+
"<extra_id_46>",
|
| 877 |
+
"<extra_id_47>",
|
| 878 |
+
"<extra_id_48>",
|
| 879 |
+
"<extra_id_49>",
|
| 880 |
+
"<extra_id_50>",
|
| 881 |
+
"<extra_id_51>",
|
| 882 |
+
"<extra_id_52>",
|
| 883 |
+
"<extra_id_53>",
|
| 884 |
+
"<extra_id_54>",
|
| 885 |
+
"<extra_id_55>",
|
| 886 |
+
"<extra_id_56>",
|
| 887 |
+
"<extra_id_57>",
|
| 888 |
+
"<extra_id_58>",
|
| 889 |
+
"<extra_id_59>",
|
| 890 |
+
"<extra_id_60>",
|
| 891 |
+
"<extra_id_61>",
|
| 892 |
+
"<extra_id_62>",
|
| 893 |
+
"<extra_id_63>",
|
| 894 |
+
"<extra_id_64>",
|
| 895 |
+
"<extra_id_65>",
|
| 896 |
+
"<extra_id_66>",
|
| 897 |
+
"<extra_id_67>",
|
| 898 |
+
"<extra_id_68>",
|
| 899 |
+
"<extra_id_69>",
|
| 900 |
+
"<extra_id_70>",
|
| 901 |
+
"<extra_id_71>",
|
| 902 |
+
"<extra_id_72>",
|
| 903 |
+
"<extra_id_73>",
|
| 904 |
+
"<extra_id_74>",
|
| 905 |
+
"<extra_id_75>",
|
| 906 |
+
"<extra_id_76>",
|
| 907 |
+
"<extra_id_77>",
|
| 908 |
+
"<extra_id_78>",
|
| 909 |
+
"<extra_id_79>",
|
| 910 |
+
"<extra_id_80>",
|
| 911 |
+
"<extra_id_81>",
|
| 912 |
+
"<extra_id_82>",
|
| 913 |
+
"<extra_id_83>",
|
| 914 |
+
"<extra_id_84>",
|
| 915 |
+
"<extra_id_85>",
|
| 916 |
+
"<extra_id_86>",
|
| 917 |
+
"<extra_id_87>",
|
| 918 |
+
"<extra_id_88>",
|
| 919 |
+
"<extra_id_89>",
|
| 920 |
+
"<extra_id_90>",
|
| 921 |
+
"<extra_id_91>",
|
| 922 |
+
"<extra_id_92>",
|
| 923 |
+
"<extra_id_93>",
|
| 924 |
+
"<extra_id_94>",
|
| 925 |
+
"<extra_id_95>",
|
| 926 |
+
"<extra_id_96>",
|
| 927 |
+
"<extra_id_97>",
|
| 928 |
+
"<extra_id_98>",
|
| 929 |
+
"<extra_id_99>"
|
| 930 |
+
],
|
| 931 |
+
"clean_up_tokenization_spaces": true,
|
| 932 |
+
"eos_token": "</s>",
|
| 933 |
+
"extra_ids": 100,
|
| 934 |
+
"extra_special_tokens": {},
|
| 935 |
+
"model_max_length": 512,
|
| 936 |
+
"pad_token": "<pad>",
|
| 937 |
+
"tokenizer_class": "T5Tokenizer",
|
| 938 |
+
"unk_token": "<unk>"
|
| 939 |
+
}
|
models/chatbot_t5/training_args.bin
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:42fb2a22064282e8f09b4610ba008dd3138e1acc9ae501500af8225913ec9bdd
|
| 3 |
+
size 5777
|
models/complaint_classifier_rf.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:0d2c197298f8d1bfa907523c9155f4631e6055333948eb3b6a6e520aa8e2ad08
|
| 3 |
+
size 38277841
|
models/tfidf_vectorizer.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:0f484985441c6e095fe89402b015faac5c278dc224b7140cde747954e5ee2201
|
| 3 |
+
size 51265
|
proejectremember_andnote.txt
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
if you converting data into csv but if have code have 4 colum and i some line you hacve 5 it give error
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
Ahh — nice, bro. That error happens because XGBoost doesn’t accept sparse matrices (like TF-IDF) in its native DMatrix unless you convert them properly.
|
| 5 |
+
|
| 6 |
+
logistic ,svm,xboost is good in classification but in good sentiment so thaat why onaa try bert
|
| 7 |
+
|
| 8 |
+
Encoding UTF-8 in Python is the process of converting human-readable text into a format that computers can store and transmit as raw data (bytes), specifically using the rules of the UTF-8 system.
|
| 9 |
+
Think of it like translating a message into a secret code that a computer understands.
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
Imagine you are telling a story. When you get to the very end, you might say "The End."
|
| 13 |
+
The <|endoftext|> token is exactly like "The End" for a computer model.
|
| 14 |
+
What it means:
|
| 15 |
+
For the computer: "I am finished writing now."
|
| 16 |
+
During training: It helped the computer learn where one story stops and another starts.
|
| 17 |
+
When you get an answer: If the computer decides to use this token, its software stops the response immediately.
|
| 18 |
+
It's a secret signal, hidden from you, that tells the AI to stop talking and give you the final answer.
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
also used
|
| 22 |
+
|
| 23 |
+
def detect_mixed(text, sentiment):
|
| 24 |
+
pos_words = ["good","great","amazing","excellent","perfect","love"]
|
| 25 |
+
neg_words = ["delay","broken","bad","terrible","refund","lost","not"]
|
| 26 |
+
pos = any(w in text.lower() for w in pos_words)
|
| 27 |
+
neg = any(w in text.lower() for w in neg_words)
|
| 28 |
+
|
| 29 |
+
if pos and neg:
|
| 30 |
+
return "Mixed"
|
| 31 |
+
return sentiment
|
| 32 |
+
result = bert_sentiment(text)[0]
|
| 33 |
+
sentiment = detect_mixed(text, result['label'])
|
| 34 |
+
|
| 35 |
+
def polarity_override(text, sentiment):
|
| 36 |
+
text = text.lower()
|
| 37 |
+
negative_keywords = ["delay", "late", "scammed", "broken", "refund not", "not received", "missing", "cancelled"]
|
| 38 |
+
positive_keywords = ["delivered", "resolved", "refunded", "on time", "working", "successfully"]
|
| 39 |
+
|
| 40 |
+
if any(word in text for word in negative_keywords):
|
| 41 |
+
return "Negative"
|
| 42 |
+
elif any(word in text for word in positive_keywords):
|
| 43 |
+
return "Positive"
|
| 44 |
+
return sentiment
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
if length problem apper try to fix bt poolingg=max_length
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
you can seee model diffent after chaing epoch
|
| 51 |
+
by this
|
| 52 |
+
|
| 53 |
+
import pandas as pd
|
| 54 |
+
import matplotlib.pyplot as plt
|
| 55 |
+
|
| 56 |
+
# Load training history from Trainer's log
|
| 57 |
+
logs = pd.DataFrame(trainer.state.log_history)
|
| 58 |
+
|
| 59 |
+
# Keep only relevant columns
|
| 60 |
+
logs = logs.dropna(subset=['loss','eval_loss'], how='all')
|
| 61 |
+
|
| 62 |
+
plt.figure(figsize=(8,5))
|
| 63 |
+
plt.plot(logs["epoch"], logs["loss"], label="Training Loss")
|
| 64 |
+
if "eval_loss" in logs.columns:
|
| 65 |
+
plt.plot(logs["epoch"], logs["eval_loss"], label="Validation Loss")
|
| 66 |
+
plt.xlabel("Epoch")
|
| 67 |
+
plt.ylabel("Loss")
|
| 68 |
+
plt.title("Training vs Validation Loss")
|
| 69 |
+
plt.legend()
|
| 70 |
+
plt.grid(True)
|
| 71 |
+
plt.show()
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
for tranfomer errors
|
| 77 |
+
|
| 78 |
+
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM, TrainingArguments, Trainer
|
| 79 |
+
import numpy as np
|
| 80 |
+
|
| 81 |
+
model_name = "t5-small"
|
| 82 |
+
tokenizer = AutoTokenizer.from_pretrained(model_name)
|
| 83 |
+
model = AutoModelForSeq2SeqLM.from_pretrained(model_name)
|
| 84 |
+
|
| 85 |
+
training_args = TrainingArguments(
|
| 86 |
+
output_dir="./results",
|
| 87 |
+
num_train_epochs=3,
|
| 88 |
+
per_device_train_batch_size=8,
|
| 89 |
+
per_device_eval_batch_size=8,
|
| 90 |
+
learning_rate=2e-4,
|
| 91 |
+
weight_decay=0.01,
|
| 92 |
+
eval_strategy="epoch", # <- use eval_strategy (not evaluation_strategy)
|
| 93 |
+
save_strategy="epoch", # save checkpoints every epoch
|
| 94 |
+
logging_strategy="steps", # or "epoch"
|
| 95 |
+
logging_steps=100,
|
| 96 |
+
logging_dir="./logs",
|
| 97 |
+
report_to="none"
|
| 98 |
+
)
|
| 99 |
+
|
| 100 |
+
trainer = Trainer(
|
| 101 |
+
model=model,
|
| 102 |
+
args=training_args,
|
| 103 |
+
train_dataset=tokenized_train,
|
| 104 |
+
eval_dataset=tokenized_test,
|
| 105 |
+
tokenizer=tokenizer,
|
| 106 |
+
compute_metrics=compute_metrics,
|
| 107 |
+
# predict_with_generate=True # enable if you want generated outputs for seq2seq eval
|
| 108 |
+
)
|
| 109 |
+
|
| 110 |
+
trainer.train()
|
| 111 |
+
|
requirements.txt
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Flask==3.0.2
|
| 2 |
+
transformers==4.45.1
|
| 3 |
+
torch
|
| 4 |
+
scikit-learn
|
| 5 |
+
joblib
|
| 6 |
+
numpy
|
| 7 |
+
pandas
|
| 8 |
+
|
| 9 |
+
Flask-Login==0.6.2
|
| 10 |
+
Flask-SQLAlchemy==3.0.3
|
| 11 |
+
Flask-Mail==0.9.1
|
| 12 |
+
transformers==4.45.1
|
| 13 |
+
torch
|
| 14 |
+
joblib
|
| 15 |
+
numpy
|
| 16 |
+
pandas
|
| 17 |
+
sentencepiece
|
static/script.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const chatForm = document.getElementById("chat-form");
|
| 2 |
+
const userInput = document.getElementById("user-input");
|
| 3 |
+
const chatBox = document.getElementById("chat-box");
|
| 4 |
+
const orderIdEl = document.getElementById("order_id");
|
| 5 |
+
const categoryEl = document.getElementById("category");
|
| 6 |
+
const sentimentEl = document.getElementById("sentiment");
|
| 7 |
+
const negativeBox = document.getElementById("negative-box");
|
| 8 |
+
|
| 9 |
+
let sentimentChart = null;
|
| 10 |
+
|
| 11 |
+
// 🧠 Append User Message
|
| 12 |
+
function appendUser(text) {
|
| 13 |
+
chatBox.innerHTML += `<p class="user-msg">🧑 You: ${text}</p>`;
|
| 14 |
+
chatBox.scrollTop = chatBox.scrollHeight;
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
// 🤖 Append Bot Message
|
| 18 |
+
function appendBot(text) {
|
| 19 |
+
chatBox.innerHTML += `<p class="bot-msg">🤖 Bot: ${text}</p>`;
|
| 20 |
+
chatBox.scrollTop = chatBox.scrollHeight;
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
// ⭐ Send chat message
|
| 24 |
+
chatForm.addEventListener("submit", async (e) => {
|
| 25 |
+
e.preventDefault();
|
| 26 |
+
|
| 27 |
+
const text = userInput.value.trim();
|
| 28 |
+
const order_id = orderIdEl.value.trim();
|
| 29 |
+
if (!text) return;
|
| 30 |
+
|
| 31 |
+
appendUser(text);
|
| 32 |
+
userInput.value = "";
|
| 33 |
+
|
| 34 |
+
try {
|
| 35 |
+
const res = await fetch("/chat", {
|
| 36 |
+
method: "POST",
|
| 37 |
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
| 38 |
+
body: new URLSearchParams({ user_input: text, order_id })
|
| 39 |
+
});
|
| 40 |
+
|
| 41 |
+
const data = await res.json();
|
| 42 |
+
|
| 43 |
+
if (data.error) {
|
| 44 |
+
appendBot("Sorry, could not process your message.");
|
| 45 |
+
return;
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
appendBot(data.reply);
|
| 49 |
+
|
| 50 |
+
categoryEl.textContent = data.category || "—";
|
| 51 |
+
sentimentEl.textContent = `${data.sentiment || "—"} (${data.confidence || 0}%)`;
|
| 52 |
+
|
| 53 |
+
await updateAnalytics();
|
| 54 |
+
await updateNegatives();
|
| 55 |
+
} catch (err) {
|
| 56 |
+
console.error(err);
|
| 57 |
+
appendBot("Network error — try again.");
|
| 58 |
+
}
|
| 59 |
+
});
|
| 60 |
+
|
| 61 |
+
// 📊 Update Analytics Charts
|
| 62 |
+
async function updateAnalytics() {
|
| 63 |
+
const res = await fetch("/analytics");
|
| 64 |
+
const data = await res.json();
|
| 65 |
+
|
| 66 |
+
const ctx = document.getElementById("sentimentChart");
|
| 67 |
+
|
| 68 |
+
if (sentimentChart) sentimentChart.destroy();
|
| 69 |
+
|
| 70 |
+
sentimentChart = new Chart(ctx, {
|
| 71 |
+
type: "pie",
|
| 72 |
+
data: {
|
| 73 |
+
labels: data.labels,
|
| 74 |
+
datasets: [{
|
| 75 |
+
data: data.values,
|
| 76 |
+
backgroundColor: ["#2ecc71", "#e74c3c", "#f1c40f"]
|
| 77 |
+
}]
|
| 78 |
+
}
|
| 79 |
+
});
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
// ⚠️ Update Negative Messages Box
|
| 83 |
+
async function updateNegatives() {
|
| 84 |
+
if (!negativeBox) return; // Safety check
|
| 85 |
+
|
| 86 |
+
const res = await fetch("/admin/negatives-data");
|
| 87 |
+
const data = await res.json();
|
| 88 |
+
|
| 89 |
+
negativeBox.innerHTML = data.length === 0
|
| 90 |
+
? "<p>No negative messages yet.</p>"
|
| 91 |
+
: data.map(msg =>
|
| 92 |
+
`<p class="neg-item">⚠️ <b>${msg.username}</b>: ${msg.message}</p>`
|
| 93 |
+
).join("");
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
// auto-refresh negative messages
|
| 97 |
+
setInterval(updateNegatives, 8000);
|
static/style.css
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
:root{--bg:#f4f7fb;--card:#fff;--accent:#27ae60;--muted:#6b7280}
|
| 2 |
+
*{box-sizing:border-box}
|
| 3 |
+
body{font-family:Inter,system-ui,Arial,sans-serif;background:var(--bg);margin:0;color:#111}
|
| 4 |
+
.topbar{display:flex;justify-content:space-between;align-items:center;padding:12px 20px;background:linear-gradient(90deg,#ffffff,#fbfdfe);border-bottom:1px solid #eee}
|
| 5 |
+
.brand{font-weight:700}
|
| 6 |
+
.nav a{margin-left:12px;text-decoration:none;color:var(--muted)}
|
| 7 |
+
.container{max-width:1100px;margin:22px auto;padding:12px}
|
| 8 |
+
.chat-grid{display:grid;grid-template-columns:1fr 360px;gap:20px}
|
| 9 |
+
.chat-panel{background:var(--card);border-radius:12px;padding:14px;box-shadow:0 8px 24px rgba(16,24,40,0.06)}
|
| 10 |
+
.side-panel{background:var(--card);border-radius:12px;padding:14px;box-shadow:0 8px 24px rgba(16,24,40,0.06)}
|
| 11 |
+
.chat-box{height:360px;overflow:auto;border:1px solid #eef2f7;border-radius:8px;padding:12px;background:#fcfeff}
|
| 12 |
+
.user-msg{text-align:right;margin:8px 0;color:#0f172a}
|
| 13 |
+
.bot-msg{text-align:left;margin:8px 0;color:#064e3b}
|
| 14 |
+
.input-row{display:flex;gap:8px;margin-top:10px}
|
| 15 |
+
#user-input{flex:1;padding:10px;border:1px solid #e6eef6;border-radius:8px}
|
| 16 |
+
#order_id{width:100%;padding:8px;margin-top:8px;border-radius:8px;border:1px solid #e6eef6}
|
| 17 |
+
#send-btn{background:var(--accent);color:#fff;border:none;padding:10px 14px;border-radius:8px;cursor:pointer}
|
| 18 |
+
.meta{display:flex;gap:14px;margin-top:12px;color:var(--muted)}
|
| 19 |
+
.negative-box{height:180px;overflow:auto;border:1px solid #fdecea;background:#fff5f5;padding:8px;border-radius:8px}
|
| 20 |
+
.negative-entry{border-bottom:1px dashed #ffdede;padding:8px;margin-bottom:6px}
|
| 21 |
+
.flashes .flash{padding:10px;border-radius:6px;margin-bottom:8px}
|
| 22 |
+
.flash.success{background:#e6ffed;color:#0b6a3a}
|
| 23 |
+
.flash.warning{background:#fff7e6;color:#7a4d00}
|
| 24 |
+
.flash.danger{background:#ffe6e6;color:#912d2d}
|
| 25 |
+
.footer{padding:12px;text-align:center;color:var(--muted);font-size:13px;margin-top:18px}
|
| 26 |
+
.home-grid{display:flex;gap:20px}
|
| 27 |
+
.home-left{flex:1}
|
| 28 |
+
.home-right{width:420px}
|
| 29 |
+
.btn{display:inline-block;padding:10px 14px;background:var(--accent);color:#fff;border-radius:8px;text-decoration:none}
|
| 30 |
+
.btn.ghost{background:transparent;color:var(--accent);border:1px solid var(--accent)}
|
| 31 |
+
@media(max-width:900px){.chat-grid{grid-template-columns:1fr}.home-grid{flex-direction:column}}
|
templates/admin_negatives.html
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% extends "base.html" %}
|
| 2 |
+
{% block content %}
|
| 3 |
+
<h2>Negative Messages</h2>
|
| 4 |
+
<table class="table">
|
| 5 |
+
<thead>
|
| 6 |
+
<tr><th>Time</th><th>User</th><th>Order ID</th><th>Message</th><th>Category</th><th>Status</th></tr>
|
| 7 |
+
</thead>
|
| 8 |
+
<tbody>
|
| 9 |
+
{% for m in negatives %}
|
| 10 |
+
<tr>
|
| 11 |
+
<td>{{ m.created_at }}</td>
|
| 12 |
+
<td>{{ m.username }}</td>
|
| 13 |
+
<td>{{ m.order_id }}</td>
|
| 14 |
+
<td>{{ m.message }}</td>
|
| 15 |
+
<td>{{ m.category }}</td>
|
| 16 |
+
<td>{{ m.status }}</td>
|
| 17 |
+
</tr>
|
| 18 |
+
{% endfor %}
|
| 19 |
+
</tbody>
|
| 20 |
+
</table>
|
| 21 |
+
{% endblock %}
|
templates/base.html
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!doctype html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="utf-8" />
|
| 5 |
+
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
| 6 |
+
<title>FastShip AI</title>
|
| 7 |
+
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}">
|
| 8 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
| 9 |
+
</head>
|
| 10 |
+
<body>
|
| 11 |
+
<header class="topbar">
|
| 12 |
+
<div class="brand">🚚 FastShip AI</div>
|
| 13 |
+
<nav class="nav">
|
| 14 |
+
{% if current_user.is_authenticated %}
|
| 15 |
+
<span class="user">Hello, {{ current_user.fullname }}</span>
|
| 16 |
+
<a href="{{ url_for('dashboard') }}">Dashboard</a>
|
| 17 |
+
{% if current_user.is_admin %}
|
| 18 |
+
<a href="{{ url_for('admin_negatives') }}">Admin</a>
|
| 19 |
+
{% endif %}
|
| 20 |
+
<a href="{{ url_for('logout') }}">Logout</a>
|
| 21 |
+
{% else %}
|
| 22 |
+
<a href="{{ url_for('login') }}">Login</a>
|
| 23 |
+
<a href="{{ url_for('register') }}">Register</a>
|
| 24 |
+
{% endif %}
|
| 25 |
+
</nav>
|
| 26 |
+
</header>
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
<main class="main">
|
| 30 |
+
<div class="container">
|
| 31 |
+
{% with messages = get_flashed_messages(with_categories=true) %}
|
| 32 |
+
{% if messages %}
|
| 33 |
+
<div class="flashes">
|
| 34 |
+
{% for category, msg in messages %}
|
| 35 |
+
<div class="flash {{ category|lower }}">{{ msg }}</div>
|
| 36 |
+
{% endfor %}
|
| 37 |
+
</div>
|
| 38 |
+
{% endif %}
|
| 39 |
+
{% endwith %}
|
| 40 |
+
{% block content %}{% endblock %}
|
| 41 |
+
</div>
|
| 42 |
+
</main>
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
<footer class="footer">© FastShip AI</footer>
|
| 46 |
+
</body>
|
| 47 |
+
</html>
|
templates/chat.html
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% extends "base.html" %}
|
| 2 |
+
{% block content %}
|
| 3 |
+
<div class="chat-grid">
|
| 4 |
+
<section class="chat-panel">
|
| 5 |
+
<h2>Chat</h2>
|
| 6 |
+
<div id="chat-box" class="chat-box" aria-live="polite"></div>
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
<form id="chat-form" class="chat-form" autocomplete="off">
|
| 10 |
+
<input id="order_id" name="order_id" placeholder="Order ID (optional)" />
|
| 11 |
+
<div class="input-row">
|
| 12 |
+
<input id="user-input" name="user_input" placeholder="Type your message..." />
|
| 13 |
+
<button id="send-btn" type="submit">Send</button>
|
| 14 |
+
</div>
|
| 15 |
+
</form>
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
<div class="meta">
|
| 19 |
+
<div><strong>Category:</strong> <span id="category">—</span></div>
|
| 20 |
+
<div><strong>Sentiment:</strong> <span id="sentiment">—</span></div>
|
| 21 |
+
</div>
|
| 22 |
+
</section>
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
<aside class="side-panel">
|
| 26 |
+
<h3>Live Analytics</h3>
|
| 27 |
+
<canvas id="sentimentChart" height="140"></canvas>
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
<h3>Recent Negatives</h3>
|
| 31 |
+
<div id="negative-box" class="negative-box"></div>
|
| 32 |
+
</aside>
|
| 33 |
+
</div>
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
| 37 |
+
<script src="{{ url_for('static', filename='script.js') }}"></script>
|
| 38 |
+
{% endblock %}
|
templates/dashboard.html
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% extends "base.html" %}
|
| 2 |
+
{% block content %}
|
| 3 |
+
<h2>Dashboard</h2>
|
| 4 |
+
<p>Total messages: {{ total }}</p>
|
| 5 |
+
<p>Positive: {{ pos }} | Neutral: {{ neu }} | Negative: {{ neg }}</p>
|
| 6 |
+
<p><a href="{{ url_for('admin_negatives') }}">View negative messages (admin)</a></p>
|
| 7 |
+
{% endblock %}
|
templates/forgot.html
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% extends "base.html" %}
|
| 2 |
+
{% block content %}
|
| 3 |
+
<h2>Forgot Password</h2>
|
| 4 |
+
<form method="post">
|
| 5 |
+
<label>Enter your registered email</label><br/>
|
| 6 |
+
<input name="email" type="email" required><br/>
|
| 7 |
+
<button type="submit">Send OTP</button>
|
| 8 |
+
</form>
|
| 9 |
+
{% endblock %}
|
templates/index.html
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% extends "base.html" %}
|
| 2 |
+
{% block content %}
|
| 3 |
+
<div class="home-grid">
|
| 4 |
+
<div class="home-left">
|
| 5 |
+
<h2>🤖 FastShip AI Assistant</h2>
|
| 6 |
+
<p>Login to chat with the assistant or test the demo below.</p>
|
| 7 |
+
<a class="btn" href="{{ url_for('login') }}">Login</a>
|
| 8 |
+
<a class="btn ghost" href="{{ url_for('register') }}">Register</a>
|
| 9 |
+
</div>
|
| 10 |
+
<div class="home-right">
|
| 11 |
+
<h3>Live Demo</h3>
|
| 12 |
+
<div id="chat-box-mini" class="chat-box-mini"></div>
|
| 13 |
+
<div class="input-area">
|
| 14 |
+
<input id="user-input-mini" type="text" placeholder="Try: "Where's my order?"" />
|
| 15 |
+
<button id="send-mini" class="btn">Send</button>
|
| 16 |
+
</div>
|
| 17 |
+
</div>
|
| 18 |
+
</div>
|
| 19 |
+
<script>
|
| 20 |
+
// tiny demo handler calling /analyze
|
| 21 |
+
document.getElementById('send-mini').addEventListener('click', async function(){
|
| 22 |
+
const t = document.getElementById('user-input-mini').value.trim();
|
| 23 |
+
if(!t) return;
|
| 24 |
+
const r = await fetch('/analyze', {method:'POST', headers:{'Content-Type':'application/x-www-form-urlencoded'}, body: new URLSearchParams({user_input:t})});
|
| 25 |
+
const js = await r.json();
|
| 26 |
+
const el = document.getElementById('chat-box-mini');
|
| 27 |
+
el.innerHTML += `<div><b>You:</b> ${t}</div><div><b>Bot:</b> ${js.reply}</div>`;
|
| 28 |
+
});
|
| 29 |
+
</script>
|
| 30 |
+
{% endblock %}
|
templates/login.html
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% extends "base.html" %}
|
| 2 |
+
{% block content %}
|
| 3 |
+
|
| 4 |
+
<style>
|
| 5 |
+
.auth-wrapper {
|
| 6 |
+
min-height: 80vh;
|
| 7 |
+
display: flex;
|
| 8 |
+
justify-content: center;
|
| 9 |
+
align-items: center;
|
| 10 |
+
background: linear-gradient(135deg, #4a90e2, #7b4397);
|
| 11 |
+
padding: 20px;
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
.auth-card {
|
| 15 |
+
width: 100%;
|
| 16 |
+
max-width: 420px;
|
| 17 |
+
background: #ffffff;
|
| 18 |
+
border-radius: 12px;
|
| 19 |
+
box-shadow: 0 10px 30px rgba(0,0,0,0.15);
|
| 20 |
+
padding: 26px 22px 28px;
|
| 21 |
+
box-sizing: border-box;
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
.auth-title {
|
| 25 |
+
text-align: center;
|
| 26 |
+
margin-bottom: 8px;
|
| 27 |
+
font-size: 24px;
|
| 28 |
+
color: #333;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
.auth-subtitle {
|
| 32 |
+
text-align: center;
|
| 33 |
+
font-size: 13px;
|
| 34 |
+
color: #777;
|
| 35 |
+
margin-bottom: 20px;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
.auth-form label {
|
| 39 |
+
font-size: 14px;
|
| 40 |
+
color: #444;
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
.auth-form input {
|
| 44 |
+
width: 100%;
|
| 45 |
+
padding: 10px;
|
| 46 |
+
margin: 6px 0 16px;
|
| 47 |
+
border-radius: 6px;
|
| 48 |
+
border: 1px solid #ccc;
|
| 49 |
+
font-size: 14px;
|
| 50 |
+
outline: none;
|
| 51 |
+
box-sizing: border-box;
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
.auth-form input:focus {
|
| 55 |
+
border-color: #4a90e2;
|
| 56 |
+
box-shadow: 0 0 0 2px rgba(74,144,226,0.2);
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
.auth-btn {
|
| 60 |
+
width: 100%;
|
| 61 |
+
padding: 10px;
|
| 62 |
+
border-radius: 6px;
|
| 63 |
+
border: none;
|
| 64 |
+
background: #4a90e2;
|
| 65 |
+
color: #fff;
|
| 66 |
+
font-size: 15px;
|
| 67 |
+
font-weight: 600;
|
| 68 |
+
cursor: pointer;
|
| 69 |
+
margin-top: 4px;
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
.auth-btn:hover {
|
| 73 |
+
background: #3a7bd5;
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
.auth-extra {
|
| 77 |
+
margin-top: 12px;
|
| 78 |
+
font-size: 13px;
|
| 79 |
+
text-align: center;
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
.auth-extra a {
|
| 83 |
+
color: #4a90e2;
|
| 84 |
+
text-decoration: none;
|
| 85 |
+
font-weight: 600;
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
.auth-extra a:hover {
|
| 89 |
+
text-decoration: underline;
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
@media (max-width: 480px) {
|
| 93 |
+
.auth-card {
|
| 94 |
+
padding: 22px 16px 24px;
|
| 95 |
+
}
|
| 96 |
+
}
|
| 97 |
+
</style>
|
| 98 |
+
|
| 99 |
+
<div class="auth-wrapper">
|
| 100 |
+
<div class="auth-card">
|
| 101 |
+
<h2 class="auth-title">Login</h2>
|
| 102 |
+
<p class="auth-subtitle">Welcome back! Please enter your details.</p>
|
| 103 |
+
|
| 104 |
+
<form method="post" class="auth-form">
|
| 105 |
+
<label>Email</label><br/>
|
| 106 |
+
<input name="email" type="email" required><br/>
|
| 107 |
+
|
| 108 |
+
<label>Password</label><br/>
|
| 109 |
+
<input name="password" type="password" required><br/>
|
| 110 |
+
|
| 111 |
+
<button type="submit" class="auth-btn">Login</button>
|
| 112 |
+
</form>
|
| 113 |
+
|
| 114 |
+
<p class="auth-extra">
|
| 115 |
+
<a href="{{ url_for('forgot') }}">Forgot password?</a>
|
| 116 |
+
</p>
|
| 117 |
+
</div>
|
| 118 |
+
</div>
|
| 119 |
+
|
| 120 |
+
{% endblock %}
|
templates/register.html
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% extends "base.html" %}
|
| 2 |
+
{% block content %}
|
| 3 |
+
|
| 4 |
+
<style>
|
| 5 |
+
.auth-wrapper {
|
| 6 |
+
min-height: 80vh;
|
| 7 |
+
display: flex;
|
| 8 |
+
justify-content: center;
|
| 9 |
+
align-items: center;
|
| 10 |
+
background: linear-gradient(135deg, #4a90e2, #7b4397);
|
| 11 |
+
padding: 20px;
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
.auth-card {
|
| 15 |
+
width: 100%;
|
| 16 |
+
max-width: 480px;
|
| 17 |
+
background: #ffffff;
|
| 18 |
+
border-radius: 12px;
|
| 19 |
+
box-shadow: 0 10px 30px rgba(0,0,0,0.15);
|
| 20 |
+
padding: 26px 22px 28px;
|
| 21 |
+
box-sizing: border-box;
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
.auth-title {
|
| 25 |
+
text-align: center;
|
| 26 |
+
margin-bottom: 8px;
|
| 27 |
+
font-size: 24px;
|
| 28 |
+
color: #333;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
.auth-subtitle {
|
| 32 |
+
text-align: center;
|
| 33 |
+
font-size: 13px;
|
| 34 |
+
color: #777;
|
| 35 |
+
margin-bottom: 20px;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
.auth-form label {
|
| 39 |
+
font-size: 14px;
|
| 40 |
+
color: #444;
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
.auth-form input,
|
| 44 |
+
.auth-form textarea {
|
| 45 |
+
width: 100%;
|
| 46 |
+
padding: 10px;
|
| 47 |
+
margin: 6px 0 16px;
|
| 48 |
+
border-radius: 6px;
|
| 49 |
+
border: 1px solid #ccc;
|
| 50 |
+
font-size: 14px;
|
| 51 |
+
outline: none;
|
| 52 |
+
box-sizing: border-box;
|
| 53 |
+
resize: vertical;
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
.auth-form input:focus,
|
| 57 |
+
.auth-form textarea:focus {
|
| 58 |
+
border-color: #4a90e2;
|
| 59 |
+
box-shadow: 0 0 0 2px rgba(74,144,226,0.2);
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
.auth-btn {
|
| 63 |
+
width: 100%;
|
| 64 |
+
padding: 10px;
|
| 65 |
+
border-radius: 6px;
|
| 66 |
+
border: none;
|
| 67 |
+
background: #4a90e2;
|
| 68 |
+
color: #fff;
|
| 69 |
+
font-size: 15px;
|
| 70 |
+
font-weight: 600;
|
| 71 |
+
cursor: pointer;
|
| 72 |
+
margin-top: 4px;
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
.auth-btn:hover {
|
| 76 |
+
background: #3a7bd5;
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
@media (max-width: 480px) {
|
| 80 |
+
.auth-card {
|
| 81 |
+
padding: 22px 16px 24px;
|
| 82 |
+
}
|
| 83 |
+
}
|
| 84 |
+
</style>
|
| 85 |
+
|
| 86 |
+
<div class="auth-wrapper">
|
| 87 |
+
<div class="auth-card">
|
| 88 |
+
<h2 class="auth-title">Register</h2>
|
| 89 |
+
<p class="auth-subtitle">Create your account to get started.</p>
|
| 90 |
+
|
| 91 |
+
<form method="post" class="auth-form">
|
| 92 |
+
<label>Full name</label><br/>
|
| 93 |
+
<input name="fullname" required><br/>
|
| 94 |
+
|
| 95 |
+
<label>Email</label><br/>
|
| 96 |
+
<input name="email" type="email" required><br/>
|
| 97 |
+
|
| 98 |
+
<label>Password</label><br/>
|
| 99 |
+
<input name="password" type="password" required><br/>
|
| 100 |
+
|
| 101 |
+
<label>Phone</label><br/>
|
| 102 |
+
<input name="phone"><br/>
|
| 103 |
+
|
| 104 |
+
<label>Address</label><br/>
|
| 105 |
+
<textarea name="address" rows="3"></textarea><br/>
|
| 106 |
+
|
| 107 |
+
<button type="submit" class="auth-btn">Register</button>
|
| 108 |
+
</form>
|
| 109 |
+
</div>
|
| 110 |
+
</div>
|
| 111 |
+
|
| 112 |
+
{% endblock %}
|
templates/reset.html
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% extends "base.html" %}
|
| 2 |
+
{% block content %}
|
| 3 |
+
<h2>Reset Password</h2>
|
| 4 |
+
<form method="post">
|
| 5 |
+
<label>Email</label><br/><input name="email" type="email" required><br/>
|
| 6 |
+
<label>OTP (check email)</label><br/><input name="otp" required><br/>
|
| 7 |
+
<label>New password</label><br/><input name="password" type="password" required><br/>
|
| 8 |
+
<button type="submit">Reset Password</button>
|
| 9 |
+
</form>
|
| 10 |
+
{% endblock %}
|