adding French
Browse files- Camembert/Camembert/label_encoder.pkl +3 -0
- Camembert/Camembert/saved_model/config.json +43 -0
- Camembert/Camembert/saved_model/model.safetensors +3 -0
- Camembert/Camembert/saved_tokenizer/added_tokens.json +3 -0
- Camembert/Camembert/saved_tokenizer/sentencepiece.bpe.model +3 -0
- Camembert/Camembert/saved_tokenizer/special_tokens_map.json +20 -0
- Camembert/Camembert/saved_tokenizer/tokenizer.json +0 -0
- Camembert/Camembert/saved_tokenizer/tokenizer_config.json +83 -0
- FrModel.py +159 -0
- Model.py +1 -1
- __pycache__/FrModel.cpython-310.pyc +0 -0
- __pycache__/Model.cpython-310.pyc +0 -0
- __pycache__/app.cpython-310.pyc +0 -0
- __pycache__/helper_functions.cpython-310.pyc +0 -0
- app.py +188 -17
- fr_neptune/fr_neptune/added_tokens.json +4 -0
- fr_neptune/fr_neptune/model.pt +3 -0
- fr_neptune/fr_neptune/sentencepiece.bpe.model +3 -0
- fr_neptune/fr_neptune/special_tokens_map.json +24 -0
- fr_neptune/fr_neptune/tokenizer.json +0 -0
- fr_neptune/fr_neptune/tokenizer_config.json +89 -0
- fr_neptune/fr_neptune/unique_labels.json +1 -0
- helper_functions.py +211 -2
- static/icons/English.svg +2 -0
- static/icons/France.svg +2 -0
- static/icons/flag-for-flag-france.htm +1 -0
- static/js/pdf.js +15 -1
- static/js/pdf_fr.js +236 -0
- static/js/sentence_fr.js +253 -0
- templates/pdf.html +42 -4
- templates/pdf_fr.html +177 -0
- templates/response_fr_sentence.html +50 -0
- templates/sentence.html +31 -14
- templates/sentence_fr.html +229 -0
- templates/voice.html +6 -0
- templates/voice_fr.html +235 -0
Camembert/Camembert/label_encoder.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:0298d9049295e4472f832099653bec067850fb84c8e19f84aa994a7124d5cf4e
|
3 |
+
size 187
|
Camembert/Camembert/saved_model/config.json
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"_name_or_path": "camembert-base",
|
3 |
+
"architectures": [
|
4 |
+
"CamembertForSequenceClassification"
|
5 |
+
],
|
6 |
+
"attention_probs_dropout_prob": 0.1,
|
7 |
+
"bos_token_id": 5,
|
8 |
+
"classifier_dropout": null,
|
9 |
+
"eos_token_id": 6,
|
10 |
+
"hidden_act": "gelu",
|
11 |
+
"hidden_dropout_prob": 0.1,
|
12 |
+
"hidden_size": 768,
|
13 |
+
"id2label": {
|
14 |
+
"0": "LABEL_0",
|
15 |
+
"1": "LABEL_1",
|
16 |
+
"2": "LABEL_2",
|
17 |
+
"3": "LABEL_3",
|
18 |
+
"4": "LABEL_4"
|
19 |
+
},
|
20 |
+
"initializer_range": 0.02,
|
21 |
+
"intermediate_size": 3072,
|
22 |
+
"label2id": {
|
23 |
+
"LABEL_0": 0,
|
24 |
+
"LABEL_1": 1,
|
25 |
+
"LABEL_2": 2,
|
26 |
+
"LABEL_3": 3,
|
27 |
+
"LABEL_4": 4
|
28 |
+
},
|
29 |
+
"layer_norm_eps": 1e-05,
|
30 |
+
"max_position_embeddings": 514,
|
31 |
+
"model_type": "camembert",
|
32 |
+
"num_attention_heads": 12,
|
33 |
+
"num_hidden_layers": 12,
|
34 |
+
"output_past": true,
|
35 |
+
"pad_token_id": 1,
|
36 |
+
"position_embedding_type": "absolute",
|
37 |
+
"problem_type": "single_label_classification",
|
38 |
+
"torch_dtype": "float32",
|
39 |
+
"transformers_version": "4.41.2",
|
40 |
+
"type_vocab_size": 1,
|
41 |
+
"use_cache": true,
|
42 |
+
"vocab_size": 32005
|
43 |
+
}
|
Camembert/Camembert/saved_model/model.safetensors
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:9d1747b6e96c281ed0206a061b49f1233b2354c33f7371c163b4df3c8f1dc1b2
|
3 |
+
size 442527332
|
Camembert/Camembert/saved_tokenizer/added_tokens.json
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"<unk>NOTUSED": 32005
|
3 |
+
}
|
Camembert/Camembert/saved_tokenizer/sentencepiece.bpe.model
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:988bc5a00281c6d210a5d34bd143d0363741a432fefe741bf71e61b1869d4314
|
3 |
+
size 810912
|
Camembert/Camembert/saved_tokenizer/special_tokens_map.json
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"additional_special_tokens": [
|
3 |
+
"<s>NOTUSED",
|
4 |
+
"</s>NOTUSED",
|
5 |
+
"<unk>NOTUSED"
|
6 |
+
],
|
7 |
+
"bos_token": "<s>",
|
8 |
+
"cls_token": "<s>",
|
9 |
+
"eos_token": "</s>",
|
10 |
+
"mask_token": {
|
11 |
+
"content": "<mask>",
|
12 |
+
"lstrip": true,
|
13 |
+
"normalized": false,
|
14 |
+
"rstrip": false,
|
15 |
+
"single_word": false
|
16 |
+
},
|
17 |
+
"pad_token": "<pad>",
|
18 |
+
"sep_token": "</s>",
|
19 |
+
"unk_token": "<unk>"
|
20 |
+
}
|
Camembert/Camembert/saved_tokenizer/tokenizer.json
ADDED
The diff for this file is too large to render.
See raw diff
|
|
Camembert/Camembert/saved_tokenizer/tokenizer_config.json
ADDED
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"added_tokens_decoder": {
|
3 |
+
"0": {
|
4 |
+
"content": "<s>NOTUSED",
|
5 |
+
"lstrip": false,
|
6 |
+
"normalized": false,
|
7 |
+
"rstrip": false,
|
8 |
+
"single_word": false,
|
9 |
+
"special": true
|
10 |
+
},
|
11 |
+
"1": {
|
12 |
+
"content": "<pad>",
|
13 |
+
"lstrip": false,
|
14 |
+
"normalized": false,
|
15 |
+
"rstrip": false,
|
16 |
+
"single_word": false,
|
17 |
+
"special": true
|
18 |
+
},
|
19 |
+
"2": {
|
20 |
+
"content": "</s>NOTUSED",
|
21 |
+
"lstrip": false,
|
22 |
+
"normalized": false,
|
23 |
+
"rstrip": false,
|
24 |
+
"single_word": false,
|
25 |
+
"special": true
|
26 |
+
},
|
27 |
+
"4": {
|
28 |
+
"content": "<unk>",
|
29 |
+
"lstrip": false,
|
30 |
+
"normalized": false,
|
31 |
+
"rstrip": false,
|
32 |
+
"single_word": false,
|
33 |
+
"special": true
|
34 |
+
},
|
35 |
+
"5": {
|
36 |
+
"content": "<s>",
|
37 |
+
"lstrip": false,
|
38 |
+
"normalized": false,
|
39 |
+
"rstrip": false,
|
40 |
+
"single_word": false,
|
41 |
+
"special": true
|
42 |
+
},
|
43 |
+
"6": {
|
44 |
+
"content": "</s>",
|
45 |
+
"lstrip": false,
|
46 |
+
"normalized": false,
|
47 |
+
"rstrip": false,
|
48 |
+
"single_word": false,
|
49 |
+
"special": true
|
50 |
+
},
|
51 |
+
"32004": {
|
52 |
+
"content": "<mask>",
|
53 |
+
"lstrip": true,
|
54 |
+
"normalized": false,
|
55 |
+
"rstrip": false,
|
56 |
+
"single_word": false,
|
57 |
+
"special": true
|
58 |
+
},
|
59 |
+
"32005": {
|
60 |
+
"content": "<unk>NOTUSED",
|
61 |
+
"lstrip": false,
|
62 |
+
"normalized": false,
|
63 |
+
"rstrip": false,
|
64 |
+
"single_word": false,
|
65 |
+
"special": true
|
66 |
+
}
|
67 |
+
},
|
68 |
+
"additional_special_tokens": [
|
69 |
+
"<s>NOTUSED",
|
70 |
+
"</s>NOTUSED",
|
71 |
+
"<unk>NOTUSED"
|
72 |
+
],
|
73 |
+
"bos_token": "<s>",
|
74 |
+
"clean_up_tokenization_spaces": true,
|
75 |
+
"cls_token": "<s>",
|
76 |
+
"eos_token": "</s>",
|
77 |
+
"mask_token": "<mask>",
|
78 |
+
"model_max_length": 512,
|
79 |
+
"pad_token": "<pad>",
|
80 |
+
"sep_token": "</s>",
|
81 |
+
"tokenizer_class": "CamembertTokenizer",
|
82 |
+
"unk_token": "<unk>"
|
83 |
+
}
|
FrModel.py
ADDED
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
import torch
|
3 |
+
import torch.nn as nn
|
4 |
+
import numpy as np
|
5 |
+
from transformers import AutoTokenizer
|
6 |
+
import pickle
|
7 |
+
|
8 |
+
fr_tokenizer = AutoTokenizer.from_pretrained("camembert-base")
|
9 |
+
|
10 |
+
# FRENCH Tokenizer
|
11 |
+
fr_tokenizer.add_special_tokens({'additional_special_tokens': ['<MULT>']})
|
12 |
+
fr_mult_token_id = fr_tokenizer.convert_tokens_to_ids('<MULT>')
|
13 |
+
fr_cls_token_id = fr_tokenizer.cls_token_id
|
14 |
+
fr_sep_token_id = fr_tokenizer.sep_token_id
|
15 |
+
fr_pad_token_id = fr_tokenizer.pad_token_id
|
16 |
+
|
17 |
+
## Voice Part functions
|
18 |
+
maxlen = 255 # maximum of length
|
19 |
+
batch_size = 32
|
20 |
+
max_pred = 5 # max tokens of prediction
|
21 |
+
n_layers = 6 # number of Encoder of Encoder Layer
|
22 |
+
n_heads = 12 # number of heads in Multi-Head Attention
|
23 |
+
d_model = 768 # Embedding Size
|
24 |
+
d_ff = 768 * 4 # 4*d_model, FeedForward dimension
|
25 |
+
d_k = d_v = 64 # dimension of K(=Q), V
|
26 |
+
n_segments = 2
|
27 |
+
fr_vocab_size = fr_tokenizer.vocab_size +2
|
28 |
+
|
29 |
+
def get_attn_pad_mask(seq_q, seq_k):
|
30 |
+
batch_size, len_q = seq_q.size()
|
31 |
+
batch_size, len_k = seq_k.size()
|
32 |
+
# eq(zero) is PAD token
|
33 |
+
pad_attn_mask = seq_k.data.eq(1).unsqueeze(1) # batch_size x 1 x len_k(=len_q), one is masking
|
34 |
+
return pad_attn_mask.expand(batch_size, len_q, len_k) # batch_size x len_q x len_k
|
35 |
+
|
36 |
+
class Embedding(nn.Module):
|
37 |
+
def __init__(self):
|
38 |
+
super(Embedding, self).__init__()
|
39 |
+
self.tok_embed = nn.Embedding(fr_vocab_size, d_model) # token embedding
|
40 |
+
self.pos_embed = nn.Embedding(maxlen, d_model) # position embedding
|
41 |
+
self.seg_embed = nn.Embedding(n_segments, d_model) # segment(token type) embedding
|
42 |
+
self.norm = nn.LayerNorm(d_model)
|
43 |
+
|
44 |
+
def forward(self, x, seg):
|
45 |
+
seq_len = x.size(1)
|
46 |
+
pos = torch.arange(seq_len, dtype=torch.long, device=x.device)
|
47 |
+
pos = pos.unsqueeze(0).expand_as(x) # (seq_len,) -> (batch_size, seq_len)
|
48 |
+
embedding = self.tok_embed(x)
|
49 |
+
embedding += self.pos_embed(pos)
|
50 |
+
embedding += self.seg_embed(seg)
|
51 |
+
return self.norm(embedding)
|
52 |
+
|
53 |
+
class ScaledDotProductAttention(nn.Module):
|
54 |
+
def __init__(self):
|
55 |
+
super(ScaledDotProductAttention, self).__init__()
|
56 |
+
|
57 |
+
def forward(self, Q, K, V, attn_mask):
|
58 |
+
scores = torch.matmul(Q, K.transpose(-1, -2)) / np.sqrt(d_k) # scores : [batch_size x n_heads x len_q(=len_k) x len_k(=len_q)]
|
59 |
+
scores.masked_fill_(attn_mask, -1e9) # Fills elements of self tensor with value where mask is one.
|
60 |
+
attn = nn.Softmax(dim=-1)(scores)
|
61 |
+
context = torch.matmul(attn, V)
|
62 |
+
return scores , context, attn
|
63 |
+
|
64 |
+
class MultiHeadAttention(nn.Module):
|
65 |
+
def __init__(self):
|
66 |
+
super(MultiHeadAttention, self).__init__()
|
67 |
+
self.W_Q = nn.Linear(d_model, d_k * n_heads)
|
68 |
+
self.W_K = nn.Linear(d_model, d_k * n_heads)
|
69 |
+
self.W_V = nn.Linear(d_model, d_v * n_heads)
|
70 |
+
self.fc = nn.Linear(n_heads * d_v, d_model)
|
71 |
+
self.norm = nn.LayerNorm(d_model)
|
72 |
+
def forward(self, Q, K, V, attn_mask):
|
73 |
+
# q: [batch_size x len_q x d_model], k: [batch_size x len_k x d_model], v: [batch_size x len_k x d_model]
|
74 |
+
residual, batch_size = Q, Q.size(0)
|
75 |
+
device = Q.device
|
76 |
+
Q, K, V = Q.to(device), K.to(device), V.to(device)
|
77 |
+
# (B, S, D) -proj-> (B, S, D) -split-> (B, S, H, W) -trans-> (B, H, S, W)
|
78 |
+
q_s = self.W_Q(Q).view(batch_size, -1, n_heads, d_k).transpose(1,2) # q_s: [batch_size x n_heads x len_q x d_k]
|
79 |
+
k_s = self.W_K(K).view(batch_size, -1, n_heads, d_k).transpose(1,2) # k_s: [batch_size x n_heads x len_k x d_k]
|
80 |
+
v_s = self.W_V(V).view(batch_size, -1, n_heads, d_v).transpose(1,2) # v_s: [batch_size x n_heads x len_k x d_v]
|
81 |
+
|
82 |
+
attn_mask = attn_mask.unsqueeze(1).repeat(1, n_heads, 1, 1) # attn_mask : [batch_size x n_heads x len_q x len_k]
|
83 |
+
|
84 |
+
# context: [batch_size x n_heads x len_q x d_v], attn: [batch_size x n_heads x len_q(=len_k) x len_k(=len_q)]
|
85 |
+
scores ,context, attn = ScaledDotProductAttention()(q_s, k_s, v_s, attn_mask)
|
86 |
+
context = context.transpose(1, 2).contiguous().view(batch_size, -1, n_heads * d_v) # context: [batch_size x len_q x n_heads * d_v]
|
87 |
+
output = self.fc(context)
|
88 |
+
return self.norm(output + residual), attn # output: [batch_size x len_q x d_model]
|
89 |
+
|
90 |
+
class PoswiseFeedForwardNet(nn.Module):
|
91 |
+
def __init__(self):
|
92 |
+
super(PoswiseFeedForwardNet, self).__init__()
|
93 |
+
self.fc1 = nn.Linear(d_model, d_ff)
|
94 |
+
self.fc2 = nn.Linear(d_ff, d_model)
|
95 |
+
self.gelu = nn.GELU()
|
96 |
+
def forward(self, x):
|
97 |
+
# (batch_size, len_seq, d_model) -> (batch_size, len_seq, d_ff) -> (batch_size, len_seq, d_model)
|
98 |
+
return self.fc2(self.gelu(self.fc1(x)))
|
99 |
+
|
100 |
+
class EncoderLayer(nn.Module):
|
101 |
+
def __init__(self):
|
102 |
+
super(EncoderLayer, self).__init__()
|
103 |
+
self.enc_self_attn = MultiHeadAttention()
|
104 |
+
self.pos_ffn = PoswiseFeedForwardNet()
|
105 |
+
|
106 |
+
def forward(self, enc_inputs, enc_self_attn_mask):
|
107 |
+
enc_outputs, attn = self.enc_self_attn(enc_inputs, enc_inputs, enc_inputs, enc_self_attn_mask.to(enc_inputs.device)) # enc_inputs to same Q,K,V
|
108 |
+
enc_outputs = self.pos_ffn(enc_outputs) # enc_outputs: [batch_size x len_q x d_model]
|
109 |
+
return enc_outputs, attn
|
110 |
+
|
111 |
+
class FR_BERT(nn.Module):
|
112 |
+
def __init__(self):
|
113 |
+
super(FR_BERT, self).__init__()
|
114 |
+
self.embedding = Embedding()
|
115 |
+
self.layers = nn.ModuleList([EncoderLayer() for _ in range(n_layers)])
|
116 |
+
self.fc = nn.Linear(d_model, d_model)
|
117 |
+
self.activ1 = nn.Tanh()
|
118 |
+
self.linear = nn.Linear(d_model, d_model)
|
119 |
+
self.activ2 = nn.GELU()
|
120 |
+
self.norm = nn.LayerNorm(d_model)
|
121 |
+
self.classifier = nn.Linear(d_model, 2)
|
122 |
+
# decoder is shared with embedding layer
|
123 |
+
embed_weight = self.embedding.tok_embed.weight
|
124 |
+
n_vocab, n_dim = embed_weight.size()
|
125 |
+
self.decoder = nn.Linear(n_dim, n_vocab, bias=False)
|
126 |
+
self.decoder.weight = embed_weight
|
127 |
+
self.decoder_bias = nn.Parameter(torch.zeros(n_vocab))
|
128 |
+
self.mclassifier = nn.Linear(d_model, 17)
|
129 |
+
|
130 |
+
def forward(self, input_ids, segment_ids, masked_pos):
|
131 |
+
output = self.embedding(input_ids, segment_ids)
|
132 |
+
enc_self_attn_mask = get_attn_pad_mask(input_ids, input_ids).to(output.device)
|
133 |
+
for layer in self.layers:
|
134 |
+
output, enc_self_attn = layer(output, enc_self_attn_mask)
|
135 |
+
# output : [batch_size, len, d_model], attn : [batch_size, n_heads, d_mode, d_model]
|
136 |
+
# it will be decided by first token(CLS)
|
137 |
+
h_pooled = self.activ1(self.fc(output[:, 0])) # [batch_size, d_model]
|
138 |
+
logits_clsf = self.classifier(h_pooled) # [batch_size, 2]
|
139 |
+
|
140 |
+
masked_pos = masked_pos[:, :, None].expand(-1, -1, output.size(-1)) # [batch_size, max_pred, d_model]
|
141 |
+
# get masked position from final output of transformer.
|
142 |
+
h_masked = torch.gather(output, 1, masked_pos) # masking position [batch_size, max_pred, d_model]
|
143 |
+
h_masked = self.norm(self.activ2(self.linear(h_masked)))
|
144 |
+
logits_lm = self.decoder(h_masked) + self.decoder_bias # [batch_size, max_pred, n_vocab]
|
145 |
+
|
146 |
+
h_mult_sent1 = self.activ1(self.fc(output[:, 1]))
|
147 |
+
logits_mclsf1 = self.mclassifier(h_mult_sent1)
|
148 |
+
|
149 |
+
mult2_token_id = fr_mult_token_id # Assuming mult_token_id is defined globally
|
150 |
+
mult2_positions = (input_ids == mult2_token_id).nonzero(as_tuple=False) # Find positions of [MULT2] tokens
|
151 |
+
# Ensure there are exactly two [MULT] tokens in each input sequence
|
152 |
+
assert mult2_positions.size(0) == 2 * input_ids.size(0)
|
153 |
+
mult2_positions = mult2_positions[1::2][:, 1]
|
154 |
+
# Gather the hidden states corresponding to the second [MULT] token
|
155 |
+
h_mult_sent2 = output[torch.arange(output.size(0)), mult2_positions]
|
156 |
+
|
157 |
+
logits_mclsf2 = self.mclassifier(h_mult_sent2)
|
158 |
+
logits_mclsf2 = self.mclassifier(h_mult_sent2)
|
159 |
+
return logits_lm, logits_clsf , logits_mclsf1 , logits_mclsf2
|
Model.py
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
import torch
|
3 |
import torch.nn as nn
|
4 |
import numpy as np
|
5 |
-
from transformers import AutoTokenizer
|
6 |
import pickle
|
7 |
|
8 |
# Load the tokenizer
|
|
|
2 |
import torch
|
3 |
import torch.nn as nn
|
4 |
import numpy as np
|
5 |
+
from transformers import AutoTokenizer
|
6 |
import pickle
|
7 |
|
8 |
# Load the tokenizer
|
__pycache__/FrModel.cpython-310.pyc
ADDED
Binary file (6.15 kB). View file
|
|
__pycache__/Model.cpython-310.pyc
CHANGED
Binary files a/__pycache__/Model.cpython-310.pyc and b/__pycache__/Model.cpython-310.pyc differ
|
|
__pycache__/app.cpython-310.pyc
CHANGED
Binary files a/__pycache__/app.cpython-310.pyc and b/__pycache__/app.cpython-310.pyc differ
|
|
__pycache__/helper_functions.cpython-310.pyc
CHANGED
Binary files a/__pycache__/helper_functions.cpython-310.pyc and b/__pycache__/helper_functions.cpython-310.pyc differ
|
|
app.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1 |
from flask import Flask, render_template,request, redirect,url_for, jsonify , session
|
2 |
-
from helper_functions import predict_class ,
|
|
|
3 |
import fitz # PyMuPDF
|
4 |
import os, shutil
|
5 |
import torch
|
@@ -13,13 +14,21 @@ app.config['UPLOAD_FOLDER'] = 'static/uploads'
|
|
13 |
# Global variables for models
|
14 |
global_model = None
|
15 |
global_neptune = None
|
16 |
-
global_tokenizer = None
|
17 |
global_pipe = None
|
|
|
|
|
|
|
|
|
|
|
18 |
|
19 |
def init_app():
|
20 |
global global_model, global_neptune, global_pipe
|
21 |
-
print("Loading models...")
|
22 |
global_model, global_neptune, global_pipe = load_models()
|
|
|
|
|
|
|
|
|
23 |
print("Models loaded successfully!")
|
24 |
|
25 |
init_app()
|
@@ -36,11 +45,12 @@ def pdf():
|
|
36 |
predict_class = ""
|
37 |
class_probabilities = dict()
|
38 |
chart_data = dict()
|
39 |
-
|
|
|
40 |
|
41 |
@app.route('/pdf/upload' , methods = ['POST'])
|
42 |
def treatment():
|
43 |
-
global global_model,
|
44 |
if request.method == 'POST' :
|
45 |
# Récupérer le fichier PDF de la requête
|
46 |
file = request.files['file']
|
@@ -71,6 +81,10 @@ def treatment():
|
|
71 |
pdf_document.close()
|
72 |
# Prepare data for the chart
|
73 |
predicted_class , class_probabilities = predict_class([extracted_text] , global_model)
|
|
|
|
|
|
|
|
|
74 |
chart_data = {
|
75 |
'datasets': [{
|
76 |
'data': list(class_probabilities.values()),
|
@@ -81,6 +95,7 @@ def treatment():
|
|
81 |
}
|
82 |
print(predict_class)
|
83 |
print(chart_data)
|
|
|
84 |
# clear the uploads folder
|
85 |
for filename in os.listdir(app.config['UPLOAD_FOLDER']):
|
86 |
file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
|
@@ -91,14 +106,14 @@ def treatment():
|
|
91 |
shutil.rmtree(file_path)
|
92 |
except Exception as e:
|
93 |
print('Failed to delete %s. Reason: %s' % (file_path, e))
|
94 |
-
return render_template('pdf.html',extracted_text = extracted_text, class_probabilities=class_probabilities, predicted_class=predicted_class, chart_data = chart_data)
|
95 |
return render_template('pdf.html')
|
96 |
|
97 |
## Sentence
|
98 |
|
99 |
@app.route('/sentence' , methods = ['GET' , 'POST'])
|
100 |
def sentence():
|
101 |
-
global global_model
|
102 |
if request.method == 'POST':
|
103 |
# Get the form data
|
104 |
text = [request.form['text']]
|
@@ -113,16 +128,6 @@ def sentence():
|
|
113 |
'labels': [label[0] for label in class_probabilities.keys()]
|
114 |
}
|
115 |
print(chart_data)
|
116 |
-
# clear the uploads folder
|
117 |
-
for filename in os.listdir(app.config['UPLOAD_FOLDER']):
|
118 |
-
file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
|
119 |
-
try:
|
120 |
-
if os.path.isfile(file_path) or os.path.islink(file_path):
|
121 |
-
os.unlink(file_path)
|
122 |
-
elif os.path.isdir(file_path):
|
123 |
-
shutil.rmtree(file_path)
|
124 |
-
except Exception as e:
|
125 |
-
print('Failed to delete %s. Reason: %s' % (file_path, e))
|
126 |
return render_template('response_sentence.html', text=text, class_probabilities=class_probabilities, predicted_class=predicted_class,chart_data = chart_data)
|
127 |
|
128 |
# Render the initial form page
|
@@ -244,5 +249,171 @@ def slu():
|
|
244 |
chart_data={},
|
245 |
sentences_prediction={})
|
246 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
247 |
if __name__ == '__main__':
|
248 |
app.run(debug=True)
|
|
|
1 |
from flask import Flask, render_template,request, redirect,url_for, jsonify , session
|
2 |
+
from helper_functions import predict_class , inference , predict , align_predictions_with_sentences , load_models , load_fr_models
|
3 |
+
from helper_functions import predict_fr_class, fr_inference , align_fr_predictions_with_sentences
|
4 |
import fitz # PyMuPDF
|
5 |
import os, shutil
|
6 |
import torch
|
|
|
14 |
# Global variables for models
|
15 |
global_model = None
|
16 |
global_neptune = None
|
|
|
17 |
global_pipe = None
|
18 |
+
global_fr_model = None
|
19 |
+
global_fr_neptune = None
|
20 |
+
global_fr_pipe = None
|
21 |
+
|
22 |
+
|
23 |
|
24 |
def init_app():
|
25 |
global global_model, global_neptune, global_pipe
|
26 |
+
print("Loading English models...")
|
27 |
global_model, global_neptune, global_pipe = load_models()
|
28 |
+
|
29 |
+
global global_fr_model, global_fr_neptune, global_fr_pipe
|
30 |
+
print("Loading French models...")
|
31 |
+
global_fr_model , global_fr_neptune , global_fr_pipe = load_fr_models()
|
32 |
print("Models loaded successfully!")
|
33 |
|
34 |
init_app()
|
|
|
45 |
predict_class = ""
|
46 |
class_probabilities = dict()
|
47 |
chart_data = dict()
|
48 |
+
sentences_prediction = dict()
|
49 |
+
return render_template('pdf.html', class_probabilities= class_probabilities, predicted_class=predict_class,chart_data = chart_data,sentences_prediction=sentences_prediction)
|
50 |
|
51 |
@app.route('/pdf/upload' , methods = ['POST'])
|
52 |
def treatment():
|
53 |
+
global global_model , global_neptune
|
54 |
if request.method == 'POST' :
|
55 |
# Récupérer le fichier PDF de la requête
|
56 |
file = request.files['file']
|
|
|
81 |
pdf_document.close()
|
82 |
# Prepare data for the chart
|
83 |
predicted_class , class_probabilities = predict_class([extracted_text] , global_model)
|
84 |
+
# Process the transcribed text
|
85 |
+
inference_batch, sentences = inference(extracted_text)
|
86 |
+
predictions = predict(inference_batch, global_neptune)
|
87 |
+
sentences_prediction = align_predictions_with_sentences(sentences, predictions)
|
88 |
chart_data = {
|
89 |
'datasets': [{
|
90 |
'data': list(class_probabilities.values()),
|
|
|
95 |
}
|
96 |
print(predict_class)
|
97 |
print(chart_data)
|
98 |
+
print(sentences_prediction)
|
99 |
# clear the uploads folder
|
100 |
for filename in os.listdir(app.config['UPLOAD_FOLDER']):
|
101 |
file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
|
|
|
106 |
shutil.rmtree(file_path)
|
107 |
except Exception as e:
|
108 |
print('Failed to delete %s. Reason: %s' % (file_path, e))
|
109 |
+
return render_template('pdf.html',extracted_text = extracted_text, class_probabilities=class_probabilities, predicted_class=predicted_class, chart_data = chart_data,sentences_prediction=sentences_prediction)
|
110 |
return render_template('pdf.html')
|
111 |
|
112 |
## Sentence
|
113 |
|
114 |
@app.route('/sentence' , methods = ['GET' , 'POST'])
|
115 |
def sentence():
|
116 |
+
global global_model
|
117 |
if request.method == 'POST':
|
118 |
# Get the form data
|
119 |
text = [request.form['text']]
|
|
|
128 |
'labels': [label[0] for label in class_probabilities.keys()]
|
129 |
}
|
130 |
print(chart_data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
return render_template('response_sentence.html', text=text, class_probabilities=class_probabilities, predicted_class=predicted_class,chart_data = chart_data)
|
132 |
|
133 |
# Render the initial form page
|
|
|
249 |
chart_data={},
|
250 |
sentences_prediction={})
|
251 |
|
252 |
+
## French Pages
|
253 |
+
@app.route('/pdf_fr')
|
254 |
+
def pdf_fr():
|
255 |
+
predict_class = ""
|
256 |
+
class_probabilities = dict()
|
257 |
+
chart_data = dict()
|
258 |
+
return render_template('pdf_fr.html', class_probabilities= class_probabilities, predicted_class=predict_class,chart_data = chart_data)
|
259 |
+
|
260 |
+
@app.route('/pdf_fr/upload' , methods = ['POST'])
|
261 |
+
def treatment_fr():
|
262 |
+
global global_fr_neptune
|
263 |
+
if request.method == 'POST' :
|
264 |
+
# Récupérer le fichier PDF de la requête
|
265 |
+
file = request.files['file']
|
266 |
+
filename = file.filename
|
267 |
+
|
268 |
+
# Enregistrer le fichier dans le répertoire de téléchargement
|
269 |
+
filepath = app.config['UPLOAD_FOLDER'] + "/" + filename
|
270 |
+
file.save(filepath)
|
271 |
+
|
272 |
+
# Ouvrir le fichier PDF
|
273 |
+
pdf_document = fitz.open(filepath)
|
274 |
+
|
275 |
+
# Initialiser une variable pour stocker le texte extrait
|
276 |
+
extracted_text = ""
|
277 |
+
|
278 |
+
# Boucler à travers chaque page pour extraire le texte
|
279 |
+
for page_num in range(len(pdf_document)):
|
280 |
+
# Récupérer l'objet de la page
|
281 |
+
page = pdf_document.load_page(page_num)
|
282 |
+
|
283 |
+
# Extraire le texte de la page
|
284 |
+
page_text = page.get_text()
|
285 |
+
|
286 |
+
# Ajouter le texte de la page à la variable d'extraction
|
287 |
+
extracted_text += f"\nPage {page_num + 1}:\n{page_text}"
|
288 |
+
|
289 |
+
# Fermer le fichier PDF
|
290 |
+
pdf_document.close()
|
291 |
+
# Process the text
|
292 |
+
inference_batch, sentences = fr_inference(extracted_text)
|
293 |
+
predictions = predict(inference_batch, global_fr_neptune)
|
294 |
+
sentences_prediction = align_fr_predictions_with_sentences(sentences, predictions)
|
295 |
+
# Prepare data for the chart
|
296 |
+
predicted_class , class_probabilities = predict_fr_class([extracted_text] , global_fr_model)
|
297 |
+
|
298 |
+
chart_data = {
|
299 |
+
'datasets': [{
|
300 |
+
'data': list(class_probabilities.values()),
|
301 |
+
'backgroundColor': [color[2] for color in class_probabilities.keys()],
|
302 |
+
'borderColor': [color[2] for color in class_probabilities.keys()]
|
303 |
+
}],
|
304 |
+
'labels': [label[0] for label in class_probabilities.keys()]
|
305 |
+
}
|
306 |
+
print(predict_class)
|
307 |
+
print(chart_data)
|
308 |
+
# clear the uploads folder
|
309 |
+
for filename in os.listdir(app.config['UPLOAD_FOLDER']):
|
310 |
+
file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
|
311 |
+
try:
|
312 |
+
if os.path.isfile(file_path) or os.path.islink(file_path):
|
313 |
+
os.unlink(file_path)
|
314 |
+
elif os.path.isdir(file_path):
|
315 |
+
shutil.rmtree(file_path)
|
316 |
+
except Exception as e:
|
317 |
+
print('Failed to delete %s. Reason: %s' % (file_path, e))
|
318 |
+
return render_template('pdf_fr.html',extracted_text = extracted_text, class_probabilities=class_probabilities, predicted_class=predicted_class, chart_data = chart_data, sentences_prediction=sentences_prediction)
|
319 |
+
return render_template('pdf_fr.html')
|
320 |
+
|
321 |
+
@app.route('/sentence_fr' , methods = ['GET' , 'POST'])
|
322 |
+
def sentence_fr():
|
323 |
+
global global_fr_model
|
324 |
+
if request.method == 'POST':
|
325 |
+
# Get the form data
|
326 |
+
text = [request.form['text']]
|
327 |
+
predicted_class , class_probabilities = predict_fr_class(text , global_fr_model)
|
328 |
+
# Prepare data for the chart
|
329 |
+
chart_data = {
|
330 |
+
'datasets': [{
|
331 |
+
'data': list(class_probabilities.values()),
|
332 |
+
'backgroundColor': [color[2 ] for color in class_probabilities.keys()],
|
333 |
+
'borderColor': [color[2] for color in class_probabilities.keys()]
|
334 |
+
}],
|
335 |
+
'labels': [label[0] for label in class_probabilities.keys()]
|
336 |
+
}
|
337 |
+
print(predicted_class)
|
338 |
+
print(chart_data)
|
339 |
+
return render_template('response_fr_sentence.html', text=text, class_probabilities=class_probabilities, predicted_class=predicted_class,chart_data = chart_data)
|
340 |
+
|
341 |
+
# Render the initial form page
|
342 |
+
return render_template('sentence_fr.html')
|
343 |
+
|
344 |
+
@app.route("/voice_fr", methods=['GET', 'POST'])
|
345 |
+
def slu_fr():
|
346 |
+
global global_fr_neptune, global_fr_pipe, global_fr_model
|
347 |
+
|
348 |
+
if request.method == 'POST':
|
349 |
+
logging.debug("Received POST request")
|
350 |
+
audio_file = request.files.get('audio')
|
351 |
+
|
352 |
+
if audio_file:
|
353 |
+
logging.debug(f"Received audio file: {audio_file.filename}")
|
354 |
+
|
355 |
+
# Save audio data to a temporary file
|
356 |
+
with tempfile.NamedTemporaryFile(delete=False, suffix='.wav') as temp_audio:
|
357 |
+
audio_file.save(temp_audio)
|
358 |
+
temp_audio_path = temp_audio.name
|
359 |
+
|
360 |
+
logging.debug(f"Saved audio to temporary file: {temp_audio_path}")
|
361 |
+
|
362 |
+
try:
|
363 |
+
# Transcribe audio using Whisper
|
364 |
+
result = global_fr_pipe(temp_audio_path)
|
365 |
+
extracted_text = result["text"]
|
366 |
+
logging.debug(f"Transcribed text: {extracted_text}")
|
367 |
+
|
368 |
+
# Process the transcribed text
|
369 |
+
inference_batch, sentences = fr_inference(extracted_text)
|
370 |
+
predictions = predict(inference_batch, global_fr_neptune)
|
371 |
+
sentences_prediction = align_fr_predictions_with_sentences(sentences, predictions)
|
372 |
+
predicted_class, class_probabilities = predict_fr_class([extracted_text], global_fr_model)
|
373 |
+
|
374 |
+
chart_data = {
|
375 |
+
'datasets': [{
|
376 |
+
'data': list(class_probabilities.values()),
|
377 |
+
'backgroundColor': [color[2] for color in class_probabilities.keys()],
|
378 |
+
'borderColor': [color[2] for color in class_probabilities.keys()]
|
379 |
+
}],
|
380 |
+
'labels': [label[0] for label in class_probabilities.keys()]
|
381 |
+
}
|
382 |
+
|
383 |
+
response_data = {
|
384 |
+
'extracted_text': extracted_text,
|
385 |
+
'class_probabilities' : class_probabilities,
|
386 |
+
'predicted_class': predicted_class,
|
387 |
+
'chart_data': chart_data,
|
388 |
+
'sentences_prediction': sentences_prediction
|
389 |
+
}
|
390 |
+
logging.debug(f"Prepared response data: {response_data}")
|
391 |
+
|
392 |
+
return render_template('voice_fr.html',
|
393 |
+
class_probabilities= class_probabilities,
|
394 |
+
predicted_class= predicted_class,
|
395 |
+
chart_data= chart_data,
|
396 |
+
sentences_prediction=sentences_prediction)
|
397 |
+
|
398 |
+
except Exception as e:
|
399 |
+
logging.error(f"Error processing audio: {str(e)}")
|
400 |
+
return jsonify({'error': str(e)}), 500
|
401 |
+
|
402 |
+
finally:
|
403 |
+
# Remove temporary file
|
404 |
+
os.unlink(temp_audio_path)
|
405 |
+
|
406 |
+
else:
|
407 |
+
logging.error("No audio file received")
|
408 |
+
return jsonify({'error': 'No audio file received'}), 400
|
409 |
+
|
410 |
+
# For GET request
|
411 |
+
logging.debug("Received GET request")
|
412 |
+
return render_template('voice_fr.html',
|
413 |
+
class_probabilities={},
|
414 |
+
predicted_class=[""],
|
415 |
+
chart_data={},
|
416 |
+
sentences_prediction={})
|
417 |
+
|
418 |
if __name__ == '__main__':
|
419 |
app.run(debug=True)
|
fr_neptune/fr_neptune/added_tokens.json
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"<MULT>": 32006,
|
3 |
+
"<unk>NOTUSED": 32005
|
4 |
+
}
|
fr_neptune/fr_neptune/model.pt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:bd05f03e109cff6f56e6508f8e281da9c608e707bf967fd524f5a5c0771db112
|
3 |
+
size 274139674
|
fr_neptune/fr_neptune/sentencepiece.bpe.model
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:988bc5a00281c6d210a5d34bd143d0363741a432fefe741bf71e61b1869d4314
|
3 |
+
size 810912
|
fr_neptune/fr_neptune/special_tokens_map.json
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"additional_special_tokens": [
|
3 |
+
{
|
4 |
+
"content": "<MULT>",
|
5 |
+
"lstrip": false,
|
6 |
+
"normalized": false,
|
7 |
+
"rstrip": false,
|
8 |
+
"single_word": false
|
9 |
+
}
|
10 |
+
],
|
11 |
+
"bos_token": "<s>",
|
12 |
+
"cls_token": "<s>",
|
13 |
+
"eos_token": "</s>",
|
14 |
+
"mask_token": {
|
15 |
+
"content": "<mask>",
|
16 |
+
"lstrip": true,
|
17 |
+
"normalized": false,
|
18 |
+
"rstrip": false,
|
19 |
+
"single_word": false
|
20 |
+
},
|
21 |
+
"pad_token": "<pad>",
|
22 |
+
"sep_token": "</s>",
|
23 |
+
"unk_token": "<unk>"
|
24 |
+
}
|
fr_neptune/fr_neptune/tokenizer.json
ADDED
The diff for this file is too large to render.
See raw diff
|
|
fr_neptune/fr_neptune/tokenizer_config.json
ADDED
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"added_tokens_decoder": {
|
3 |
+
"0": {
|
4 |
+
"content": "<s>NOTUSED",
|
5 |
+
"lstrip": false,
|
6 |
+
"normalized": false,
|
7 |
+
"rstrip": false,
|
8 |
+
"single_word": false,
|
9 |
+
"special": true
|
10 |
+
},
|
11 |
+
"1": {
|
12 |
+
"content": "<pad>",
|
13 |
+
"lstrip": false,
|
14 |
+
"normalized": false,
|
15 |
+
"rstrip": false,
|
16 |
+
"single_word": false,
|
17 |
+
"special": true
|
18 |
+
},
|
19 |
+
"2": {
|
20 |
+
"content": "</s>NOTUSED",
|
21 |
+
"lstrip": false,
|
22 |
+
"normalized": false,
|
23 |
+
"rstrip": false,
|
24 |
+
"single_word": false,
|
25 |
+
"special": true
|
26 |
+
},
|
27 |
+
"4": {
|
28 |
+
"content": "<unk>",
|
29 |
+
"lstrip": false,
|
30 |
+
"normalized": false,
|
31 |
+
"rstrip": false,
|
32 |
+
"single_word": false,
|
33 |
+
"special": true
|
34 |
+
},
|
35 |
+
"5": {
|
36 |
+
"content": "<s>",
|
37 |
+
"lstrip": false,
|
38 |
+
"normalized": false,
|
39 |
+
"rstrip": false,
|
40 |
+
"single_word": false,
|
41 |
+
"special": true
|
42 |
+
},
|
43 |
+
"6": {
|
44 |
+
"content": "</s>",
|
45 |
+
"lstrip": false,
|
46 |
+
"normalized": false,
|
47 |
+
"rstrip": false,
|
48 |
+
"single_word": false,
|
49 |
+
"special": true
|
50 |
+
},
|
51 |
+
"32004": {
|
52 |
+
"content": "<mask>",
|
53 |
+
"lstrip": true,
|
54 |
+
"normalized": false,
|
55 |
+
"rstrip": false,
|
56 |
+
"single_word": false,
|
57 |
+
"special": true
|
58 |
+
},
|
59 |
+
"32005": {
|
60 |
+
"content": "<unk>NOTUSED",
|
61 |
+
"lstrip": false,
|
62 |
+
"normalized": false,
|
63 |
+
"rstrip": false,
|
64 |
+
"single_word": false,
|
65 |
+
"special": true
|
66 |
+
},
|
67 |
+
"32006": {
|
68 |
+
"content": "<MULT>",
|
69 |
+
"lstrip": false,
|
70 |
+
"normalized": false,
|
71 |
+
"rstrip": false,
|
72 |
+
"single_word": false,
|
73 |
+
"special": true
|
74 |
+
}
|
75 |
+
},
|
76 |
+
"additional_special_tokens": [
|
77 |
+
"<MULT>"
|
78 |
+
],
|
79 |
+
"bos_token": "<s>",
|
80 |
+
"clean_up_tokenization_spaces": true,
|
81 |
+
"cls_token": "<s>",
|
82 |
+
"eos_token": "</s>",
|
83 |
+
"mask_token": "<mask>",
|
84 |
+
"model_max_length": 512,
|
85 |
+
"pad_token": "<pad>",
|
86 |
+
"sep_token": "</s>",
|
87 |
+
"tokenizer_class": "CamembertTokenizer",
|
88 |
+
"unk_token": "<unk>"
|
89 |
+
}
|
fr_neptune/fr_neptune/unique_labels.json
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
["Physics", "ai", "economies", "environments", "sports", "technologies"]
|
helper_functions.py
CHANGED
@@ -1,13 +1,15 @@
|
|
1 |
import torch
|
2 |
import pickle
|
3 |
-
from transformers import AutoTokenizer , DistilBertForSequenceClassification
|
4 |
from transformers import BatchEncoding, PreTrainedTokenizerBase
|
5 |
from typing import Optional
|
6 |
from torch import Tensor
|
7 |
import numpy as np
|
8 |
from random import shuffle
|
9 |
from Model import BERT
|
|
|
10 |
from Model import tokenizer , mult_token_id , cls_token_id , pad_token_id , max_pred , maxlen , sep_token_id
|
|
|
11 |
from transformers import pipeline
|
12 |
|
13 |
device = "cpu"
|
@@ -37,6 +39,28 @@ def load_models():
|
|
37 |
|
38 |
return model, neptune, pipe
|
39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
class_labels = {
|
41 |
16: ('vehicles','info' , '#4f9ef8'),
|
42 |
10: ('environments','success' , '#0cbc87'),
|
@@ -333,4 +357,189 @@ def align_predictions_with_sentences(sentences, preds):
|
|
333 |
dc = {} # Initialize an empty dictionary
|
334 |
for sentence, pred in zip(sentences, preds): # Iterate through sentences and predictions
|
335 |
dc[sentence] = class_labels.get(pred, "Unknown") # Look up the label for each prediction
|
336 |
-
return dc
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import torch
|
2 |
import pickle
|
3 |
+
from transformers import AutoTokenizer , DistilBertForSequenceClassification , CamembertForSequenceClassification
|
4 |
from transformers import BatchEncoding, PreTrainedTokenizerBase
|
5 |
from typing import Optional
|
6 |
from torch import Tensor
|
7 |
import numpy as np
|
8 |
from random import shuffle
|
9 |
from Model import BERT
|
10 |
+
from FrModel import FR_BERT
|
11 |
from Model import tokenizer , mult_token_id , cls_token_id , pad_token_id , max_pred , maxlen , sep_token_id
|
12 |
+
from FrModel import fr_tokenizer , fr_mult_token_id , fr_cls_token_id , fr_pad_token_id , fr_sep_token_id
|
13 |
from transformers import pipeline
|
14 |
|
15 |
device = "cpu"
|
|
|
39 |
|
40 |
return model, neptune, pipe
|
41 |
|
42 |
+
def load_fr_models():
|
43 |
+
print("Loading Camembert model")
|
44 |
+
fr_model = CamembertForSequenceClassification.from_pretrained("Camembert/Camembert/saved_model")
|
45 |
+
print("Loading BERT model...")
|
46 |
+
fr_neptune = FR_BERT()
|
47 |
+
device = "cpu"
|
48 |
+
model_save_path = "fr_neptune/fr_neptune/model.pt"
|
49 |
+
fr_neptune.load_state_dict(torch.load(model_save_path, map_location=torch.device('cpu')))
|
50 |
+
fr_neptune.to(device)
|
51 |
+
print("Loading speech recognition pipeline...")
|
52 |
+
pipe = pipeline(
|
53 |
+
"automatic-speech-recognition",
|
54 |
+
model="openai/whisper-tiny.en",
|
55 |
+
chunk_length_s=30,
|
56 |
+
device=device,
|
57 |
+
)
|
58 |
+
print(pipe)
|
59 |
+
return fr_model , fr_neptune , pipe
|
60 |
+
|
61 |
+
fr_class_labels = {0: ('Physics', 'primary', '#0f6fec'), 1: ('AI','cyan', '#0dcaf0'),
|
62 |
+
2: ('economies', 'warning' , '#f7c32e'), 3: ('environments','success' , '#0cbc87'),
|
63 |
+
4: ('sports', 'orange', '#fd7e14')}
|
64 |
class_labels = {
|
65 |
16: ('vehicles','info' , '#4f9ef8'),
|
66 |
10: ('environments','success' , '#0cbc87'),
|
|
|
357 |
dc = {} # Initialize an empty dictionary
|
358 |
for sentence, pred in zip(sentences, preds): # Iterate through sentences and predictions
|
359 |
dc[sentence] = class_labels.get(pred, "Unknown") # Look up the label for each prediction
|
360 |
+
return dc
|
361 |
+
|
362 |
+
#### FRENCH PREPROCESSING ####
|
363 |
+
def predict_fr_class(text , model):
|
364 |
+
# Tokenisation du texte
|
365 |
+
inputs = transform_list_of_fr_texts(text, fr_tokenizer, 126, 30, 1, 2550)
|
366 |
+
# Extraire le tenseur de la liste
|
367 |
+
input_ids_tensor = inputs["input_ids"][0]
|
368 |
+
attention_mask_tensor = inputs["attention_mask"][0]
|
369 |
+
# Passage du texte à travers le modèle
|
370 |
+
with torch.no_grad():
|
371 |
+
outputs = model(input_ids=input_ids_tensor, attention_mask=attention_mask_tensor)
|
372 |
+
|
373 |
+
# Application de la fonction softmax
|
374 |
+
probabilities = torch.softmax(outputs.logits, dim=1)[0]
|
375 |
+
|
376 |
+
# Identification de la classe majoritaire
|
377 |
+
predicted_class_index = torch.argmax(probabilities).item()
|
378 |
+
predicted_class = fr_class_labels[predicted_class_index]
|
379 |
+
|
380 |
+
# Créer un dictionnaire de pourcentages trié par probabilité
|
381 |
+
sorted_percentages = {fr_class_labels[idx]: probabilities[idx].item() * 100 for idx in range(len(fr_class_labels))}
|
382 |
+
sorted_percentages = dict(sorted(sorted_percentages.items(), key=lambda item: item[1], reverse=True))
|
383 |
+
|
384 |
+
return predicted_class, sorted_percentages
|
385 |
+
|
386 |
+
def prepare_fr_text(tokens_splitted: BatchEncoding):
|
387 |
+
batch = []
|
388 |
+
sentences = []
|
389 |
+
input_ids_list = tokens_splitted['input_ids']
|
390 |
+
|
391 |
+
for i in range(0, len(input_ids_list), 2): # Adjust loop to stop at second last index
|
392 |
+
k = i + 1
|
393 |
+
if k == len(input_ids_list):
|
394 |
+
input_ids_a = input_ids_list[i]
|
395 |
+
input_ids_a = [token for token in input_ids_a.view(-1).tolist() if token != pad_token_id]
|
396 |
+
input_ids_b = []
|
397 |
+
input_ids = [fr_cls_token_id] + [fr_mult_token_id] + input_ids_a + [fr_sep_token_id] + [fr_mult_token_id] + input_ids_b + [fr_sep_token_id]
|
398 |
+
text_input_a = fr_tokenizer.decode(input_ids_a)
|
399 |
+
sentences.append(text_input_a)
|
400 |
+
segment_ids = [0] * (1 + 1 + len(input_ids_a) + 1) + [1] * (1 + len(input_ids_b) + 1)
|
401 |
+
|
402 |
+
# MASK LM
|
403 |
+
n_pred = min(max_pred, max(1, int(round(len(input_ids) * 0.15))))
|
404 |
+
cand_masked_pos = [idx for idx, token in enumerate(input_ids) if token not in [fr_cls_token_id, fr_sep_token_id, fr_mult_token_id]]
|
405 |
+
shuffle(cand_masked_pos)
|
406 |
+
masked_tokens, masked_pos = [], []
|
407 |
+
for pos in cand_masked_pos[:n_pred]:
|
408 |
+
masked_pos.append(pos)
|
409 |
+
masked_tokens.append(input_ids[pos])
|
410 |
+
input_ids[pos] = fr_tokenizer.mask_token_id
|
411 |
+
|
412 |
+
# Zero Padding
|
413 |
+
n_pad = maxlen - len(input_ids)
|
414 |
+
input_ids.extend([fr_pad_token_id] * n_pad)
|
415 |
+
segment_ids.extend([0] * n_pad)
|
416 |
+
|
417 |
+
# Zero Padding for masked tokens
|
418 |
+
if max_pred > n_pred:
|
419 |
+
n_pad = max_pred - n_pred
|
420 |
+
masked_tokens.extend([0] * n_pad)
|
421 |
+
masked_pos.extend([0] * n_pad)
|
422 |
+
else:
|
423 |
+
input_ids_a = input_ids_list[i] # Correct the indexing here
|
424 |
+
input_ids_b = input_ids_list[k] # Correct the indexing here
|
425 |
+
input_ids_a = [token for token in input_ids_a.view(-1).tolist() if token != pad_token_id]
|
426 |
+
input_ids_b = [token for token in input_ids_b.view(-1).tolist() if token != pad_token_id]
|
427 |
+
input_ids = [fr_cls_token_id] + [fr_mult_token_id] + input_ids_a + [fr_sep_token_id] + [fr_mult_token_id] + input_ids_b + [fr_sep_token_id]
|
428 |
+
segment_ids = [0] * (1 + 1 + len(input_ids_a) + 1) + [1] * (1 + len(input_ids_b) + 1)
|
429 |
+
text_input_a = fr_tokenizer.decode(input_ids_a)
|
430 |
+
text_input_b = fr_tokenizer.decode(input_ids_b)
|
431 |
+
sentences.append(text_input_a)
|
432 |
+
sentences.append(text_input_b)
|
433 |
+
|
434 |
+
# MASK LM
|
435 |
+
n_pred = min(max_pred, max(1, int(round(len(input_ids) * 0.15))))
|
436 |
+
cand_masked_pos = [idx for idx, token in enumerate(input_ids) if token not in [fr_cls_token_id, fr_sep_token_id, fr_mult_token_id]]
|
437 |
+
shuffle(cand_masked_pos)
|
438 |
+
masked_tokens, masked_pos = [], []
|
439 |
+
for pos in cand_masked_pos[:n_pred]:
|
440 |
+
masked_pos.append(pos)
|
441 |
+
masked_tokens.append(input_ids[pos])
|
442 |
+
input_ids[pos] = fr_tokenizer.mask_token_id
|
443 |
+
|
444 |
+
# Zero Padding
|
445 |
+
n_pad = maxlen - len(input_ids)
|
446 |
+
input_ids.extend([fr_pad_token_id] * n_pad)
|
447 |
+
segment_ids.extend([0] * n_pad)
|
448 |
+
|
449 |
+
# Zero Padding for masked tokens
|
450 |
+
if max_pred > n_pred:
|
451 |
+
n_pad = max_pred - n_pred
|
452 |
+
masked_tokens.extend([0] * n_pad)
|
453 |
+
masked_pos.extend([0] * n_pad)
|
454 |
+
|
455 |
+
batch.append([input_ids, segment_ids, masked_pos])
|
456 |
+
return batch, sentences
|
457 |
+
|
458 |
+
def fr_inference(text: str):
|
459 |
+
encoded_text = transform_for_inference_fr_text(text, fr_tokenizer, 125, 125, 1, 2550)
|
460 |
+
batch, sentences = prepare_fr_text(encoded_text)
|
461 |
+
return batch, sentences
|
462 |
+
|
463 |
+
def align_fr_predictions_with_sentences(sentences, preds):
|
464 |
+
dc = {} # Initialize an empty dictionary
|
465 |
+
for sentence, pred in zip(sentences, preds): # Iterate through sentences and predictions
|
466 |
+
dc[sentence] = fr_class_labels.get(pred, "Unknown") # Look up the label for each prediction
|
467 |
+
return dc
|
468 |
+
|
469 |
+
def transform_for_inference_fr_text(text: str,
|
470 |
+
tokenizer: PreTrainedTokenizerBase,
|
471 |
+
chunk_size: int,
|
472 |
+
stride: int,
|
473 |
+
minimal_chunk_length: int,
|
474 |
+
maximal_text_length: Optional[int],) -> BatchEncoding:
|
475 |
+
if maximal_text_length:
|
476 |
+
tokens = tokenize_text_with_truncation(text, tokenizer, maximal_text_length)
|
477 |
+
else:
|
478 |
+
tokens = tokenize_whole_text(text, tokenizer)
|
479 |
+
input_id_chunks, mask_chunks = split_tokens_into_smaller_chunks(tokens, chunk_size, stride, minimal_chunk_length)
|
480 |
+
add_special_tokens_at_beginning_and_end_inference(input_id_chunks, mask_chunks)
|
481 |
+
add_padding_fr_tokens_inference(input_id_chunks, mask_chunks, chunk_size)
|
482 |
+
input_ids, attention_mask = stack_tokens_from_all_chunks_for_inference(input_id_chunks, mask_chunks)
|
483 |
+
return {"input_ids": input_ids, "attention_mask": attention_mask}
|
484 |
+
|
485 |
+
def add_padding_fr_tokens_inference(input_id_chunks: list[Tensor], mask_chunks: list[Tensor], chunk_size: int) -> None:
|
486 |
+
"""Adds padding tokens at the end to make sure that all chunks have exactly chunk_size tokens."""
|
487 |
+
pad_token_id = 1 # Assuming this is defined somewhere in your code
|
488 |
+
for i in range(len(input_id_chunks)):
|
489 |
+
# get required padding length
|
490 |
+
pad_len = chunk_size - input_id_chunks[i].shape[0]
|
491 |
+
# check if tensor length satisfies required chunk size
|
492 |
+
if pad_len > 0:
|
493 |
+
# if padding length is more than 0, we must add padding
|
494 |
+
input_id_chunks[i] = torch.cat([input_id_chunks[i], torch.tensor([pad_token_id] * pad_len)])
|
495 |
+
mask_chunks[i] = torch.cat([mask_chunks[i], torch.tensor([0] * pad_len)])
|
496 |
+
|
497 |
+
|
498 |
+
def transform_list_of_fr_texts(
|
499 |
+
texts: list[str],
|
500 |
+
tokenizer: PreTrainedTokenizerBase,
|
501 |
+
chunk_size: int,
|
502 |
+
stride: int,
|
503 |
+
minimal_chunk_length: int,
|
504 |
+
maximal_text_length: Optional[int] = None,
|
505 |
+
) -> BatchEncoding:
|
506 |
+
model_inputs = [
|
507 |
+
transform_single_fr_text(text, tokenizer, chunk_size, stride, minimal_chunk_length, maximal_text_length)
|
508 |
+
for text in texts
|
509 |
+
]
|
510 |
+
input_ids = [model_input[0] for model_input in model_inputs]
|
511 |
+
attention_mask = [model_input[1] for model_input in model_inputs]
|
512 |
+
tokens = {"input_ids": input_ids, "attention_mask": attention_mask}
|
513 |
+
return BatchEncoding(tokens)
|
514 |
+
|
515 |
+
|
516 |
+
def transform_single_fr_text(
|
517 |
+
text: str,
|
518 |
+
tokenizer: PreTrainedTokenizerBase,
|
519 |
+
chunk_size: int,
|
520 |
+
stride: int,
|
521 |
+
minimal_chunk_length: int,
|
522 |
+
maximal_text_length: Optional[int],
|
523 |
+
) -> tuple[Tensor, Tensor]:
|
524 |
+
"""Transforms (the entire) text to model input of BERT model."""
|
525 |
+
if maximal_text_length:
|
526 |
+
tokens = tokenize_text_with_truncation(text, tokenizer, maximal_text_length)
|
527 |
+
else:
|
528 |
+
tokens = tokenize_whole_text(text, tokenizer)
|
529 |
+
input_id_chunks, mask_chunks = split_tokens_into_smaller_chunks(tokens, chunk_size, stride, minimal_chunk_length)
|
530 |
+
add_fr_special_tokens_at_beginning_and_end(input_id_chunks, mask_chunks)
|
531 |
+
add_padding_tokens(input_id_chunks, mask_chunks , chunk_size)
|
532 |
+
input_ids, attention_mask = stack_tokens_from_all_chunks(input_id_chunks, mask_chunks)
|
533 |
+
return input_ids, attention_mask
|
534 |
+
|
535 |
+
def add_fr_special_tokens_at_beginning_and_end(input_id_chunks: list[Tensor], mask_chunks: list[Tensor]) -> None:
|
536 |
+
"""
|
537 |
+
Adds special CLS token (token id = 101) at the beginning.
|
538 |
+
Adds SEP token (token id = 102) at the end of each chunk.
|
539 |
+
Adds corresponding attention masks equal to 1 (attention mask is boolean).
|
540 |
+
"""
|
541 |
+
for i in range(len(input_id_chunks)):
|
542 |
+
# adding CLS (token id 101) and SEP (token id 102) tokens
|
543 |
+
input_id_chunks[i] = torch.cat([Tensor([5]), input_id_chunks[i], Tensor([6])])
|
544 |
+
# adding attention masks corresponding to special tokens
|
545 |
+
mask_chunks[i] = torch.cat([Tensor([1]), mask_chunks[i], Tensor([1])])
|
static/icons/English.svg
ADDED
static/icons/France.svg
ADDED
static/icons/flag-for-flag-france.htm
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><link rel="icon" href="/favicon.ico"/><link rel="search" href="/opensearch.xml" type="application/opensearchdescription+xml" title="SVG Repo"/><script type="application/ld+json">[{"@context":"http://schema.org","@type":"WebSite","url":"https://www.svgrepo.com/","name":"SVG Repo - Free SVG Vectors and Icons","alternateName":"Free SVG Icons","potentialAction":{"@type":"SearchAction","target":"http://www.svgrepo.com/vectors/{search_term_string}/","query-input":"required name=search_term_string"}},{"@context":"http://schema.org","@type":"Organization","name":"SVG Repo","legalName":"SVG Repo LLC","foundingDate":"2013","url":"https://www.svgrepo.com","logo":"https://www.svgrepo.com/logo.png","founders":[{"@type":"Person","name":"Burak Tokak"}],"address":{"@type":"PostalAddress","streetAddress":"123 Genting Lane","addressLocality":"Yenom","addressRegion":"SG","postalCode":"24","addressCountry":"Singapore"},"contactPoint":{"@type":"ContactPoint","contactType":"Support","telephone":"[+561-526-8457]","email":"info@svgrepo.com"},"sameAs":["http://www.twitter.com/svgrepo","http://www.instagram.com/svgrepo","http://www.facebook.com/svgrepo","https://www.producthunt.com/products/svgrepo","https://dribbble.com/svgrepo"]},{"@context":"http://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"https://www.svgrepo.com/","name":"Home"}},{"@type":"ListItem","position":2,"item":{"@id":"https://www.svgrepo.com/collections/","name":"SVG Vector"}},{"@type":"ListItem","position":3,"item":{"@id":"https://www.svgrepo.com/svg/405485/flag-for-flag-france","name":"Flag For Flag France"}}]}]</script><title>Flag For Flag France Vector SVG Icon - SVG Repo</title><meta name="robots" content="index,follow,max-image-preview:large"/><meta name="googlebot" content="index,follow,max-image-preview:large"/><meta name="description" content="Free Flag For Flag France Vector Icon in SVG format. ✅ Download Free Flag For Flag France Vector and icons for commercial use. Flag For Flag France SVG vector illustration graphic art design format.SVG Vector vectors."/><meta name="twitter:card" content="summary_large_image"/><meta name="twitter:site" content="@svgrepo"/><meta name="twitter:creator" content="@svgrepo"/><meta property="og:title" content="Flag For Flag France Vector SVG Icon - SVG Repo"/><meta property="og:description" content="Free Flag For Flag France Vector Icon in SVG format. ✅ Download Free Flag For Flag France Vector and icons for commercial use. Flag For Flag France SVG vector illustration graphic art design format.SVG Vector vectors."/><meta property="og:url" content="https://www.svgrepo.com/svg/405485/flag-for-flag-france"/><meta property="og:image" content="https://www.svgrepo.com/social.png"/><meta property="og:image:alt" content=" Free Icons and Vectors"/><meta property="og:image:type" content="image/png"/><meta property="og:image:width" content="1600"/><meta property="og:image:height" content="800"/><meta property="og:site_name" content="SVG Repo"/><link rel="canonical" href="https://www.svgrepo.com/svg/405485/flag-for-flag-france"/><link rel="preload" href="/show/405485/flag-for-flag-france.svg" as="image" fetchpriority="high"/><meta name="next-head-count" content="23"/><meta name="next-font-preconnect"/><link rel="preload" href="/_next/static/media/c9a5bc6a7c948fb0-s.p.woff2" as="font" type="font/woff2" crossorigin="anonymous" data-next-font="size-adjust"/><link rel="preload" href="/_next/static/css/c9f2e23721645114.css" as="style"/><link rel="stylesheet" href="/_next/static/css/c9f2e23721645114.css" data-n-g=""/><link rel="preload" href="/_next/static/css/b4b0348ba0c97866.css" as="style"/><link rel="stylesheet" href="/_next/static/css/b4b0348ba0c97866.css" data-n-p=""/><link rel="preload" href="/_next/static/css/fb2c987d854b03ca.css" as="style"/><link rel="stylesheet" href="/_next/static/css/fb2c987d854b03ca.css"/><link rel="preload" href="/_next/static/css/853c26dabccca674.css" as="style"/><link rel="stylesheet" href="/_next/static/css/853c26dabccca674.css"/><link rel="preload" href="/_next/static/css/f5d51dbe22da7e06.css" as="style"/><link rel="stylesheet" href="/_next/static/css/f5d51dbe22da7e06.css"/><noscript data-n-css=""></noscript><link rel="preload" href="/_next/static/chunks/675-bbaffee85ab26582.js" as="script"/><link rel="preload" href="/_next/static/chunks/400-cf97d6bdbdf0f340.js" as="script"/><link rel="preload" href="/_next/static/chunks/451.5f026fc39acc1202.js" as="script"/><link rel="preload" href="/_next/static/chunks/929.0b4636598979df75.js" as="script"/><link rel="preload" href="/_next/static/chunks/293.58b6d7eb60abc47f.js" as="script"/><link rel="preload" href="/_next/static/chunks/webpack-915b915b0059e2ac.js" as="script"/><link rel="preload" href="/_next/static/chunks/framework-63157d71ad419e09.js" as="script"/><link rel="preload" href="/_next/static/chunks/main-76fff4db6e2e1f3e.js" as="script"/><link rel="preload" href="/_next/static/chunks/pages/_app-14ac00e97c23b48c.js" as="script"/><link rel="preload" href="/_next/static/chunks/914-237739ac1bf6acde.js" as="script"/><link rel="preload" href="/_next/static/chunks/675-bbaffee85ab26582.js" as="script"/><link rel="preload" href="/_next/static/chunks/962-5f0fda52dcac7bd5.js" as="script"/><link rel="preload" href="/_next/static/chunks/28-3a8558ea2bc8e2bd.js" as="script"/><link rel="preload" href="/_next/static/chunks/454-8e7fbd1b315808b6.js" as="script"/><link rel="preload" href="/_next/static/chunks/pages/svg/%5B%5B...param%5D%5D-6f17f889eae5f5f5.js" as="script"/><style id="__jsx-619996359">html,input{font-family:'__Inter_e66fe9', '__Inter_Fallback_e66fe9',-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}</style></head><body><div id="__next"><div><div class="style_header__zGlFh"><div class="style_headerHolder__i_tTb"><a style="display:auto" href="/"><span class="style_logoHolder__YKj11"><img class="style_logo__OFa7_" src="/logo.svg" width="73" height="22" alt="SVG Repo - Search, explore, edit and share open licensed SVG vectors"/></span></a><div class="style_searchHolder__s_8Sf" style="display:auto"><div class="style_search__5Sx9r"><div class="style_pressEnter__Rv8T3"><span>CTRL</span> + K</div><div class="style_searchIndicator__sASd0"><svg alt="Search" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" style="transform:scale(1)"><path d="M16.32 14.9l5.39 5.4a1 1 0 0 1-1.42 1.4l-5.38-5.38a8 8 0 1 1 1.41-1.41zM10 16a6 6 0 1 0 0-12 6 6 0 0 0 0 12z"></path></svg><img alt="Searching" loading="lazy" width="21" height="21" decoding="async" data-nimg="1" style="color:transparent;opacity:0" src="/_next/static/media/spin.6ffd8bb2.svg"/></div><form><input type="text" placeholder="Search for vectors and icons..." style="text-indent:40px" value=""/><input type="submit" style="display:none"/></form><div class="style_recommendation__SXg4e" style="opacity:1"></div></div></div><ul class="style_menuMobile__uHUfg" style="display:auto"><li><a alt="Saved Vectors" title="Saved Vectors" href="/saved/"><svg style="position:relative;top:5px;margin-left:5px;margin-right:5px" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg></a></li><li><div><svg style="position:relative;top:5px;margin-left:5px;margin-right:5px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="21" height="21" fill="#333"><path d="M16.32 14.9l5.39 5.4a1 1 0 0 1-1.42 1.4l-5.38-5.38a8 8 0 1 1 1.41-1.41zM10 16a6 6 0 1 0 0-12 6 6 0 0 0 0 12z"></path></svg></div></li></ul><ul class="style_menu__qDQTZ"><li><a href="/collections/">Vector Collections</a></li><li><a alt="Saved Vectors" title="Saved Vectors" href="/saved/"><svg style="position:relative;top:5px;margin-left:5px;margin-right:5px" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg></a></li></ul></div></div><div class="style_headerSpacer__lt8mM"></div><div class="style_fixed__LxyCF"><div class="style_breadCrumbs__UNVWH"><div class="style_breadCrumbsScroller__93Cu8"><a href="/"><span>Home</span></a><div><svg width="24" height="24" viewBox="0 0 24 24" fill="#e1e1e1"><path d="M8.59,16.59L13.17,12L8.59,7.41L10,6l6,6l-6,6L8.59,16.59z"></path><path fill="none" d="M0,0h24v24H0V0z"></path></svg><a href="/collections/"><span>SVG Vector</span></a></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="#e1e1e1"><path d="M8.59,16.59L13.17,12L8.59,7.41L10,6l6,6l-6,6L8.59,16.59z"></path><path fill="none" d="M0,0h24v24H0V0z"></path></svg><a href="/svg/405485/flag-for-flag-france"><span class="style_current__O54cA">Flag For Flag France</span></a></div></div></div><div class="styles_contentHolder__tGZ_5" style="opacity:1"><div class="styles_mediaDescription__RUGi3"><h1>Flag For Flag France<!-- --> SVG Vector </h1><p class="subtext" style="margin-bottom:5px">Free Download <!-- -->Flag For Flag France<!-- --> SVG vector file in monocolor and multicolor type for Sketch and Figma from <!-- -->Flag For Flag France<!-- --> Vectors svg vector collection. <!-- -->Flag For Flag France<!-- --> Vectors SVG vector illustration graphic art design format.</p><ul class="styles_manifest__YTzNu"><li><b>COLLECTION:</b> <a href="/collections/">SVG Vector</a></li><li><b>LICENSE:</b> <a target="_blank" href="/page/licensing/#CC0">CC0<!-- --> License</a></li><li><b>UPLOADER<!-- -->:</b> <a href="/">SVG Repo</a></li><li class="styles_tags__Ng0DG"><a class="tag" style="margin-left:0" href="/vectors/flag-for-flag-france/">flag for flag france</a></li></ul><div class="styles_buttons__BCMQN"><div><div class="button buttonActive" style="padding-right:35px"><a style="width:100%;display:flex;justify-content:center;align-items:center;height:100%" href="/download/405485/flag-for-flag-france.svg"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="3" stroke-linecap="round"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span>Download SVG<span> Vector</span></span></a><div class="buttonExtra"><svg height="18" width="18" viewBox="0 0 24 24" stroke="#fff" fill="none" transform="rotate(90)" stroke-width="2" stroke-linecap="round" stroke-linejoin="arcs" style="margin-left:5px"><path d="M9 18l6-6-6-6"></path></svg></div><div class="buttonOptions"><a href="/download/405485/flag-for-flag-france.svg"><li>SVG <span>Optimized</span></li></a><a href="/svg/405485/flag-for-flag-france?edit=true"><li>PNG <span>256x256</span></li></a><a href="/svg/405485/flag-for-flag-france?edit=true"><li>PNG <span>512x512</span></li></a><a href="/svg/405485/flag-for-flag-france?edit=true"><li>PNG <span>1024x1024</span></li></a></div></div></div><div style="width:15px"></div><div class="button"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="3" stroke-linecap="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><span>Save</span></div></div></div><div class="styles_mediaContent__xVExe" itemscope="" itemType="http://schema.org/ImageObject"><img alt="Flag For Flag France SVG Vector Icon" fetchpriority="high" width="250" height="250" decoding="async" data-nimg="1" style="color:transparent;width:250px;height:250px" src="/show/405485/flag-for-flag-france.svg"/><div class="styles_mediaButtons__gS452"><a href="/svg/405485/flag-for-flag-france?edit=true"><div class="button buttonSmall"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="2" stroke-linecap="round"><circle cx="13.5" cy="6.5" r=".5"></circle><circle cx="17.5" cy="10.5" r=".5"></circle><circle cx="8.5" cy="7.5" r=".5"></circle><circle cx="6.5" cy="12.5" r=".5"></circle><path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.926 0 1.648-.746 1.648-1.688 0-.437-.18-.835-.437-1.125-.29-.289-.438-.652-.438-1.125a1.64 1.64 0 011.668-1.668h1.996c3.051 0 5.555-2.503 5.555-5.554C21.965 6.012 17.461 2 12 2z"></path></svg><span>Edit Vector</span></div></a><span itemProp="creator" itemscope="" itemType="http://schema.org/Organization"><meta itemProp="name" content="SVG Repo"/></span><meta itemProp="author" content="SVG Repo"/><meta itemProp="name" content="Flag For Flag France SVG Vector Icon"/><meta itemProp="contentUrl" content="https://www.svgrepo.com/show/405485/flag-for-flag-france.svg"/><meta itemProp="creditText" content="SVG Repo"/><meta itemProp="copyrightNotice" content="CC0"/><meta itemProp="license" content="https://www.svgrepo.com/page/licensing/#CC0"/><meta itemProp="acquireLicensePage" content="https://www.svgrepo.com/page/licensing/#CC0"/><meta itemProp="url" content="https://www.svgrepo.com/svg/405485/flag-for-flag-france"/></div><div></div></div></div><div class="style_native__ce_K5" id="native-vector-405485" style="min-height:110px"><div class="style_nativeInline__5nS3E"><div class="style_nativeContent__6Vvo4"><div class="style_nativeImagePlaceholder___q1OM"></div><div class="style_nativeText__faLaF"><div class="style_textPlaceholder__Tlefp" style="width:60%"></div><div class="style_textPlaceholder__Tlefp" style="width:90%"></div></div></div></div><div class="style_request__p92Kt" style="opacity:0;top:10px"><h3>No Ads here 🤗</h3><p style="font-size:15px">Instead, you can give us a <a href="http://twitter.com/share?text=Check%20out%20SVG%20Repo%21%0AFree%20500.000%20Open%20Licensed%20SVG%20Vector%20and%20Icons%0A%F0%9F%91%87&url=https://www.svgrepo.com/ @svgrepo" target="_blank" rel="noreferrer">Share on Twitter.</a></p><p style="position:absolute;top:20px;right:20px;padding:1px;padding-left:10px;padding-right:10px;border-radius:50px;cursor:pointer;background-color:#fafafa">×</p></div></div><div class="carrier"><div class="content"><div class="compact"><h2>SVG Vector<!-- --> SVG Vectors</h2><p class="description">Flag For Flag France<!-- --> SVG Vector is a part of <!-- -->SVG Vector<!-- --> vector collection. Following vectors are from the same pack as this vector also checkout all <!-- -->SVG Vector<!-- --> icons and vectors.</p></div><div class="style_nodeListing__7Nmro"><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div></div><a href="/collections/"><div class="button" style="margin-bottom:15px"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="3" stroke-linecap="round"><path d="M5 12h13M12 5l7 7-7 7"></path></svg><span>See All Collection</span></div></a><div class="style_native__ce_K5" id="native-vector-405485-2" style="min-height:80px"><div class="style_nativeInline__5nS3E"><div class="style_nativeContent__6Vvo4"><div class="style_nativeImagePlaceholder___q1OM"></div><div class="style_nativeText__faLaF"><div class="style_textPlaceholder__Tlefp" style="width:60%"></div><div class="style_textPlaceholder__Tlefp" style="width:90%"></div></div></div></div><div class="style_request__p92Kt" style="opacity:0;top:10px"><h3>No Ads here 🤗</h3><p style="font-size:15px">Instead, you can give us a <a href="http://twitter.com/share?text=Check%20out%20SVG%20Repo%21%0AFree%20500.000%20Open%20Licensed%20SVG%20Vector%20and%20Icons%0A%F0%9F%91%87&url=https://www.svgrepo.com/ @svgrepo" target="_blank" rel="noreferrer">Share on Twitter.</a></p><p style="position:absolute;top:20px;right:20px;padding:1px;padding-left:10px;padding-right:10px;border-radius:50px;cursor:pointer;background-color:#fafafa">×</p></div></div><h2>Flag For Flag France<!-- --> SVG Vectors</h2><p class="description">Checkout other <!-- -->Flag For Flag France<!-- --> Vectors with different styles in SVG vector and icon library.</p><div class="style_nodeListing__7Nmro"><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div></div><a href="/vectors/flag-for-flag-france/"><div class="button"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="3" stroke-linecap="round"><path d="M5 12h13M12 5l7 7-7 7"></path></svg><span>See More <span>Flag For Flag France<!-- --> </span>Vectors</span></div></a></div></div></div><div class="style_flexbarHolder__DgQcl"><div class="style_flexbar__DvWpX" id="native-flex-svg-405485-flag-for-flag-france"></div></div><div class="style_footerCarrier__SziG4"><h3 style="height:0;overflow:hidden;padding:0;margin:0">Website Content</h3><div class="style_footer__Ozqwl"><div class="style_footerInner__HZ_6Q"><div class="style_footerLogoHolder__zWQrk"><a id="footer" href="/"><span class="style_logoHolder__vMETC"><img alt="SVG Repo - Search, explore, edit and share open licensed SVG vectors" loading="lazy" width="100" height="30" decoding="async" data-nimg="1" class="style_logo___nBAe" style="color:transparent" src="/logo.svg"/></span></a><p>Search, explore, edit and share open-licensed SVG vectors</p><div class="style_socialLinks__Bvs4v"><a href="https://twitter.com/svgrepo" target="_blank" rel="noopener noreferrer"><img alt="SVG Repo Twitter" loading="lazy" width="21" height="21" decoding="async" data-nimg="1" style="color:transparent" src="/_next/static/media/twitter.29b6fbd9.svg"/></a><a href="https://instagram.com/svgrepo" target="_blank" rel="noopener noreferrer"><img alt="SVG Repo Instagram" loading="lazy" width="21" height="21" decoding="async" data-nimg="1" style="color:transparent" src="/_next/static/media/instagram.7062f55e.svg"/></a><a href="https://dribbble.com/svgrepo" target="_blank" rel="noopener noreferrer"><img alt="SVG Repo Dribbble" loading="lazy" width="21" height="21" decoding="async" data-nimg="1" style="color:transparent" src="/_next/static/media/dribbble.e6cbf389.svg"/></a><a href="https://producthunt.com/products/svgrepo" target="_blank" rel="noopener noreferrer"><img alt="SVG Repo ProductHunt" loading="lazy" width="21" height="21" decoding="async" data-nimg="1" style="color:transparent" src="/_next/static/media/producthunt.fabbb697.svg"/></a></div><div style="height:60px"><div><div id="footer-native-native-flex-svg-405485-flag-for-flag-france"></div></div></div></div><div><h4>Free Vectors</h4><ul><li><a href="/collections/monocolor/">Monocolor Vectors</a></li><li><a href="/collections/multicolor/">Multicolor Vectors</a></li><li><a href="/collections/filled/">Filled Vectors</a></li><li><a href="/collections/outlined/">Outlined Vectors</a></li><li><a href="/collections/icon/">Icon Vectors</a></li></ul></div><div><h4>Other Collections</h4><ul><li><a href="/collections/icon/">Glyphs Vectors</a></li><li><a href="/collections/circular/">Circular Vectors</a></li><li><a href="/collections/duotone/">Duotone Vectors</a></li><li><a href="/collections/flat/">Flat Vectors</a></li><li><a href="https://upload.svgrepo.com" target="_blank" rel="noopener">Submit Assets</a></li></ul></div><div><h4>Developers / Designers</h4><ul><li><a href="/tools/">Free Tools</a></li><li><a href="https://www.svgapi.com" target="_blank" rel="noopener">Icon API</a></li><li><a href="https://vectormaker.co" target="_blank" rel="noopener">vectormaker</a></li><li><a href="https://www.fontrepo.com" target="_blank" rel="noopener">Font Repo</a></li><li><a href="https://svgfind.com" target="_blank" rel="noopener">SVG Find</a></li></ul></div></div><div class="style_footerBottom__l8wqE"><div>© <!-- -->2024<!-- --> · SVG Repo LLC</div><div><a href="/page/terms-of-use/">Terms of Use</a><a href="/page/privacy-policy/">Privacy Policy</a><a href="/page/licensing/">Licensing</a><a href="/page/contact/">Contact</a></div></div></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"ssrIcon":{"id":"405485","slug":"flag-for-flag-france","title":"flag-for-flag-france","similar":[false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]}},"__N_SSP":true},"page":"/svg/[[...param]]","query":{"param":["405485/flag-for-flag-france"]},"buildId":"9UdWXZJ2dR-D_IkpQGEy7","isFallback":false,"dynamicIds":[451,6929,2293],"gssp":true,"customServer":true,"scriptLoader":[]}</script><script nomodule="" src="/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script async="" src="/_next/static/chunks/400-cf97d6bdbdf0f340.js"></script><script async="" src="/_next/static/chunks/451.5f026fc39acc1202.js"></script><script async="" src="/_next/static/chunks/929.0b4636598979df75.js"></script><script async="" src="/_next/static/chunks/293.58b6d7eb60abc47f.js"></script><script src="/_next/static/chunks/webpack-915b915b0059e2ac.js" async=""></script><script src="/_next/static/chunks/framework-63157d71ad419e09.js" async=""></script><script src="/_next/static/chunks/main-76fff4db6e2e1f3e.js" async=""></script><script src="/_next/static/chunks/pages/_app-14ac00e97c23b48c.js" async=""></script><script src="/_next/static/chunks/914-237739ac1bf6acde.js" async=""></script><script src="/_next/static/chunks/675-bbaffee85ab26582.js" async=""></script><script src="/_next/static/chunks/962-5f0fda52dcac7bd5.js" async=""></script><script src="/_next/static/chunks/28-3a8558ea2bc8e2bd.js" async=""></script><script src="/_next/static/chunks/454-8e7fbd1b315808b6.js" async=""></script><script src="/_next/static/chunks/pages/svg/%5B%5B...param%5D%5D-6f17f889eae5f5f5.js" async=""></script><script src="/_next/static/9UdWXZJ2dR-D_IkpQGEy7/_buildManifest.js" async=""></script><script src="/_next/static/9UdWXZJ2dR-D_IkpQGEy7/_ssgManifest.js" async=""></script></body></html>
|
static/js/pdf.js
CHANGED
@@ -8,8 +8,10 @@ const reset = document.getElementById("reset");
|
|
8 |
const imagePreview = dropArea.querySelector("#image-preview");
|
9 |
const currentClassProbabilitiesList = document.getElementById("class-probabilities");
|
10 |
const currentPredictedClass = document.getElementById('predicted-class')
|
|
|
11 |
const staticDiv = document.getElementById("static");
|
12 |
const dynamicDiv = document.getElementById("dynamic");
|
|
|
13 |
var chartData;
|
14 |
let file;
|
15 |
|
@@ -115,9 +117,21 @@ form.addEventListener("submit", (event) => {
|
|
115 |
currentClassProbabilitiesList.innerHTML = classProbabilitiesList.innerHTML;
|
116 |
const PredictedClass = responseDOM.getElementById("predicted-class")
|
117 |
currentPredictedClass.innerHTML = PredictedClass.innerHTML;
|
|
|
|
|
|
|
118 |
dynamicDiv.classList.remove('d-none');
|
119 |
staticDiv.classList.add('d-none');
|
120 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
var canvasElement = responseDOM.querySelector('.bestSellers'); // Sélectionnez le premier élément avec la classe 'bestSellers'
|
122 |
chartData = canvasElement.getAttribute('data-chart');
|
123 |
var data = JSON.parse(chartData).datasets[0].data.slice(0, 5);
|
|
|
8 |
const imagePreview = dropArea.querySelector("#image-preview");
|
9 |
const currentClassProbabilitiesList = document.getElementById("class-probabilities");
|
10 |
const currentPredictedClass = document.getElementById('predicted-class')
|
11 |
+
const sentencePredictions = document.getElementById('classifiedText')
|
12 |
const staticDiv = document.getElementById("static");
|
13 |
const dynamicDiv = document.getElementById("dynamic");
|
14 |
+
const sentenceResultDiv = document.getElementById("dynamicResult");
|
15 |
var chartData;
|
16 |
let file;
|
17 |
|
|
|
117 |
currentClassProbabilitiesList.innerHTML = classProbabilitiesList.innerHTML;
|
118 |
const PredictedClass = responseDOM.getElementById("predicted-class")
|
119 |
currentPredictedClass.innerHTML = PredictedClass.innerHTML;
|
120 |
+
document.getElementById('transcribedText').innerHTML = responseDOM.getElementById('transcribedText').innerHTML;
|
121 |
+
const sentencePredictionsResponse= responseDOM.getElementById('classifiedText').innerHTML;
|
122 |
+
sentencePredictions.innerHTML = sentencePredictionsResponse;
|
123 |
dynamicDiv.classList.remove('d-none');
|
124 |
staticDiv.classList.add('d-none');
|
125 |
+
sentenceResultDiv.classList.remove('d-none');
|
126 |
+
setTimeout(() => {
|
127 |
+
const resultsDiv = document.getElementById('dynamicResult');
|
128 |
+
if (resultsDiv) {
|
129 |
+
resultsDiv.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
130 |
+
}
|
131 |
+
}, 100);
|
132 |
+
if (resultsHeading) {
|
133 |
+
resultsHeading.scrollIntoView({ behavior: 'smooth' });
|
134 |
+
}
|
135 |
var canvasElement = responseDOM.querySelector('.bestSellers'); // Sélectionnez le premier élément avec la classe 'bestSellers'
|
136 |
chartData = canvasElement.getAttribute('data-chart');
|
137 |
var data = JSON.parse(chartData).datasets[0].data.slice(0, 5);
|
static/js/pdf_fr.js
ADDED
@@ -0,0 +1,236 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
const dropArea = document.getElementById("dropArea");
|
2 |
+
const dragText = dropArea.querySelector("h6");
|
3 |
+
const input = dropArea.querySelector("input");
|
4 |
+
const form = document.querySelector("form");
|
5 |
+
const ocrResult = document.getElementById("ocr-result");
|
6 |
+
const categoryResult = document.getElementById("category-result")
|
7 |
+
const reset = document.getElementById("reset");
|
8 |
+
const imagePreview = dropArea.querySelector("#image-preview");
|
9 |
+
const currentClassProbabilitiesList = document.getElementById("class-probabilities");
|
10 |
+
const currentPredictedClass = document.getElementById('predicted-class')
|
11 |
+
const sentencePredictions = document.getElementById('classifiedText')
|
12 |
+
const staticDiv = document.getElementById("static");
|
13 |
+
const dynamicDiv = document.getElementById("dynamic");
|
14 |
+
const sentenceResultDiv = document.getElementById("dynamicResult");
|
15 |
+
var chartData;
|
16 |
+
let file;
|
17 |
+
|
18 |
+
|
19 |
+
|
20 |
+
// Event listener for clicking the dropArea to upload a file
|
21 |
+
dropArea.addEventListener("click", () => {
|
22 |
+
// Trigger click event on the file input when the dropArea is clicked
|
23 |
+
const input = document.getElementById("file-input");
|
24 |
+
input.click();
|
25 |
+
});
|
26 |
+
|
27 |
+
// Update the event listener for input change to handle file selection
|
28 |
+
const fileInput = document.getElementById("file-input");
|
29 |
+
fileInput.addEventListener("change", function () {
|
30 |
+
file = this.files[0];
|
31 |
+
dropArea.classList.add("active");
|
32 |
+
viewFile();
|
33 |
+
});
|
34 |
+
|
35 |
+
|
36 |
+
input.addEventListener("change", function () {
|
37 |
+
file = this.files[0];
|
38 |
+
dropArea.classList.add("active");
|
39 |
+
viewFile();
|
40 |
+
});
|
41 |
+
|
42 |
+
dropArea.addEventListener("dragover", (event) => {
|
43 |
+
event.preventDefault();
|
44 |
+
dropArea.classList.add("active");
|
45 |
+
dragText.textContent = "Release to Upload File";
|
46 |
+
});
|
47 |
+
|
48 |
+
dropArea.addEventListener("dragleave", () => {
|
49 |
+
dropArea.classList.remove("active");
|
50 |
+
dragText.textContent = "Drag & Drop or Click to Upload File";
|
51 |
+
});
|
52 |
+
|
53 |
+
dropArea.addEventListener("drop", (event) => {
|
54 |
+
event.preventDefault();
|
55 |
+
file = event.dataTransfer.files[0];
|
56 |
+
viewFile();
|
57 |
+
});
|
58 |
+
|
59 |
+
// Définir la fonction initializeChart en premier
|
60 |
+
function initializeChart(data, backgroundColor, borderColor, labels) {
|
61 |
+
// Créer une nouvelle instance Chart.js pour chaque élément canvas avec la classe 'bestSellers'
|
62 |
+
data = data.map(function (element) {
|
63 |
+
return parseFloat(element).toFixed(2);
|
64 |
+
});
|
65 |
+
document.querySelectorAll('.bestSellers').forEach(function (canvas) {
|
66 |
+
// Initialiser le graphique
|
67 |
+
new Chart(canvas, {
|
68 |
+
type: 'doughnut', // Définir le type de graphique sur doughnut
|
69 |
+
data: {
|
70 |
+
datasets: [{
|
71 |
+
data: data,
|
72 |
+
backgroundColor: backgroundColor,
|
73 |
+
borderColor: borderColor,
|
74 |
+
}],
|
75 |
+
labels: labels
|
76 |
+
},
|
77 |
+
options: {
|
78 |
+
responsive: true, // Rendre le graphique responsive
|
79 |
+
cutoutPercentage: 80, // Définir le pourcentage de découpe
|
80 |
+
legend: {
|
81 |
+
display: false, // Masquer la légende
|
82 |
+
},
|
83 |
+
animation: {
|
84 |
+
animateScale: true,
|
85 |
+
animateRotate: true
|
86 |
+
},
|
87 |
+
plugins: {
|
88 |
+
datalabels: {
|
89 |
+
display: false,
|
90 |
+
align: 'center',
|
91 |
+
anchor: 'center'
|
92 |
+
}
|
93 |
+
}
|
94 |
+
}
|
95 |
+
});
|
96 |
+
});
|
97 |
+
}
|
98 |
+
|
99 |
+
form.addEventListener("submit", (event) => {
|
100 |
+
event.preventDefault();
|
101 |
+
if (!file) {
|
102 |
+
alert("Please select a file!");
|
103 |
+
return;
|
104 |
+
}
|
105 |
+
const formData = new FormData();
|
106 |
+
formData.append("file", file);
|
107 |
+
fetch("/pdf_fr/upload", {
|
108 |
+
method: "POST",
|
109 |
+
body: formData,
|
110 |
+
})
|
111 |
+
.then((response) => response.text())
|
112 |
+
.then((html) => {
|
113 |
+
const responseDOM = new DOMParser().parseFromString(html, "text/html");
|
114 |
+
const resultTextArea = responseDOM.getElementById("ocr-result");
|
115 |
+
ocrResult.value = resultTextArea.value;
|
116 |
+
const classProbabilitiesList = responseDOM.getElementById("class-probabilities");
|
117 |
+
currentClassProbabilitiesList.innerHTML = classProbabilitiesList.innerHTML;
|
118 |
+
const PredictedClass = responseDOM.getElementById("predicted-class")
|
119 |
+
currentPredictedClass.innerHTML = PredictedClass.innerHTML;
|
120 |
+
document.getElementById('transcribedText').innerHTML = responseDOM.getElementById('transcribedText').innerHTML;
|
121 |
+
const sentencePredictionsResponse= responseDOM.getElementById('classifiedText').innerHTML;
|
122 |
+
sentencePredictions.innerHTML = sentencePredictionsResponse;
|
123 |
+
dynamicDiv.classList.remove('d-none');
|
124 |
+
staticDiv.classList.add('d-none');
|
125 |
+
sentenceResultDiv.classList.remove('d-none');
|
126 |
+
setTimeout(() => {
|
127 |
+
const resultsDiv = document.getElementById('dynamicResult');
|
128 |
+
if (resultsDiv) {
|
129 |
+
resultsDiv.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
130 |
+
}
|
131 |
+
}, 100);
|
132 |
+
if (resultsHeading) {
|
133 |
+
resultsHeading.scrollIntoView({ behavior: 'smooth' });
|
134 |
+
}
|
135 |
+
var canvasElement = responseDOM.querySelector('.bestSellers'); // Sélectionnez le premier élément avec la classe 'bestSellers'
|
136 |
+
chartData = canvasElement.getAttribute('data-chart');
|
137 |
+
var data = JSON.parse(chartData).datasets[0].data.slice(0, 5);
|
138 |
+
var backgroundColor = JSON.parse(chartData).datasets[0].backgroundColor.slice(0, 5);
|
139 |
+
var borderColor = JSON.parse(chartData).datasets[0].borderColor.slice(0, 5);
|
140 |
+
var labels = JSON.parse(chartData).labels.slice(0, 5);
|
141 |
+
|
142 |
+
// Créer de nouveaux graphiques
|
143 |
+
loadDashboardScript(data, backgroundColor, borderColor, labels);
|
144 |
+
})
|
145 |
+
.catch((error) => console.error(error));
|
146 |
+
});
|
147 |
+
|
148 |
+
function destroyPreviousCharts() {
|
149 |
+
// Trouver tous les éléments canvas avec la classe 'bestSellers'
|
150 |
+
document.querySelectorAll('.bestSellers').forEach(function (canvas) {
|
151 |
+
// Récupérer l'instance du graphique
|
152 |
+
var chartInstance = Chart.getChart(canvas);
|
153 |
+
// Si une instance existe, détruire le graphique
|
154 |
+
if (chartInstance) {
|
155 |
+
chartInstance.destroy();
|
156 |
+
}
|
157 |
+
});
|
158 |
+
}
|
159 |
+
|
160 |
+
function loadDashboardScript(data, backgroundColor, borderColor, labels) { // Correction ici
|
161 |
+
var scriptElement = document.createElement('script');
|
162 |
+
scriptElement.type = 'text/javascript';
|
163 |
+
scriptElement.src = '../static/js/dashboard_pdf.js';
|
164 |
+
// Attendez que le script soit chargé avant d'appeler la fonction d'initialisation
|
165 |
+
scriptElement.onload = function () {
|
166 |
+
initializeChart(data, backgroundColor, borderColor, labels);
|
167 |
+
};
|
168 |
+
document.body.appendChild(scriptElement);
|
169 |
+
}
|
170 |
+
|
171 |
+
|
172 |
+
// Define the original HTML structure of the drop area
|
173 |
+
const originalDropAreaHTML = `
|
174 |
+
<h6 class="text-white-50">Drag and Drop File Here</h6>
|
175 |
+
<span class="text-white-50">OR</span>
|
176 |
+
<h6 class="text-white-50">Click here</h6>
|
177 |
+
<input id="file-input" type="file" name="image" accept=".pdf" hidden>
|
178 |
+
`;
|
179 |
+
|
180 |
+
function deleteCurrentFile() {
|
181 |
+
// Recharger le fichier index.js après l'envoi du formulaire
|
182 |
+
window.location.reload();
|
183 |
+
file = null;
|
184 |
+
|
185 |
+
// Restore the original HTML structure
|
186 |
+
dropArea.innerHTML = originalDropAreaHTML;
|
187 |
+
|
188 |
+
// Remove the 'active' class to reset the styling
|
189 |
+
dropArea.classList.remove("active");
|
190 |
+
|
191 |
+
// Update the event listener for input change to handle file selection
|
192 |
+
const fileInput = document.getElementById("file-input");
|
193 |
+
|
194 |
+
fileInput.addEventListener("change", function () {
|
195 |
+
file = this.files[0];
|
196 |
+
dropArea.classList.add("active");
|
197 |
+
viewFile();
|
198 |
+
});
|
199 |
+
}
|
200 |
+
|
201 |
+
|
202 |
+
function viewFile() {
|
203 |
+
let fileType = file.type;
|
204 |
+
let validExtensions = ["application/pdf"];
|
205 |
+
if (validExtensions.includes(fileType)) {
|
206 |
+
let fileURL = URL.createObjectURL(file);
|
207 |
+
let pdfTag = `<iframe src="${fileURL}" style="width:100%;height:100%;"></iframe>`;
|
208 |
+
dropArea.innerHTML = pdfTag;
|
209 |
+
} else {
|
210 |
+
alert("This is not a PDF File!");
|
211 |
+
dropArea.classList.remove("active");
|
212 |
+
dragText.textContent = "Drag & Drop or Click to Upload File";
|
213 |
+
}
|
214 |
+
}
|
215 |
+
|
216 |
+
const copyBtn = document.getElementById("copy-btn");
|
217 |
+
|
218 |
+
copyBtn.addEventListener("click", () => {
|
219 |
+
ocrResult.select();
|
220 |
+
document.execCommand("copy");
|
221 |
+
});
|
222 |
+
|
223 |
+
function createResponseElement(response) {
|
224 |
+
var pdfResponseElement = document.createElement('ul');
|
225 |
+
pdfResponseElement.classList.add('graph-legend-rectangle');
|
226 |
+
pdfResponseElement.innerHTML = response;
|
227 |
+
return pdfResponseElement;
|
228 |
+
}
|
229 |
+
|
230 |
+
// Modifiez la fonction reloadDashboardScript pour accepter les données supplémentaires
|
231 |
+
function reloadDashboardScript(data, backgroundColor, borderColor, labels) {
|
232 |
+
var scriptElement = document.createElement('script');
|
233 |
+
scriptElement.type = 'text/javascript';
|
234 |
+
scriptElement.src = `../static/js/dashboard_pdf.js?data=${encodeURIComponent(JSON.stringify(data))}&backgroundColor=${encodeURIComponent(JSON.stringify(backgroundColor))}&borderColor=${encodeURIComponent(JSON.stringify(borderColor))}&labels=${encodeURIComponent(JSON.stringify(labels))}`;
|
235 |
+
document.body.appendChild(scriptElement);
|
236 |
+
}
|
static/js/sentence_fr.js
ADDED
@@ -0,0 +1,253 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
var chartData;
|
2 |
+
function generateUniqueId() {
|
3 |
+
return 'chart-' + Date.now(); // Utilisez un timestamp comme identifiant unique
|
4 |
+
}
|
5 |
+
|
6 |
+
function submitForm() {
|
7 |
+
event.preventDefault(); // Prevent the default form submission
|
8 |
+
|
9 |
+
var form = document.getElementById('sentenceForm');
|
10 |
+
var textarea = document.getElementById("ocr-result");
|
11 |
+
|
12 |
+
// Check if the textarea is empty
|
13 |
+
if (textarea.value.trim() === "") {
|
14 |
+
textarea.setCustomValidity("Input is required."); // Set custom validation message
|
15 |
+
textarea.reportValidity(); // Display the validation message
|
16 |
+
return; // Do not proceed with form submission
|
17 |
+
} else {
|
18 |
+
textarea.setCustomValidity(""); // Clear any previous validation message
|
19 |
+
}
|
20 |
+
$
|
21 |
+
var formData = new FormData(form);
|
22 |
+
|
23 |
+
// Hide the presentation div
|
24 |
+
var presentationDiv = document.getElementById('presentation');
|
25 |
+
presentationDiv.classList.add('d-none');
|
26 |
+
|
27 |
+
// Send a POST request to the Flask route with the form data
|
28 |
+
fetch('/sentence_fr', {
|
29 |
+
method: 'POST',
|
30 |
+
body: formData
|
31 |
+
})
|
32 |
+
.then(response => response.text())
|
33 |
+
.then(data => {
|
34 |
+
|
35 |
+
// Reset the textarea height to its initial value
|
36 |
+
var textarea = document.getElementById("ocr-result");
|
37 |
+
textarea.style.height = "50px";
|
38 |
+
|
39 |
+
// Add the new user message to the chat conversation
|
40 |
+
var userMessageElement = createUserMessageElement(formData.get('text'));
|
41 |
+
var chatConversation = document.querySelector('.chat-conversation-content .os-content');
|
42 |
+
chatConversation.appendChild(userMessageElement);
|
43 |
+
|
44 |
+
// Create a new message element for Flask response
|
45 |
+
var flaskResponseElement = createFlaskResponseElement(data);
|
46 |
+
// Append the Flask response as a left message to the chat conversation
|
47 |
+
chatConversation.appendChild(flaskResponseElement);
|
48 |
+
var canvasElement = document.querySelector('.bestSellers'); // Sélectionnez le premier élément avec la classe 'bestSellers'
|
49 |
+
chartData = canvasElement.getAttribute('data-chart');
|
50 |
+
var data = JSON.parse(chartData).datasets[0].data.slice(0, 5);
|
51 |
+
var backgroundColor = JSON.parse(chartData).datasets[0].backgroundColor.slice(0, 5);
|
52 |
+
var borderColor = JSON.parse(chartData).datasets[0].borderColor.slice(0, 5);
|
53 |
+
var labels = JSON.parse(chartData).labels.slice(0, 5);
|
54 |
+
// Scroll to the bottom of the chat conversation
|
55 |
+
addAutoResize();
|
56 |
+
scrollDown();
|
57 |
+
// Clear the textarea after submitting
|
58 |
+
form.reset();
|
59 |
+
// Create a new canvas element for the new chart
|
60 |
+
var canvasId = generateUniqueId();
|
61 |
+
var canvasHTML = document.getElementById('bestSellers#');
|
62 |
+
canvasHTML.id = generateUniqueId();
|
63 |
+
canvasId = canvasHTML.id;
|
64 |
+
|
65 |
+
// Update the new chart with data
|
66 |
+
updateChart(canvasId);
|
67 |
+
})
|
68 |
+
.catch(error => console.error('Error:', error));
|
69 |
+
}
|
70 |
+
function updateChart(canvasId) {
|
71 |
+
var canvas = document.getElementById(canvasId);
|
72 |
+
var chartData = JSON.parse(canvas.dataset.chart);
|
73 |
+
var data = chartData.datasets[0].data.slice(0, 5).map(function(element) {
|
74 |
+
return parseFloat(element).toFixed(2);
|
75 |
+
});
|
76 |
+
var backgroundColor = chartData.datasets[0].backgroundColor.slice(0,5);
|
77 |
+
var borderColor = chartData.datasets[0].borderColor.slice(0,5);
|
78 |
+
var labels = chartData.labels.slice(0,5);
|
79 |
+
var Data = {
|
80 |
+
datasets: [{
|
81 |
+
data: data,
|
82 |
+
backgroundColor:
|
83 |
+
backgroundColor
|
84 |
+
,
|
85 |
+
borderColor: backgroundColor,
|
86 |
+
}],
|
87 |
+
// These labels appear in the legend and in the tooltips when hovering different arcs
|
88 |
+
labels: labels
|
89 |
+
};
|
90 |
+
var pieChart = new Chart(canvas, {
|
91 |
+
type: 'doughnut',
|
92 |
+
data: Data,
|
93 |
+
options: {
|
94 |
+
responsive: true, // Rendre le graphique responsive
|
95 |
+
cutoutPercentage: 80, // Définir le pourcentage de découpe
|
96 |
+
legend: {
|
97 |
+
display: false, // Masquer la légende
|
98 |
+
},
|
99 |
+
animation: {
|
100 |
+
animateScale: true,
|
101 |
+
animateRotate: true
|
102 |
+
},
|
103 |
+
plugins: {
|
104 |
+
datalabels: {
|
105 |
+
display: false,
|
106 |
+
align: 'center',
|
107 |
+
anchor: 'center'
|
108 |
+
}
|
109 |
+
}
|
110 |
+
}
|
111 |
+
});
|
112 |
+
}
|
113 |
+
|
114 |
+
|
115 |
+
function handleEnter(event) {
|
116 |
+
if (event.key === "Enter" && !event.shiftKey) {
|
117 |
+
event.preventDefault(); // Prevent default behavior (line break)
|
118 |
+
submitForm(); // Submit the form asynchronously
|
119 |
+
}
|
120 |
+
}
|
121 |
+
|
122 |
+
|
123 |
+
document.getElementById('sentenceForm').addEventListener('submit', function (event) {
|
124 |
+
event.preventDefault(); // Prevent the form from submitting normally
|
125 |
+
var form = event.target;
|
126 |
+
var formData = new FormData(form);
|
127 |
+
|
128 |
+
// Hide the presentation div
|
129 |
+
var presentationDiv = document.getElementById('presentation');
|
130 |
+
presentationDiv.classList.add('d-none');
|
131 |
+
|
132 |
+
// Send a POST request to the Flask route with the form data
|
133 |
+
fetch('/sentence_fr', {
|
134 |
+
method: 'POST',
|
135 |
+
body: formData
|
136 |
+
})
|
137 |
+
.then(response => response.text())
|
138 |
+
.then(data => {
|
139 |
+
|
140 |
+
// Reset the textarea height to its initial value
|
141 |
+
var textarea = document.getElementById("ocr-result");
|
142 |
+
textarea.style.height = "50px";
|
143 |
+
// Add the new user message to the chat conversation
|
144 |
+
var userMessageElement = createUserMessageElement(formData.get('text'));
|
145 |
+
var chatConversation = document.querySelector('.chat-conversation-content .os-content');
|
146 |
+
chatConversation.appendChild(userMessageElement);
|
147 |
+
|
148 |
+
// Create a new message element for Flask response
|
149 |
+
var flaskResponseElement = createFlaskResponseElement(data);
|
150 |
+
|
151 |
+
// Append the Flask response as a left message to the chat conversation
|
152 |
+
chatConversation.appendChild(flaskResponseElement);
|
153 |
+
var canvasElement = document.querySelector('.bestSellers'); // Sélectionnez le premier élément avec la classe 'bestSellers'
|
154 |
+
chartData = canvasElement.getAttribute('data-chart');
|
155 |
+
var data = JSON.parse(chartData).datasets[0].data.slice(0, 5);
|
156 |
+
var backgroundColor = JSON.parse(chartData).datasets[0].backgroundColor.slice(0, 5);
|
157 |
+
var borderColor = JSON.parse(chartData).datasets[0].borderColor.slice(0, 5);
|
158 |
+
var labels = JSON.parse(chartData).labels.slice(0, 5);
|
159 |
+
addAutoResize();
|
160 |
+
scrollDown();
|
161 |
+
// Clear the textarea after submitting
|
162 |
+
form.reset();
|
163 |
+
// Create a new canvas element for the new chart
|
164 |
+
var canvasId = generateUniqueId();
|
165 |
+
var canvasHTML = document.getElementById('bestSellers#');
|
166 |
+
canvasHTML.id = generateUniqueId();
|
167 |
+
canvasId = canvasHTML.id;
|
168 |
+
|
169 |
+
// Update the new chart with data
|
170 |
+
updateChart(canvasId);
|
171 |
+
})
|
172 |
+
.catch(error => console.error('Error:', error));
|
173 |
+
});
|
174 |
+
|
175 |
+
// Function to create a message element for user's message
|
176 |
+
function createUserMessageElement(message) {
|
177 |
+
var userMessageElement = document.createElement('div');
|
178 |
+
userMessageElement.classList.add('d-flex', 'justify-content-end', 'text-end', 'mb-1');
|
179 |
+
var userMessageSubElement = document.createElement('div');
|
180 |
+
userMessageSubElement.classList.add('w-100');
|
181 |
+
var userMessageContainer = document.createElement('div');
|
182 |
+
userMessageContainer.classList.add('d-flex', 'flex-column', 'align-items-end');
|
183 |
+
// Add message content
|
184 |
+
var userMessageContent = document.createElement('div');
|
185 |
+
userMessageContent.classList.add('bg-primary', 'text-white', 'p-2', 'px-3', 'rounded-2', 'mw-80');
|
186 |
+
var userMessageText = document.createTextNode(message);
|
187 |
+
userMessageContent.appendChild(userMessageText);
|
188 |
+
userMessageContainer.appendChild(userMessageContent);
|
189 |
+
userMessageSubElement.appendChild(userMessageContainer);
|
190 |
+
userMessageElement.appendChild(userMessageSubElement);
|
191 |
+
return userMessageElement;
|
192 |
+
}
|
193 |
+
|
194 |
+
// Function to create a message element for Flask response
|
195 |
+
function createFlaskResponseElement(response) {
|
196 |
+
var flaskResponseElement = document.createElement('div');
|
197 |
+
flaskResponseElement.classList.add('d-flex', 'mb-1');
|
198 |
+
var flaskAvatarElement = document.createElement('div');
|
199 |
+
flaskAvatarElement.classList.add('flex-shrink-0', 'avatar', 'avatar-xs', 'me-2');
|
200 |
+
var flaskAvatarImg = document.createElement('img');
|
201 |
+
flaskAvatarImg.classList.add('avatar-img', 'rounded-circle');
|
202 |
+
flaskAvatarImg.setAttribute('src', '../static/icons/logo_header_128x128.png');
|
203 |
+
flaskAvatarElement.appendChild(flaskAvatarImg);
|
204 |
+
var flaskMessageContent = document.createElement('div');
|
205 |
+
flaskMessageContent.classList.add('flex-grow-1');
|
206 |
+
flaskMessageContent.innerHTML = response;
|
207 |
+
flaskResponseElement.appendChild(flaskAvatarElement);
|
208 |
+
flaskResponseElement.appendChild(flaskMessageContent);
|
209 |
+
return flaskResponseElement;
|
210 |
+
}
|
211 |
+
// Function to reload the dashboard.js file with chartData
|
212 |
+
function reloadDashboardScript(data, backgroundColor, borderColor, labels) {
|
213 |
+
// Create a new script element
|
214 |
+
var scriptElement = document.createElement('script');
|
215 |
+
scriptElement.type = 'text/javascript';
|
216 |
+
scriptElement.onload = function () {
|
217 |
+
initializeChart(data, backgroundColor, borderColor, labels);
|
218 |
+
};
|
219 |
+
// Add chartData to the script source as a query parameter
|
220 |
+
scriptElement.src = `../static/js/dashboard_sentence.js?data=${data}&backgroundColor=${backgroundColor}&borderColor=${borderColor}&labels=${labels}`;
|
221 |
+
|
222 |
+
// Append the script element to the body
|
223 |
+
document.body.appendChild(scriptElement);
|
224 |
+
}
|
225 |
+
// START: 12 Auto resize textarea
|
226 |
+
function addAutoResize() {
|
227 |
+
document.querySelectorAll('[data-autoresize]').forEach(function (element) {
|
228 |
+
element.style.boxSizing = 'border-box';
|
229 |
+
var offset = element.offsetHeight - element.clientHeight;
|
230 |
+
element.addEventListener('input', function (event) {
|
231 |
+
event.target.style.height = 'auto';
|
232 |
+
event.target.style.height = event.target.scrollHeight + offset + 'px';
|
233 |
+
});
|
234 |
+
element.removeAttribute('data-autoresize');
|
235 |
+
});
|
236 |
+
}
|
237 |
+
// SCROLLDOWN
|
238 |
+
function scrollDown() {
|
239 |
+
var objDiv = document.getElementsByClassName("os-viewport os-viewport-native-scrollbars-invisible");
|
240 |
+
var index = 0;
|
241 |
+
while (index < objDiv.length) {
|
242 |
+
objDiv[index].scrollTop = objDiv[index].scrollHeight;
|
243 |
+
index++;
|
244 |
+
}
|
245 |
+
}
|
246 |
+
|
247 |
+
// RESIZE TEXTAREA
|
248 |
+
function resizeTextarea(textarea) {
|
249 |
+
textarea.style.height = "auto";
|
250 |
+
textarea.style.height = textarea.scrollHeight + "px";
|
251 |
+
}
|
252 |
+
|
253 |
+
|
templates/pdf.html
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
<html lang="en-US">
|
3 |
|
4 |
<head>
|
5 |
-
<title>
|
6 |
<link rel="icon" href="https://cdn-icons-png.flaticon.com/512/5262/5262072.png">
|
7 |
<link rel="stylesheet" href="../static/css/style2.css">
|
8 |
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
@@ -45,6 +45,14 @@
|
|
45 |
<li class="nav-item nav-pills nav-pills-ocr">
|
46 |
<a class="nav-item nav-link " href="voice">SLU</a>
|
47 |
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
</ul>
|
49 |
</div>
|
50 |
<!-- Main navbar END -->
|
@@ -79,12 +87,12 @@
|
|
79 |
<div class="col-12 d-flex justify-content-center">
|
80 |
<div class="col-sm-12 d-inline align-items-center" style="height: 175px; width: 229px;">
|
81 |
<div class="flex-shrink-0 avatar avatar-lg me-2 mb-3 mt-4">
|
82 |
-
<img class="avatar-img rounded-circle"
|
83 |
-
|
84 |
</div>
|
85 |
<h5 class="card-title text-white-50">Get more insights about your pdf 📑📑.</h5>
|
86 |
</div>
|
87 |
-
|
88 |
</div>
|
89 |
</div>
|
90 |
<div class="card-body d-none" id="dynamic">
|
@@ -128,6 +136,36 @@
|
|
128 |
|
129 |
<!-- Right sidebar END -->
|
130 |
</div> <!-- Row END -->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
</div>
|
132 |
</main>
|
133 |
|
|
|
2 |
<html lang="en-US">
|
3 |
|
4 |
<head>
|
5 |
+
<title>Pdf Categorization</title>
|
6 |
<link rel="icon" href="https://cdn-icons-png.flaticon.com/512/5262/5262072.png">
|
7 |
<link rel="stylesheet" href="../static/css/style2.css">
|
8 |
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
|
|
45 |
<li class="nav-item nav-pills nav-pills-ocr">
|
46 |
<a class="nav-item nav-link " href="voice">SLU</a>
|
47 |
</li>
|
48 |
+
<li class="nav-item dropdown">
|
49 |
+
<a class="nav-link" href="#" id="accounntMenu" data-bs-toggle="dropdown" aria-haspopup="true"
|
50 |
+
aria-expanded="false">language</a>
|
51 |
+
<ul class="dropdown-menu" aria-labelledby="accounntMenu">
|
52 |
+
<li> <a class="dropdown-item " href="pdf_fr"><img src="../static/icons/France.svg"
|
53 |
+
class="avatar avatar" style="height: 20px;" alt="French flag"> French </a> </li>
|
54 |
+
</ul>
|
55 |
+
</li>
|
56 |
</ul>
|
57 |
</div>
|
58 |
<!-- Main navbar END -->
|
|
|
87 |
<div class="col-12 d-flex justify-content-center">
|
88 |
<div class="col-sm-12 d-inline align-items-center" style="height: 175px; width: 229px;">
|
89 |
<div class="flex-shrink-0 avatar avatar-lg me-2 mb-3 mt-4">
|
90 |
+
<img class="avatar-img rounded-circle" src="../static/icons/logo_header_128x128.png"
|
91 |
+
alt="">
|
92 |
</div>
|
93 |
<h5 class="card-title text-white-50">Get more insights about your pdf 📑📑.</h5>
|
94 |
</div>
|
95 |
+
|
96 |
</div>
|
97 |
</div>
|
98 |
<div class="card-body d-none" id="dynamic">
|
|
|
136 |
|
137 |
<!-- Right sidebar END -->
|
138 |
</div> <!-- Row END -->
|
139 |
+
|
140 |
+
</div>
|
141 |
+
<div class="row d-sm-flex justify-content-center mb-5">
|
142 |
+
<div class="col-11">
|
143 |
+
<div class="row d-none" id='dynamicResult'>
|
144 |
+
<h1 id="resultsHeading" class="text-center text-white-50">Results</h1>
|
145 |
+
<div class="col-12">
|
146 |
+
<div class="card" style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
|
147 |
+
<div class="card-body">
|
148 |
+
<h5 class="card-title text-white mb-3">Transcribed and Classified Text</h5>
|
149 |
+
<div id="transcribedText" class="text-white-50 mb-4"></div>
|
150 |
+
<div class="text-center">
|
151 |
+
<div class="col-12 d-flex justify-content-center">
|
152 |
+
<div class="col-sm-12 d-inline align-items-center" id="classifiedText">
|
153 |
+
{% if sentences_prediction %}
|
154 |
+
{% for sentence, color in sentences_prediction.items() %}
|
155 |
+
<span class="text-bold text-start bg-{{color[1]}}">
|
156 |
+
{{sentence}}
|
157 |
+
</span>
|
158 |
+
{% endfor %}
|
159 |
+
{% endif %}
|
160 |
+
</div>
|
161 |
+
</div>
|
162 |
+
</div>
|
163 |
+
</div>
|
164 |
+
</div>
|
165 |
+
</div>
|
166 |
+
</div>
|
167 |
+
</div>
|
168 |
+
|
169 |
</div>
|
170 |
</main>
|
171 |
|
templates/pdf_fr.html
ADDED
@@ -0,0 +1,177 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en-US">
|
3 |
+
|
4 |
+
<head>
|
5 |
+
<title>Pdf Categorization</title>
|
6 |
+
<link rel="icon" href="https://cdn-icons-png.flaticon.com/512/5262/5262072.png">
|
7 |
+
<link rel="stylesheet" href="../static/css/style2.css">
|
8 |
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
9 |
+
<link rel="stylesheet" href="../static/css/vendor.bundle.base.css">
|
10 |
+
|
11 |
+
|
12 |
+
</head>
|
13 |
+
|
14 |
+
<body style="background-color: #1F2020;">
|
15 |
+
<nav class="navbar navbar-expand-lg bg-ocr mb-5">
|
16 |
+
<div class="container h-100">
|
17 |
+
<!-- Logo START -->
|
18 |
+
<a class="navbar-brand" href="pdf_fr">
|
19 |
+
<img class="navbar-brand-item" src="../static/icons/avignon_universite_blanc_RVB.png" alt="logo">
|
20 |
+
</a>
|
21 |
+
<!-- Logo END -->
|
22 |
+
|
23 |
+
<!-- Responsive navbar toggler -->
|
24 |
+
<button class="navbar-toggler ms-auto icon-md btn btn-light p-0 collapsed" type="button"
|
25 |
+
data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse"
|
26 |
+
aria-expanded="false" aria-label="Toggle navigation">
|
27 |
+
<span class="navbar-toggler-animation">
|
28 |
+
<span></span>
|
29 |
+
<span></span>
|
30 |
+
<span></span>
|
31 |
+
</span>
|
32 |
+
</button>
|
33 |
+
|
34 |
+
<!-- Main navbar START -->
|
35 |
+
<div class="navbar-collapse collapse" id="navbarCollapse">
|
36 |
+
<ul class="navbar-nav navbar-nav-scroll ms-auto p-xl-0">
|
37 |
+
<!-- Nav item 1 Demos -->
|
38 |
+
<li class="nav-item nav-pills nav-pills-ocr">
|
39 |
+
<a class="nav-item nav-link active mb-5" href="pdf_fr">Classificateur PDF</a>
|
40 |
+
</li>
|
41 |
+
<!-- Nav item 2 Pages -->
|
42 |
+
<li class="nav-item nav-pills nav-pills-ocr">
|
43 |
+
<a class="nav-item nav-link " href="sentence_fr">Classificateur de texte</a>
|
44 |
+
</li>
|
45 |
+
<li class="nav-item nav-pills nav-pills-ocr">
|
46 |
+
<a class="nav-item nav-link " href="voice_fr">SLU</a>
|
47 |
+
</li>
|
48 |
+
<li class="nav-item dropdown">
|
49 |
+
<a class="nav-link" href="#" id="accounntMenu" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">langue</a>
|
50 |
+
<ul class="dropdown-menu" aria-labelledby="accounntMenu">
|
51 |
+
<li> <a class="dropdown-item " href="pdf"><img src="../static/icons/English.svg" class="avatar avatar" style="height: 20px;" alt="French flag"> English</a> </li>
|
52 |
+
</ul>
|
53 |
+
</li>
|
54 |
+
</ul>
|
55 |
+
</div>
|
56 |
+
<!-- Main navbar END -->
|
57 |
+
</div>
|
58 |
+
</nav>
|
59 |
+
<!-- Container START -->
|
60 |
+
<main>
|
61 |
+
<div class="row d-sm-flex justify-content-center ">
|
62 |
+
<div class="col-lg-6 col-11 mb-lg-0 mb-5">
|
63 |
+
<form class="" action="/pdf/upload" style="height: 88%;" id="upload-form" method="POST"
|
64 |
+
enctype="multipart/form-data">
|
65 |
+
|
66 |
+
<div class="drag-image" id="dropArea">
|
67 |
+
<div class="text-center ">
|
68 |
+
<h6 class="text-white-50 mb-3">Glisser-déposer le PDF ici</h6>
|
69 |
+
<span class="text-white-50">OU</span>
|
70 |
+
<h6 class="text-white-50 mt-3">Cliquez ici</h6>
|
71 |
+
<input id="file-input" type="file" name="image" accept=".pdf" hidden>
|
72 |
+
</div>
|
73 |
+
</div>
|
74 |
+
<div class="d-flex justify-content-center">
|
75 |
+
<button class="btn me-3 btn-ocr" id="reset" type="button" onclick="deleteCurrentFile()"> <i
|
76 |
+
class="bi bi-pencil-fill pe-1"></i> Supprimer </button>
|
77 |
+
<button type="submit" class="btn ms-3 btn-ocr">Envoyer</button>
|
78 |
+
</div>
|
79 |
+
</form>
|
80 |
+
</div>
|
81 |
+
<!-- la categorie la plus dominante-->
|
82 |
+
<div class="col-lg-5 col-xl-5 col-11 mt-5 mt-lg-0">
|
83 |
+
<div class="card" style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
|
84 |
+
<div class="card-body text-center" id="static">
|
85 |
+
<div class="col-12 d-flex justify-content-center">
|
86 |
+
<div class="col-sm-12 d-inline align-items-center" style="height: 175px; width: 260px;">
|
87 |
+
<div class="flex-shrink-0 avatar avatar-lg me-2 mb-3 mt-4">
|
88 |
+
<img class="avatar-img rounded-circle"
|
89 |
+
src="../static/icons/logo_header_128x128.png" alt="">
|
90 |
+
</div>
|
91 |
+
<h5 class="card-title text-white-50">Obtenez plus d'informations sur votre pdf 📑📑.</h5>
|
92 |
+
</div>
|
93 |
+
|
94 |
+
</div>
|
95 |
+
</div>
|
96 |
+
<div class="card-body d-none" id="dynamic">
|
97 |
+
<h4 class="card-title text-white">Catégorie du texte</h4>
|
98 |
+
<div class="row d-flex">
|
99 |
+
<div class="col-sm-7 col-6">
|
100 |
+
<ul class="graphl-legend-rectangle" id="class-probabilities">
|
101 |
+
{% for class_label, probability in class_probabilities.items() %}
|
102 |
+
{% if loop.index <= 5 %} <li class="text-white-50">
|
103 |
+
<span class="bg-{{ class_label[1] }}"></span>
|
104 |
+
<div class="d-flex justify-content-center">
|
105 |
+
{{ class_label[0] }}:
|
106 |
+
<span class="text-white w-100"> {{ "%.2f" % probability }}%</span>
|
107 |
+
</div>
|
108 |
+
</li>
|
109 |
+
{% endif %}
|
110 |
+
{% endfor %}
|
111 |
+
</ul>
|
112 |
+
</div>
|
113 |
+
<div class="col-sm-5 grid-margin col-6">
|
114 |
+
<canvas class="bestSellers" data-chart='{{ chart_data | tojson | safe }}'
|
115 |
+
id="bestSellers#"></canvas>
|
116 |
+
</div>
|
117 |
+
</div>
|
118 |
+
<div class="mb-lg-0 text-white-50">
|
119 |
+
la classe la plus dominante est <span class="fw-bolder text-white" id="predicted-class">{{
|
120 |
+
predicted_class[0]
|
121 |
+
}}</span>
|
122 |
+
</div>
|
123 |
+
</div>
|
124 |
+
</div>
|
125 |
+
<!-- <div class="">
|
126 |
+
<textarea id="category-result" readonly>{{predicted_class}}</textarea>
|
127 |
+
</div> -->
|
128 |
+
|
129 |
+
<div class="result mt-3">
|
130 |
+
<h6 class="text-start">Texte extrait</h6>
|
131 |
+
<textarea id="ocr-result" readonly>{{extracted_text}}</textarea>
|
132 |
+
<button id="copy-btn" class="btn btn-ocr">Copier</button>
|
133 |
+
</div>
|
134 |
+
|
135 |
+
<!-- Right sidebar END -->
|
136 |
+
</div> <!-- Row END -->
|
137 |
+
</div>
|
138 |
+
<div class="row d-sm-flex justify-content-center mb-5">
|
139 |
+
<div class="col-11">
|
140 |
+
<div class="row d-none" id='dynamicResult'>
|
141 |
+
<h1 id="resultsHeading" class="text-center text-white-50">Results</h1>
|
142 |
+
<div class="col-12">
|
143 |
+
<div class="card" style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
|
144 |
+
<div class="card-body">
|
145 |
+
<h5 class="card-title text-white mb-3">Transcribed and Classified Text</h5>
|
146 |
+
<div id="transcribedText" class="text-white-50 mb-4"></div>
|
147 |
+
<div class="text-center">
|
148 |
+
<div class="col-12 d-flex justify-content-center">
|
149 |
+
<div class="col-sm-12 d-inline align-items-center" id="classifiedText">
|
150 |
+
{% if sentences_prediction %}
|
151 |
+
{% for sentence, color in sentences_prediction.items() %}
|
152 |
+
<span class="text-bold text-start bg-{{color[1]}}">
|
153 |
+
{{sentence}}
|
154 |
+
</span>
|
155 |
+
{% endfor %}
|
156 |
+
{% endif %}
|
157 |
+
</div>
|
158 |
+
</div>
|
159 |
+
</div>
|
160 |
+
</div>
|
161 |
+
</div>
|
162 |
+
</div>
|
163 |
+
</div>
|
164 |
+
</div>
|
165 |
+
|
166 |
+
</div>
|
167 |
+
</main>
|
168 |
+
|
169 |
+
<!-- Container END -->
|
170 |
+
<script id="dashboard-pdf-script" src="../static/js/dashboard_pdf.js"></script>
|
171 |
+
<script src="../static/js/Chart.min.js"></script>
|
172 |
+
<script src="../static/js/pdf_fr.js" type="text/javascript"></script>
|
173 |
+
<script src="../static/js/vendor.bundle.base.js"></script>
|
174 |
+
|
175 |
+
</body>
|
176 |
+
|
177 |
+
</html>
|
templates/response_fr_sentence.html
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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.0">
|
6 |
+
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
7 |
+
<!-- Include jQuery library -->
|
8 |
+
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
9 |
+
</head>
|
10 |
+
<body>
|
11 |
+
<div class="d-flex flex-column align-items-start">
|
12 |
+
<div class="text-secondary p-2 px-3 rounded-2">
|
13 |
+
<div class="card" style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
|
14 |
+
<div class="card-body">
|
15 |
+
<h4 class="card-title text-white">Text's Category</h4>
|
16 |
+
<div class="row d-flex">
|
17 |
+
<div class="col-sm-6 col-6">
|
18 |
+
<ul class="graphl-legend-rectangle">
|
19 |
+
<!-- Populate categories dynamically -->
|
20 |
+
<!-- class_label has two elements : the class and the color (for display)-->
|
21 |
+
{% for class_label, probability in class_probabilities.items() %}
|
22 |
+
{% if loop.index <= 5 %} <li class="text-white-50">
|
23 |
+
<span class="bg-{{ class_label[1] }}"></span>
|
24 |
+
<div class="d-flex justify-content-center">
|
25 |
+
{{ class_label[0] }}:
|
26 |
+
<span class="text-white w-100"> {{ "%.2f" % probability }}%</span>
|
27 |
+
</div>
|
28 |
+
</li>
|
29 |
+
{% endif %}
|
30 |
+
{% endfor %}
|
31 |
+
|
32 |
+
</ul>
|
33 |
+
</div>
|
34 |
+
<div class="col-sm-6 grid-margin col-6">
|
35 |
+
<canvas class="bestSellers" data-chart = '{{ chart_data | tojson | safe }}' id="bestSellers#"></canvas>
|
36 |
+
</div>
|
37 |
+
</div>
|
38 |
+
<div class="mb-lg-0 text-white-50">
|
39 |
+
la classe la plus dominante est <span class="fw-bolder text-white">{{ predicted_class[0] }}</span>
|
40 |
+
</div>
|
41 |
+
</div>
|
42 |
+
</div>
|
43 |
+
</div>
|
44 |
+
</div>
|
45 |
+
<script>
|
46 |
+
var chartData = {{ chart_data | tojson | safe}};
|
47 |
+
</script>
|
48 |
+
<script src="../static/js/dashboard_sentence.js"></script>
|
49 |
+
</body>
|
50 |
+
</html>
|
templates/sentence.html
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
<html lang="en-US">
|
3 |
|
4 |
<head>
|
5 |
-
<title>
|
6 |
<link rel="icon" href="https://cdn-icons-png.flaticon.com/512/5262/5262072.png">
|
7 |
<link rel="stylesheet" href="../static/css/style2.css">
|
8 |
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
@@ -47,6 +47,12 @@
|
|
47 |
<li class="nav-item nav-pills nav-pills-ocr">
|
48 |
<a class="nav-item nav-link " href="voice">SLU</a>
|
49 |
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
</ul>
|
51 |
</div>
|
52 |
<!-- Main navbar END -->
|
@@ -61,7 +67,7 @@
|
|
61 |
<div class="justify-content-lg-around justify-content-xl-center justify-content-md-between">
|
62 |
|
63 |
<!-- Chat conversation START -->
|
64 |
-
<div class="card card-chat bg-ocr"
|
65 |
<div class="card-body h-100 bg-ocr rounded-2">
|
66 |
<div class="tab-content py-0 mb-0 h-100" id="chatTabsContent">
|
67 |
<!-- Conversation item START -->
|
@@ -75,17 +81,16 @@
|
|
75 |
style="overflow-y: scroll;">
|
76 |
<div class="os-content" style="padding: 0px; height: 100%; width: 100%;">
|
77 |
<!-- Chat message right -->
|
78 |
-
<div class="d-inline mb-1 align-content-between position-relative top-xl-45 top-lg-0 top-lg-30"
|
|
|
79 |
<div class="flex-grow-1 row">
|
80 |
<div class="w-100 col-1 text-center">
|
81 |
<div class="d-flex flex-column">
|
82 |
<div class="text-secondary p-2 px-3 rounded-2">
|
83 |
<div class="card"
|
84 |
style="background-color: #303131;">
|
85 |
-
<div
|
86 |
-
class="
|
87 |
-
<div
|
88 |
-
class="">
|
89 |
<div
|
90 |
class="flex-shrink-0 avatar avatar-lg mb-lg-3 ">
|
91 |
<img class="avatar-img rounded-circle"
|
@@ -106,14 +111,17 @@
|
|
106 |
<div class="flex-grow-1">
|
107 |
<div class="w-100">
|
108 |
<div class="d-flex flex-column align-items-start">
|
109 |
-
<div
|
|
|
110 |
<div class="card"
|
111 |
style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
|
112 |
<div class="card-body">
|
113 |
<h5 class="card-title text-white">
|
114 |
Text Classifier</h5>
|
115 |
<div class="mb-lg-0 text-white-50">
|
116 |
-
Enter a sentence or paragraph in
|
|
|
|
|
117 |
</div>
|
118 |
|
119 |
</div>
|
@@ -127,14 +135,21 @@
|
|
127 |
<div class="flex-grow-1">
|
128 |
<div class="w-100">
|
129 |
<div class="d-flex flex-column align-items-start">
|
130 |
-
<div
|
|
|
131 |
<div class="card"
|
132 |
style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
|
133 |
<div class="card-body">
|
134 |
<h5 class="card-title text-white">
|
135 |
Example</h5>
|
136 |
<div class="mb-lg-0 text-white-50">
|
137 |
-
The sentence <span
|
|
|
|
|
|
|
|
|
|
|
|
|
138 |
</div>
|
139 |
|
140 |
</div>
|
@@ -172,14 +187,16 @@
|
|
172 |
</div>
|
173 |
|
174 |
<div class="card-footer" style="background-color: #242525;">
|
175 |
-
<form class="d-flex align-items-center" action="/sentence" method="post" id="sentenceForm"
|
|
|
176 |
<textarea class="form-control mb-sm-0 mb-3" id="ocr-result" name="text" data-autoresize=""
|
177 |
placeholder="Type your text" rows="1" style="height: 50px;box-sizing: border-box;
|
178 |
-
resize: none; max-height: 120px;" onclick="addAutoResize()"
|
|
|
179 |
<button class="btn btn-sm btn-sentence ms-2" type="submit"><img class="avatar avatar-xs"
|
180 |
src="../static/icons/avignon_universite_blanc_RVB-1.png"></button>
|
181 |
</form>
|
182 |
-
</div>
|
183 |
</div>
|
184 |
<!-- Chat conversation END -->
|
185 |
</div> <!-- Row END -->
|
|
|
2 |
<html lang="en-US">
|
3 |
|
4 |
<head>
|
5 |
+
<title>Chat Categorization</title>
|
6 |
<link rel="icon" href="https://cdn-icons-png.flaticon.com/512/5262/5262072.png">
|
7 |
<link rel="stylesheet" href="../static/css/style2.css">
|
8 |
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
|
|
47 |
<li class="nav-item nav-pills nav-pills-ocr">
|
48 |
<a class="nav-item nav-link " href="voice">SLU</a>
|
49 |
</li>
|
50 |
+
<li class="nav-item dropdown">
|
51 |
+
<a class="nav-link" href="#" id="accounntMenu" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">language</a>
|
52 |
+
<ul class="dropdown-menu" aria-labelledby="accounntMenu">
|
53 |
+
<li> <a class="dropdown-item " href="sentence_fr"><img src="../static/icons/France.svg" class="avatar avatar" style="height: 20px;" alt="French flag"> French</a> </li>
|
54 |
+
</ul>
|
55 |
+
</li>
|
56 |
</ul>
|
57 |
</div>
|
58 |
<!-- Main navbar END -->
|
|
|
67 |
<div class="justify-content-lg-around justify-content-xl-center justify-content-md-between">
|
68 |
|
69 |
<!-- Chat conversation START -->
|
70 |
+
<div class="card card-chat bg-ocr">
|
71 |
<div class="card-body h-100 bg-ocr rounded-2">
|
72 |
<div class="tab-content py-0 mb-0 h-100" id="chatTabsContent">
|
73 |
<!-- Conversation item START -->
|
|
|
81 |
style="overflow-y: scroll;">
|
82 |
<div class="os-content" style="padding: 0px; height: 100%; width: 100%;">
|
83 |
<!-- Chat message right -->
|
84 |
+
<div class="d-inline mb-1 align-content-between position-relative top-xl-45 top-lg-0 top-lg-30"
|
85 |
+
id="presentation">
|
86 |
<div class="flex-grow-1 row">
|
87 |
<div class="w-100 col-1 text-center">
|
88 |
<div class="d-flex flex-column">
|
89 |
<div class="text-secondary p-2 px-3 rounded-2">
|
90 |
<div class="card"
|
91 |
style="background-color: #303131;">
|
92 |
+
<div class="card-body">
|
93 |
+
<div class="">
|
|
|
|
|
94 |
<div
|
95 |
class="flex-shrink-0 avatar avatar-lg mb-lg-3 ">
|
96 |
<img class="avatar-img rounded-circle"
|
|
|
111 |
<div class="flex-grow-1">
|
112 |
<div class="w-100">
|
113 |
<div class="d-flex flex-column align-items-start">
|
114 |
+
<div
|
115 |
+
class="text-secondary p-2 px-3 rounded-2 w-100">
|
116 |
<div class="card"
|
117 |
style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
|
118 |
<div class="card-body">
|
119 |
<h5 class="card-title text-white">
|
120 |
Text Classifier</h5>
|
121 |
<div class="mb-lg-0 text-white-50">
|
122 |
+
Enter a sentence or paragraph in
|
123 |
+
the text box below to discover
|
124 |
+
its category.
|
125 |
</div>
|
126 |
|
127 |
</div>
|
|
|
135 |
<div class="flex-grow-1">
|
136 |
<div class="w-100">
|
137 |
<div class="d-flex flex-column align-items-start">
|
138 |
+
<div
|
139 |
+
class="text-secondary p-2 px-3 rounded-2 w-100">
|
140 |
<div class="card"
|
141 |
style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
|
142 |
<div class="card-body">
|
143 |
<h5 class="card-title text-white">
|
144 |
Example</h5>
|
145 |
<div class="mb-lg-0 text-white-50">
|
146 |
+
The sentence <span
|
147 |
+
class="text-white">'Chatbots
|
148 |
+
use AI to communicate with
|
149 |
+
users'</span> is categorized
|
150 |
+
as <span class="text-white">
|
151 |
+
'Artificial Intelligence'
|
152 |
+
</span> .
|
153 |
</div>
|
154 |
|
155 |
</div>
|
|
|
187 |
</div>
|
188 |
|
189 |
<div class="card-footer" style="background-color: #242525;">
|
190 |
+
<form class="d-flex align-items-center" action="/sentence" method="post" id="sentenceForm"
|
191 |
+
onsubmit="submitForm(event)">
|
192 |
<textarea class="form-control mb-sm-0 mb-3" id="ocr-result" name="text" data-autoresize=""
|
193 |
placeholder="Type your text" rows="1" style="height: 50px;box-sizing: border-box;
|
194 |
+
resize: none; max-height: 120px;" onclick="addAutoResize()"
|
195 |
+
onkeydown="handleEnter(event)" required></textarea>
|
196 |
<button class="btn btn-sm btn-sentence ms-2" type="submit"><img class="avatar avatar-xs"
|
197 |
src="../static/icons/avignon_universite_blanc_RVB-1.png"></button>
|
198 |
</form>
|
199 |
+
</div>
|
200 |
</div>
|
201 |
<!-- Chat conversation END -->
|
202 |
</div> <!-- Row END -->
|
templates/sentence_fr.html
ADDED
@@ -0,0 +1,229 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en-US">
|
3 |
+
|
4 |
+
<head>
|
5 |
+
<title>Chat Categorization</title>
|
6 |
+
<link rel="icon" href="https://cdn-icons-png.flaticon.com/512/5262/5262072.png">
|
7 |
+
<link rel="stylesheet" href="../static/css/style2.css">
|
8 |
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
9 |
+
<link rel="stylesheet" href="../static/css/vendor.bundle.base.css">
|
10 |
+
<link rel="stylesheet" href="../static/css/OverlayScrollbars.min.css">
|
11 |
+
|
12 |
+
|
13 |
+
</head>
|
14 |
+
|
15 |
+
<body style="background-color: #1F2020">
|
16 |
+
<header>
|
17 |
+
<nav class="navbar navbar-expand-lg bg-ocr mb-5">
|
18 |
+
<div class="container h-100">
|
19 |
+
<!-- Logo START -->
|
20 |
+
<a class="navbar-brand" href="pdf_fr">
|
21 |
+
<img class="navbar-brand-item" src="../static/icons/avignon_universite_blanc_RVB.png" alt="logo">
|
22 |
+
</a>
|
23 |
+
<!-- Logo END -->
|
24 |
+
|
25 |
+
<!-- Responsive navbar toggler -->
|
26 |
+
<button class="navbar-toggler ms-auto icon-md btn btn-light p-0 collapsed" type="button"
|
27 |
+
data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse"
|
28 |
+
aria-expanded="false" aria-label="Toggle navigation">
|
29 |
+
<span class="navbar-toggler-animation">
|
30 |
+
<span></span>
|
31 |
+
<span></span>
|
32 |
+
<span></span>
|
33 |
+
</span>
|
34 |
+
</button>
|
35 |
+
|
36 |
+
<!-- Main navbar START -->
|
37 |
+
<div class="navbar-collapse collapse" id="navbarCollapse">
|
38 |
+
<ul class="navbar-nav navbar-nav-scroll ms-auto p-xl-0">
|
39 |
+
<!-- Nav item 1 Demos -->
|
40 |
+
<li class="nav-item nav-pills nav-pills-ocr">
|
41 |
+
<a class="nav-item nav-link" href="pdf_fr">Classificateur PDF</a>
|
42 |
+
</li>
|
43 |
+
<!-- Nav item 2 Pages -->
|
44 |
+
<li class="nav-item nav-pills nav-pills-ocr">
|
45 |
+
<a class="nav-item nav-link active" href="sentence_fr">Classificateur de texte</a>
|
46 |
+
</li>
|
47 |
+
<li class="nav-item nav-pills nav-pills-ocr">
|
48 |
+
<a class="nav-item nav-link " href="voice_fr">SLU</a>
|
49 |
+
</li>
|
50 |
+
<li class="nav-item dropdown">
|
51 |
+
<a class="nav-link" href="#" id="accounntMenu" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">langue</a>
|
52 |
+
<ul class="dropdown-menu" aria-labelledby="accounntMenu">
|
53 |
+
<li> <a class="dropdown-item " href="sentence"><img src="../static/icons/English.svg" class="avatar avatar" style="height: 20px;" alt="French flag"> English</a> </li>
|
54 |
+
</ul>
|
55 |
+
</li>
|
56 |
+
</ul>
|
57 |
+
</div>
|
58 |
+
<!-- Main navbar END -->
|
59 |
+
</div>
|
60 |
+
</nav>
|
61 |
+
</header>
|
62 |
+
|
63 |
+
<main class="pt-3 pt-md-5 pb-md-5 pt-lg-0 mt-3 ">
|
64 |
+
|
65 |
+
<!-- Container START -->
|
66 |
+
<div class="container mt-lg-7 ">
|
67 |
+
<div class="justify-content-lg-around justify-content-xl-center justify-content-md-between">
|
68 |
+
|
69 |
+
<!-- Chat conversation START -->
|
70 |
+
<div class="card card-chat bg-ocr">
|
71 |
+
<div class="card-body h-100 bg-ocr rounded-2">
|
72 |
+
<div class="tab-content py-0 mb-0 h-100" id="chatTabsContent">
|
73 |
+
<!-- Conversation item START -->
|
74 |
+
<div class="fade tab-pane show active h-100" id="chat-1" role="tabpanel"
|
75 |
+
aria-labelledby="chat-1-tab">
|
76 |
+
<!-- Chat conversation START -->
|
77 |
+
<div
|
78 |
+
class="chat-conversation-content custom-scrollbar os-host os-theme-dark os-host-overflow os-host-overflow-y os-host-resize-disabled os-host-scrollbar-horizontal-hidden os-host-transition h-100">
|
79 |
+
<div class="os-padding">
|
80 |
+
<div class="os-viewport os-viewport-native-scrollbars-invisible"
|
81 |
+
style="overflow-y: scroll;">
|
82 |
+
<div class="os-content" style="padding: 0px; height: 100%; width: 100%;">
|
83 |
+
<!-- Chat message right -->
|
84 |
+
<div class="d-inline mb-1 align-content-between position-relative top-xl-45 top-lg-0 top-lg-30"
|
85 |
+
id="presentation">
|
86 |
+
<div class="flex-grow-1 row">
|
87 |
+
<div class="w-100 col-1 text-center">
|
88 |
+
<div class="d-flex flex-column">
|
89 |
+
<div class="text-secondary p-2 px-3 rounded-2">
|
90 |
+
<div class="card"
|
91 |
+
style="background-color: #303131;">
|
92 |
+
<div class="card-body">
|
93 |
+
<div class="">
|
94 |
+
<div
|
95 |
+
class="flex-shrink-0 avatar avatar-lg mb-lg-3 ">
|
96 |
+
<img class="avatar-img rounded-circle"
|
97 |
+
src="../static/icons/logo_header_128x128.png"
|
98 |
+
alt="">
|
99 |
+
</div>
|
100 |
+
<h4 class="text-white">Comment puis-je vous aider aujourd'hui ?</h4>
|
101 |
+
</div>
|
102 |
+
</div>
|
103 |
+
</div>
|
104 |
+
</div>
|
105 |
+
</div>
|
106 |
+
</div>
|
107 |
+
</div>
|
108 |
+
<div class="row d-flex justify-content-center">
|
109 |
+
<div class="col-lg-6 ">
|
110 |
+
<div class="flex-grow-1">
|
111 |
+
<div class="w-100">
|
112 |
+
<div class="d-flex flex-column align-items-start">
|
113 |
+
<div
|
114 |
+
class="text-secondary p-2 px-3 rounded-2 w-100">
|
115 |
+
<div class="card"
|
116 |
+
style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
|
117 |
+
<div class="card-body">
|
118 |
+
<h5 class="card-title text-white">
|
119 |
+
Classificateur de texte</h5>
|
120 |
+
<div class="mb-lg-0 text-white-50">
|
121 |
+
Saisissez une phrase ou un paragraphe dans la zone de texte ci-dessous pour découvrir sa catégorie.
|
122 |
+
</div>
|
123 |
+
|
124 |
+
</div>
|
125 |
+
</div>
|
126 |
+
</div>
|
127 |
+
</div>
|
128 |
+
</div>
|
129 |
+
</div>
|
130 |
+
</div>
|
131 |
+
<div class="col-lg-6 ">
|
132 |
+
<div class="flex-grow-1">
|
133 |
+
<div class="w-100">
|
134 |
+
<div class="d-flex flex-column align-items-start">
|
135 |
+
<div
|
136 |
+
class="text-secondary p-2 px-3 rounded-2 w-100">
|
137 |
+
<div class="card"
|
138 |
+
style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
|
139 |
+
<div class="card-body">
|
140 |
+
<h5 class="card-title text-white">
|
141 |
+
Exemple</h5>
|
142 |
+
<div class="mb-lg-0 text-white-50">
|
143 |
+
La phrase <span
|
144 |
+
class="text-white">'Les chatbots utilisent l'IA pour communiquer avec les utilisateurs'</span> est classée <span class="text-white">
|
145 |
+
'Artificial Intelligence'
|
146 |
+
</span> .
|
147 |
+
</div>
|
148 |
+
|
149 |
+
</div>
|
150 |
+
</div>
|
151 |
+
</div>
|
152 |
+
</div>
|
153 |
+
</div>
|
154 |
+
</div>
|
155 |
+
</div>
|
156 |
+
</div>
|
157 |
+
</div>
|
158 |
+
<!-- Chat message left -->
|
159 |
+
</div>
|
160 |
+
</div>
|
161 |
+
</div>
|
162 |
+
<div
|
163 |
+
class="os-scrollbar os-scrollbar-horizontal os-scrollbar-unusable os-scrollbar-auto-hidden">
|
164 |
+
<div class="os-scrollbar-track os-scrollbar-track-off">
|
165 |
+
<div class="os-scrollbar-handle"
|
166 |
+
style="width: 100%; transform: translate(0px, 0px);"></div>
|
167 |
+
</div>
|
168 |
+
</div>
|
169 |
+
<div class="os-scrollbar os-scrollbar-vertical os-scrollbar-auto-hidden">
|
170 |
+
<div class="os-scrollbar-track os-scrollbar-track-off">
|
171 |
+
<div class="os-scrollbar-handle"
|
172 |
+
style="height: 32.4192%; transform: translate(0px, 0px);"></div>
|
173 |
+
</div>
|
174 |
+
</div>
|
175 |
+
<div class="os-scrollbar-corner"></div>
|
176 |
+
</div>
|
177 |
+
<!-- Chat conversation END -->
|
178 |
+
</div>
|
179 |
+
<!-- Conversation item END -->
|
180 |
+
</div>
|
181 |
+
</div>
|
182 |
+
|
183 |
+
<div class="card-footer" style="background-color: #242525;">
|
184 |
+
<form class="d-flex align-items-center" action="/sentence_fr" method="post" id="sentenceForm"
|
185 |
+
onsubmit="submitForm(event)">
|
186 |
+
<textarea class="form-control mb-sm-0 mb-3" id="ocr-result" name="text" data-autoresize=""
|
187 |
+
placeholder="Saisir votre texte" rows="1" style="height: 50px;box-sizing: border-box;
|
188 |
+
resize: none; max-height: 120px;" onclick="addAutoResize()"
|
189 |
+
onkeydown="handleEnter(event)" required></textarea>
|
190 |
+
<button class="btn btn-sm btn-sentence ms-2" type="submit"><img class="avatar avatar-xs"
|
191 |
+
src="../static/icons/avignon_universite_blanc_RVB-1.png"></button>
|
192 |
+
</form>
|
193 |
+
</div>
|
194 |
+
</div>
|
195 |
+
<!-- Chat conversation END -->
|
196 |
+
</div> <!-- Row END -->
|
197 |
+
<!-- =======================
|
198 |
+
Chat END -->
|
199 |
+
|
200 |
+
</div>
|
201 |
+
<!-- Container END -->
|
202 |
+
|
203 |
+
</main>
|
204 |
+
<!-- Container END -->
|
205 |
+
<script src="../static/js/sentence_fr.js" type="text/javascript"></script>
|
206 |
+
<script src="../static/js/vendor.bundle.base.js"></script>
|
207 |
+
<script src="../static/js/Chart.min.js"></script>
|
208 |
+
<!-- Custom js for this page-->
|
209 |
+
|
210 |
+
<script src="../static/js/bootstrap.bundle.min.js"></script>
|
211 |
+
<script src="../static/js/OverlayScrollbars.min.js"></script>
|
212 |
+
<script>
|
213 |
+
// START: 12 Auto resize textarea
|
214 |
+
function addAutoResize() {
|
215 |
+
document.querySelectorAll('[data-autoresize]').forEach(function (element) {
|
216 |
+
element.style.boxSizing = 'border-box';
|
217 |
+
var offset = element.offsetHeight - element.clientHeight;
|
218 |
+
element.addEventListener('input', function (event) {
|
219 |
+
event.target.style.height = 'auto';
|
220 |
+
event.target.style.height = event.target.scrollHeight + offset + 'px';
|
221 |
+
});
|
222 |
+
element.removeAttribute('data-autoresize');
|
223 |
+
});
|
224 |
+
}
|
225 |
+
// END: Auto resize textarea
|
226 |
+
</script>
|
227 |
+
</body>
|
228 |
+
|
229 |
+
</html>
|
templates/voice.html
CHANGED
@@ -41,6 +41,12 @@
|
|
41 |
<li class="nav-item nav-pills nav-pills-ocr">
|
42 |
<a class="nav-item nav-link active" href="voice">SLU</a>
|
43 |
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
</ul>
|
45 |
</div>
|
46 |
<!-- Main navbar END -->
|
|
|
41 |
<li class="nav-item nav-pills nav-pills-ocr">
|
42 |
<a class="nav-item nav-link active" href="voice">SLU</a>
|
43 |
</li>
|
44 |
+
<li class="nav-item dropdown">
|
45 |
+
<a class="nav-link" href="#" id="accounntMenu" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">language</a>
|
46 |
+
<ul class="dropdown-menu" aria-labelledby="accounntMenu">
|
47 |
+
<li> <a class="dropdown-item " href="voice_fr"><img src="../static/icons/France.svg" class="avatar avatar" style="height: 20px;" alt="French flag"> French</a> </li>
|
48 |
+
</ul>
|
49 |
+
</li>
|
50 |
</ul>
|
51 |
</div>
|
52 |
<!-- Main navbar END -->
|
templates/voice_fr.html
ADDED
@@ -0,0 +1,235 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en-US">
|
3 |
+
|
4 |
+
<head>
|
5 |
+
<title>Speech Transcription</title>
|
6 |
+
<link rel="icon" href="https://cdn-icons-png.flaticon.com/512/5262/5262072.png">
|
7 |
+
<link rel="stylesheet" href="../static/css/style2.css">
|
8 |
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
9 |
+
<link rel="stylesheet" href="../static/css/vendor.bundle.base.css">
|
10 |
+
</head>
|
11 |
+
|
12 |
+
<body style="background-color: #1F2020;">
|
13 |
+
<nav class="navbar navbar-expand-lg bg-ocr mb-5">
|
14 |
+
<div class="container h-100">
|
15 |
+
<!-- Logo START -->
|
16 |
+
<a class="navbar-brand" href="pdf_fr">
|
17 |
+
<img class="navbar-brand-item" src="../static/icons/avignon_universite_blanc_RVB.png" alt="logo">
|
18 |
+
</a>
|
19 |
+
<!-- Logo END -->
|
20 |
+
|
21 |
+
<!-- Responsive navbar toggler -->
|
22 |
+
<button class="navbar-toggler ms-auto icon-md btn btn-light p-0 collapsed" type="button"
|
23 |
+
data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse"
|
24 |
+
aria-expanded="false" aria-label="Toggle navigation">
|
25 |
+
<span class="navbar-toggler-animation">
|
26 |
+
<span></span>
|
27 |
+
<span></span>
|
28 |
+
<span></span>
|
29 |
+
</span>
|
30 |
+
</button>
|
31 |
+
|
32 |
+
<!-- Main navbar START -->
|
33 |
+
<div class="navbar-collapse collapse" id="navbarCollapse">
|
34 |
+
<ul class="navbar-nav navbar-nav-scroll ms-auto p-xl-0">
|
35 |
+
<!-- Nav item 1 Demos -->
|
36 |
+
<li class="nav-item nav-pills nav-pills-ocr">
|
37 |
+
<a class="nav-item nav-link" href="pdf_fr">Classificateur PDF</a>
|
38 |
+
</li>
|
39 |
+
<!-- Nav item 2 Pages -->
|
40 |
+
<li class="nav-item nav-pills nav-pills-ocr">
|
41 |
+
<a class="nav-item nav-link " href="sentence_fr">Classificateur de texte</a>
|
42 |
+
</li>
|
43 |
+
<li class="nav-item nav-pills nav-pills-ocr">
|
44 |
+
<a class="nav-item nav-link active" href="voice_fr">SLU</a>
|
45 |
+
</li>
|
46 |
+
<li class="nav-item dropdown">
|
47 |
+
<a class="nav-link" href="#" id="accounntMenu" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">langue</a>
|
48 |
+
<ul class="dropdown-menu" aria-labelledby="accounntMenu">
|
49 |
+
<li> <a class="dropdown-item " href="voice"><img src="../static/icons/English.svg" class="avatar avatar" style="height: 20px;" alt="French flag"> English</a> </li>
|
50 |
+
</ul>
|
51 |
+
</li>
|
52 |
+
</ul>
|
53 |
+
</div>
|
54 |
+
<!-- Main navbar END -->
|
55 |
+
</div>
|
56 |
+
</nav>
|
57 |
+
|
58 |
+
<main class="pt-3 pt-md-5 pb-md-5 pt-lg-0 mt-3">
|
59 |
+
<div class="container mt-lg-7">
|
60 |
+
<div class="row">
|
61 |
+
<div class="col-lg-6 mb-4">
|
62 |
+
<div class="card bg-ocr h-100">
|
63 |
+
<div class="card-body">
|
64 |
+
<h5 class="card-title text-white">Enregistrement du discours</h5>
|
65 |
+
<p class="card-text text-white-50">Cliquez sur le bouton pour commencer à enregistrer votre discours.</p>
|
66 |
+
<div class="mt-auto text-center">
|
67 |
+
<button id="startRecord" class="btn btn-ocr">Démarrer l'enregistrement</button>
|
68 |
+
<button id="stopRecord" class="btn btn-green" disabled>Arrêter l'enregistrement</button>
|
69 |
+
</div>
|
70 |
+
</div>
|
71 |
+
</div>
|
72 |
+
</div>
|
73 |
+
<div class="col-lg-6 mb-4">
|
74 |
+
<div class="card bg-ocr">
|
75 |
+
<div class="card-body">
|
76 |
+
<h5 class="card-title text-white">Télécharger un fichier audio</h5>
|
77 |
+
<p class="card-text text-white-50">Cliquez ou faites un glisser-déposer pour télécharger un fichier audio.</p>
|
78 |
+
<div class="file-upload-wrapper" id="fileUploadWrapper">
|
79 |
+
<input type="file" id="audioFileInput" accept="audio/*">
|
80 |
+
<div class="file-upload-text">
|
81 |
+
<i class="bi bi-cloud-upload" style="font-size: 2rem;"></i>
|
82 |
+
<p>Cliquez ou glissez le fichier audio ici</p>
|
83 |
+
<p class="file-name"></p>
|
84 |
+
</div>
|
85 |
+
</div>
|
86 |
+
<div class="text-center">
|
87 |
+
<button id="uploadAudio" class="btn btn-ocr mt-3 text-center">Télécharger et transcrire</button>
|
88 |
+
</div>
|
89 |
+
</div>
|
90 |
+
</div>
|
91 |
+
</div>
|
92 |
+
</div>
|
93 |
+
<h1 class="text-center text-white-50"> R��sultats</h1>
|
94 |
+
<div class="card" id = 'static' style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
|
95 |
+
<div class="card-body text-center" id="static">
|
96 |
+
<div class="col-12 d-flex justify-content-center">
|
97 |
+
<div class="col-sm-12 d-inline align-items-center" style="height: 175px; width: 290px;">
|
98 |
+
<div class="flex-shrink-0 avatar avatar-lg me-2 mb-3 mt-4">
|
99 |
+
<img class="avatar-img rounded-circle"
|
100 |
+
src="../static/icons/logo_header_128x128.png" alt="">
|
101 |
+
</div>
|
102 |
+
<h5 class="card-title text-white-50">Obtenez plus d'informations sur votre discours 📣📢.</h5>
|
103 |
+
</div>
|
104 |
+
|
105 |
+
</div>
|
106 |
+
</div>
|
107 |
+
</div>
|
108 |
+
<div class="row d-none" id = 'dynamic'>
|
109 |
+
<div class="col-4">
|
110 |
+
<div class="nav flex-column position-sticky top-10 shadow-lg" style="background-color: #222424;">
|
111 |
+
<div class="card mb-3" style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
|
112 |
+
<div class="card-body">
|
113 |
+
<h4 class="card-title text-white">Catégorie du texte</h4>
|
114 |
+
<div class="row d-flex">
|
115 |
+
<div class="col-sm-7 col-6">
|
116 |
+
<ul class="graphl-legend-rectangle" id="class-probabilities">
|
117 |
+
{% if class_probabilities %}
|
118 |
+
{% for class_label, probability in class_probabilities.items() %}
|
119 |
+
{% if loop.index <= 5 %}
|
120 |
+
<li class="text-white-50">
|
121 |
+
<span class="bg-{{ class_label[1] }}"></span>
|
122 |
+
<div class="d-flex justify-content-center">
|
123 |
+
{{ class_label[0] }}:
|
124 |
+
<span class="text-white w-100"> {{ "%.2f" % (probability) }}%</span>
|
125 |
+
</div>
|
126 |
+
</li>
|
127 |
+
{% endif %}
|
128 |
+
{% endfor %}
|
129 |
+
{% endif %}
|
130 |
+
</ul>
|
131 |
+
</div>
|
132 |
+
<div class="col-sm-5 grid-margin col-6">
|
133 |
+
<canvas class="bestSellers" data-chart='{{ chart_data | tojson}}'
|
134 |
+
id="bestSellers"></canvas>
|
135 |
+
</div>
|
136 |
+
</div>
|
137 |
+
<div class="mb-lg-0 text-white-50">
|
138 |
+
la classe la plus dominante est <span class="fw-bolder text-white"
|
139 |
+
id="predicted-class">{{
|
140 |
+
predicted_class[0] if predicted_class else ""
|
141 |
+
}}</span>
|
142 |
+
</div>
|
143 |
+
</div>
|
144 |
+
</div>
|
145 |
+
<div class="card my-auto mt-3"
|
146 |
+
style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
|
147 |
+
<div class="card-body">
|
148 |
+
<h4 class="card-title text-white">Légende</h4>
|
149 |
+
<div class="row d-flex">
|
150 |
+
<div class="col-sm-6 col-6">
|
151 |
+
<ul class="graphl-legend-rectangle">
|
152 |
+
<li class="text-white-50"><span class="bg-info "></span>vehicles
|
153 |
+
</li>
|
154 |
+
<li class="text-white-50"><span class="bg-success"></span>environments
|
155 |
+
</li>
|
156 |
+
<li class="text-white-50"><span class="bg-danger"></span>energies
|
157 |
+
</li>
|
158 |
+
<li class="text-white-50"><span class="bg-primary"></span>Physics
|
159 |
+
</li>
|
160 |
+
<li class="text-white-50"><span class="bg-moss"></span>robotics
|
161 |
+
</li>
|
162 |
+
<li class="text-white-50"><span class="bg-agri"></span>agriculture
|
163 |
+
</li>
|
164 |
+
<li class="text-white-50"><span class="bg-yellow"></span>ML
|
165 |
+
</li>
|
166 |
+
<li class="text-white-50"><span class="bg-warning"></span>economies
|
167 |
+
</li>
|
168 |
+
<li class="text-white-50"><span class="bg-vanila"></span>technologies
|
169 |
+
</li>
|
170 |
+
</ul>
|
171 |
+
</div>
|
172 |
+
<div class="col-sm-6 col-6">
|
173 |
+
<ul class="graphl-legend-rectangle">
|
174 |
+
|
175 |
+
<li class="text-white-50"><span class="bg-coffe"></span>mathematics
|
176 |
+
</li>
|
177 |
+
<li class="text-white-50"><span class="bg-orange "></span>sports
|
178 |
+
</li>
|
179 |
+
<li class="text-white-50"><span class="bg-cyan"></span>AI
|
180 |
+
</li>
|
181 |
+
<li class="text-white-50"><span class="bg-rosy"></span>Innovation
|
182 |
+
</li>
|
183 |
+
<li class="text-white-50"><span class="bg-picton"></span>Science
|
184 |
+
</li>
|
185 |
+
<li class="text-white-50"><span class="bg-purple"></span>Societies
|
186 |
+
</li>
|
187 |
+
<li class="text-white-50"><span class="bg-pink"></span>administration
|
188 |
+
</li>
|
189 |
+
<li class="text-white-50"><span class="bg-cambridge"></span>biology
|
190 |
+
</li>
|
191 |
+
</ul>
|
192 |
+
</div>
|
193 |
+
</div>
|
194 |
+
</div>
|
195 |
+
</div>
|
196 |
+
</div>
|
197 |
+
</div>
|
198 |
+
|
199 |
+
<div class="col-8">
|
200 |
+
<div class="card" style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
|
201 |
+
<div class="card-body">
|
202 |
+
<h5 class="card-title text-white mb-3">Texte transcrit et classifié</h5>
|
203 |
+
<div id="transcribedText" class="text-white-50 mb-4"></div>
|
204 |
+
<div id="static" class="text-center">
|
205 |
+
<div class="col-12 d-flex justify-content-center">
|
206 |
+
<div class="col-sm-12 d-inline align-items-center" id="classifiedText">
|
207 |
+
{% if sentences_prediction %}
|
208 |
+
{% for sentence, color in sentences_prediction.items() %}
|
209 |
+
<span class="text-bold text-start bg-{{color[1]}}">
|
210 |
+
{{sentence}}
|
211 |
+
</span>
|
212 |
+
{% endfor %}
|
213 |
+
{% endif %}
|
214 |
+
</div>
|
215 |
+
</div>
|
216 |
+
</div>
|
217 |
+
</div>
|
218 |
+
</div>
|
219 |
+
</div>
|
220 |
+
</div>
|
221 |
+
</div>
|
222 |
+
</main>
|
223 |
+
|
224 |
+
<div id="loadingIndicator" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); z-index: 9999;">
|
225 |
+
<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: white;">
|
226 |
+
Processing...
|
227 |
+
</div>
|
228 |
+
</div>
|
229 |
+
|
230 |
+
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
231 |
+
<script src="../static/js/voice.js" type="text/javascript"></script>
|
232 |
+
<script src="../static/js/vendor.bundle.base.js"></script>
|
233 |
+
</body>
|
234 |
+
|
235 |
+
</html>
|