Spaces:
No application file
No application file
Jacob Molnia
commited on
Commit
•
8b058a4
1
Parent(s):
22dbe21
inital draft for deplyment
Browse files- app/.DS_Store +0 -0
- requirements.txt → app/requirements.txt +0 -1
- app.py → app/src/app.py +0 -0
- app/tests/test_app.py +47 -0
- deployment/.DS_Store +0 -0
- deployment/01_deploy_to_app/.DS_Store +0 -0
- deployment/01_deploy_to_app/ansible.cfg +5 -0
- deployment/01_deploy_to_app/inventory/hosts.ini +3 -0
- deployment/01_deploy_to_app/playbooks/deploy_gradio_app.yml +77 -0
- deployment/01_deploy_to_app/playbooks/install_tailscale.yml +29 -0
- deployment/01_deploy_to_app/playbooks/main.yml +8 -0
- deployment/01_deploy_to_app/playbooks/setup_users.yml +51 -0
- deployment/01_deploy_to_app/templates/gradio_app.service.j2 +12 -0
- deployment/01_deploy_to_app/vars/secrets.yml +14 -0
- deployment/02_deploy_to_controller/.DS_Store +0 -0
- deployment/02_deploy_to_controller/ansible.cfg +11 -0
- deployment/02_deploy_to_controller/inventory/hosts.ini +2 -0
- deployment/02_deploy_to_controller/playbooks/install_tailscale.yml +30 -0
- deployment/02_deploy_to_controller/playbooks/main.yml +44 -0
- deployment/02_deploy_to_controller/playbooks/setup_ansible.yml +16 -0
- deployment/02_deploy_to_controller/scripts/initial_ssh_config.sh +5 -0
- deployment/02_deploy_to_controller/vars/secrets.yml +10 -0
app/.DS_Store
ADDED
Binary file (6.15 kB). View file
|
|
requirements.txt → app/requirements.txt
RENAMED
@@ -3,4 +3,3 @@ gradio==4.39.*
|
|
3 |
torch==2.4.*
|
4 |
transformers==4.43.*
|
5 |
accelerate==0.33.*
|
6 |
-
pytest==7.4.3
|
|
|
3 |
torch==2.4.*
|
4 |
transformers==4.43.*
|
5 |
accelerate==0.33.*
|
|
app.py → app/src/app.py
RENAMED
File without changes
|
app/tests/test_app.py
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pytest
|
2 |
+
import sys
|
3 |
+
import os
|
4 |
+
|
5 |
+
# Add the parent directory to the Python path
|
6 |
+
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
7 |
+
|
8 |
+
from app import clear_conversation, update_chat_info, cancel_inference, respond, custom_css, demo
|
9 |
+
|
10 |
+
def test_clear_conversation():
|
11 |
+
result = clear_conversation()
|
12 |
+
assert result is None
|
13 |
+
|
14 |
+
def test_update_chat_info_empty():
|
15 |
+
history = None
|
16 |
+
message_count, word_count = update_chat_info(history)
|
17 |
+
assert message_count == 0
|
18 |
+
assert word_count == 0
|
19 |
+
|
20 |
+
def test_cancel_inference():
|
21 |
+
cancel_inference()
|
22 |
+
from app import stop_inference
|
23 |
+
assert stop_inference == True
|
24 |
+
|
25 |
+
def test_respond_input_types():
|
26 |
+
message = "Test message"
|
27 |
+
history = [("User", "Hello"), ("Bot", "Hi")]
|
28 |
+
system_message = "You are a test bot"
|
29 |
+
max_tokens = 100
|
30 |
+
temperature = 0.7
|
31 |
+
top_p = 0.9
|
32 |
+
use_local_model = False
|
33 |
+
|
34 |
+
generator = respond(message, history, system_message, max_tokens, temperature, top_p, use_local_model)
|
35 |
+
|
36 |
+
assert hasattr(generator, '__next__') # Check if it's a generator
|
37 |
+
|
38 |
+
def test_custom_css_exists():
|
39 |
+
assert isinstance(custom_css, str)
|
40 |
+
assert len(custom_css) > 0
|
41 |
+
|
42 |
+
def test_demo_object_creation():
|
43 |
+
assert demo is not None
|
44 |
+
assert hasattr(demo, 'launch')
|
45 |
+
|
46 |
+
if __name__ == "__main__":
|
47 |
+
pytest.main([__file__])
|
deployment/.DS_Store
ADDED
Binary file (6.15 kB). View file
|
|
deployment/01_deploy_to_app/.DS_Store
ADDED
Binary file (6.15 kB). View file
|
|
deployment/01_deploy_to_app/ansible.cfg
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[defaults]
|
2 |
+
inventory = inventory/hosts.ini
|
3 |
+
remote_user = student-admin
|
4 |
+
private_key_file = ~/.ssh/keys/id_admin_cs553
|
5 |
+
|
deployment/01_deploy_to_app/inventory/hosts.ini
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
[classserver]
|
2 |
+
server1 ansible_host=paffenroth-23.dyn.wpi.edu ansible_port=22018
|
3 |
+
#server1Tailscail ansible_host=group18
|
deployment/01_deploy_to_app/playbooks/deploy_gradio_app.yml
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
- name: Deploy Gradio App
|
3 |
+
hosts: all
|
4 |
+
become: yes
|
5 |
+
vars:
|
6 |
+
app_user: app
|
7 |
+
app_dir: /home/{{ app_user }}/gradio_app
|
8 |
+
venv_dir: "{{ app_dir }}/venv"
|
9 |
+
|
10 |
+
tasks:
|
11 |
+
- name: Create app user
|
12 |
+
user:
|
13 |
+
name: "{{ app_user }}"
|
14 |
+
shell: /bin/bash
|
15 |
+
|
16 |
+
- name: Install system dependencies
|
17 |
+
apt:
|
18 |
+
name:
|
19 |
+
- python3
|
20 |
+
- python3-pip
|
21 |
+
- python3-venv
|
22 |
+
state: present
|
23 |
+
update_cache: yes
|
24 |
+
|
25 |
+
- name: Create app directory
|
26 |
+
file:
|
27 |
+
path: "{{ app_dir }}"
|
28 |
+
state: directory
|
29 |
+
owner: "{{ app_user }}"
|
30 |
+
group: "{{ app_user }}"
|
31 |
+
mode: '0755'
|
32 |
+
|
33 |
+
- name: Copy app files
|
34 |
+
copy:
|
35 |
+
src: ../../app/
|
36 |
+
dest: "{{ app_dir }}"
|
37 |
+
owner: "{{ app_user }}"
|
38 |
+
group: "{{ app_user }}"
|
39 |
+
mode: '0644'
|
40 |
+
|
41 |
+
- name: Create virtual environment
|
42 |
+
command:
|
43 |
+
cmd: python3 -m venv {{ venv_dir }}
|
44 |
+
creates: "{{ venv_dir }}"
|
45 |
+
|
46 |
+
- name: Change ownership of virtual environment
|
47 |
+
file:
|
48 |
+
path: "{{ venv_dir }}"
|
49 |
+
owner: "{{ app_user }}"
|
50 |
+
group: "{{ app_user }}"
|
51 |
+
recurse: yes
|
52 |
+
|
53 |
+
- name: Install Python dependencies
|
54 |
+
pip:
|
55 |
+
requirements: "{{ app_dir }}/requirements.txt"
|
56 |
+
virtualenv: "{{ venv_dir }}"
|
57 |
+
virtualenv_command: python3 -m venv
|
58 |
+
|
59 |
+
- name: Change ownership of app directory
|
60 |
+
file:
|
61 |
+
path: "{{ app_dir }}"
|
62 |
+
owner: "{{ app_user }}"
|
63 |
+
group: "{{ app_user }}"
|
64 |
+
recurse: yes
|
65 |
+
|
66 |
+
- name: Create systemd service file
|
67 |
+
template:
|
68 |
+
src: ../templates/gradio_app.service.j2
|
69 |
+
dest: /etc/systemd/system/gradio_app.service
|
70 |
+
mode: '0644'
|
71 |
+
|
72 |
+
- name: Start and enable Gradio app service
|
73 |
+
systemd:
|
74 |
+
name: gradio_app
|
75 |
+
state: started
|
76 |
+
enabled: yes
|
77 |
+
daemon_reload: yes
|
deployment/01_deploy_to_app/playbooks/install_tailscale.yml
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
- name: Install and configure Tailscale
|
3 |
+
hosts: all
|
4 |
+
become: yes
|
5 |
+
vars_files:
|
6 |
+
- ../vars/secrets.yml
|
7 |
+
|
8 |
+
tasks:
|
9 |
+
- name: Add Tailscale GPG key
|
10 |
+
apt_key:
|
11 |
+
url: https://pkgs.tailscale.com/stable/ubuntu/focal.gpg
|
12 |
+
state: present
|
13 |
+
|
14 |
+
- name: Add Tailscale repository
|
15 |
+
apt_repository:
|
16 |
+
repo: deb https://pkgs.tailscale.com/stable/ubuntu focal main
|
17 |
+
state: present
|
18 |
+
filename: tailscale
|
19 |
+
|
20 |
+
- name: Install Tailscale
|
21 |
+
apt:
|
22 |
+
name: tailscale
|
23 |
+
state: present
|
24 |
+
update_cache: yes
|
25 |
+
|
26 |
+
- name: Run tailscale up with pre-authentication
|
27 |
+
command: tailscale up --authkey={{ vault_tailscale_authkey }}
|
28 |
+
register: tailscale_result
|
29 |
+
changed_when: "'Success' in tailscale_result.stdout"
|
deployment/01_deploy_to_app/playbooks/main.yml
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
- name: Run all playbooks
|
3 |
+
hosts: all
|
4 |
+
become: yes
|
5 |
+
|
6 |
+
- import_playbook: setup_users.yml
|
7 |
+
- import_playbook: install_tailscale.yml
|
8 |
+
- import_playbook: deploy_gradio_app.yml
|
deployment/01_deploy_to_app/playbooks/setup_users.yml
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
- name: Set up users with sudo privileges and SSH keys
|
3 |
+
hosts: all
|
4 |
+
become: yes
|
5 |
+
vars_files:
|
6 |
+
- ../vars/secrets.yml
|
7 |
+
vars:
|
8 |
+
users:
|
9 |
+
- name: jake
|
10 |
+
ssh_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN13c8DOTx1GjD027XbN/G6MByFEvDX8zttW9EwCxQFe main key"
|
11 |
+
- name: rayhan
|
12 |
+
ssh_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH6Zr582CwihCcLtO0wY0urFnsaka5TRUELAU/7qxt/m rayhanunix@LAPTOP-72FA1E7J"
|
13 |
+
|
14 |
+
tasks:
|
15 |
+
- name: Create users
|
16 |
+
user:
|
17 |
+
name: "{{ item.name }}"
|
18 |
+
password: "{{ item.password | password_hash('sha512') }}"
|
19 |
+
state: present
|
20 |
+
groups: sudo
|
21 |
+
shell: /bin/bash
|
22 |
+
loop: "{{ vault_users }}"
|
23 |
+
|
24 |
+
- name: Add SSH keys
|
25 |
+
authorized_key:
|
26 |
+
user: "{{ item.name }}"
|
27 |
+
key: "{{ item.ssh_key }}"
|
28 |
+
state: present
|
29 |
+
loop: "{{ users }}"
|
30 |
+
|
31 |
+
- name: Ensure sudo group has sudo privileges
|
32 |
+
lineinfile:
|
33 |
+
path: /etc/sudoers
|
34 |
+
state: present
|
35 |
+
regexp: '^%sudo'
|
36 |
+
line: '%sudo ALL=(ALL:ALL) ALL'
|
37 |
+
validate: '/usr/sbin/visudo -cf %s'
|
38 |
+
|
39 |
+
- name: Disable password authentication for SSH
|
40 |
+
lineinfile:
|
41 |
+
path: /etc/ssh/sshd_config
|
42 |
+
regexp: '^PasswordAuthentication'
|
43 |
+
line: 'PasswordAuthentication no'
|
44 |
+
state: present
|
45 |
+
notify: Restart SSH
|
46 |
+
|
47 |
+
handlers:
|
48 |
+
- name: Restart SSH
|
49 |
+
service:
|
50 |
+
name: sshd
|
51 |
+
state: restarted
|
deployment/01_deploy_to_app/templates/gradio_app.service.j2
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[Unit]
|
2 |
+
Description=Gradio App Service
|
3 |
+
After=network.target
|
4 |
+
|
5 |
+
[Service]
|
6 |
+
User={{ app_user }}
|
7 |
+
WorkingDirectory={{ app_dir }}
|
8 |
+
ExecStart={{ venv_dir }}/bin/python {{ app_dir }}/src/app.py
|
9 |
+
Restart=always
|
10 |
+
|
11 |
+
[Install]
|
12 |
+
WantedBy=multi-user.target
|
deployment/01_deploy_to_app/vars/secrets.yml
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
$ANSIBLE_VAULT;1.1;AES256
|
2 |
+
38386664653736333339653530653039636432353063633162333634383031383537393038396438
|
3 |
+
3639613064643263666536633564373138376239323765310a366431613264626336383537616138
|
4 |
+
39343335346634346165623234666432633739313936376661613330353431663338326161306263
|
5 |
+
3139313831333231380a316639363938343666663965343033626635613639386335633264306262
|
6 |
+
65656131643930386434613636633839363235306336626366666362393032646339306665383734
|
7 |
+
34356132336361323036343465393036323564316432633739366661663533343364373836646362
|
8 |
+
31623633623130633233373134353262623962393534393132393562623831626139303463656538
|
9 |
+
61373861656230643639313333363064383231613837363631663264356464663562313832306533
|
10 |
+
31643035366263396261373766373865653838323334316430656162636563323731613466643039
|
11 |
+
62613336303633663262643233323133666533343935666530623938373063643133363366383537
|
12 |
+
64623035373038376532353531303534613234313739316262626638643030613537623462343738
|
13 |
+
64323137663164626365376465656430396532366531346636633033303034636264353938333137
|
14 |
+
63626130656531336165393037643361666261396465643036366637323731356433
|
deployment/02_deploy_to_controller/.DS_Store
ADDED
Binary file (6.15 kB). View file
|
|
deployment/02_deploy_to_controller/ansible.cfg
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[defaults]
|
2 |
+
inventory = inventory/hosts.ini
|
3 |
+
remote_user = ubuntu
|
4 |
+
private_key_file = ~/.ssh/keys/id_admin_CS553
|
5 |
+
host_key_checking = False
|
6 |
+
|
7 |
+
[privilege_escalation]
|
8 |
+
become = True
|
9 |
+
become_method = sudo
|
10 |
+
become_user = root
|
11 |
+
|
deployment/02_deploy_to_controller/inventory/hosts.ini
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
[ec2_instance]
|
2 |
+
controler1 ansible_host=3.141.197.138
|
deployment/02_deploy_to_controller/playbooks/install_tailscale.yml
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
- name: Install and configure Tailscale
|
3 |
+
hosts: all
|
4 |
+
become: yes
|
5 |
+
vars_files:
|
6 |
+
- ../vars/secrets.yml
|
7 |
+
|
8 |
+
tasks:
|
9 |
+
- name: Add Tailscale GPG key
|
10 |
+
apt_key:
|
11 |
+
url: https://pkgs.tailscale.com/stable/ubuntu/focal.gpg
|
12 |
+
state: present
|
13 |
+
|
14 |
+
- name: Add Tailscale repository
|
15 |
+
apt_repository:
|
16 |
+
repo: deb https://pkgs.tailscale.com/stable/ubuntu focal main
|
17 |
+
state: present
|
18 |
+
filename: tailscale
|
19 |
+
|
20 |
+
- name: Install Tailscale
|
21 |
+
apt:
|
22 |
+
name: tailscale
|
23 |
+
state: present
|
24 |
+
update_cache: yes
|
25 |
+
|
26 |
+
- name: Run tailscale up with pre-authentication
|
27 |
+
command: tailscale up --authkey={{ vault_tailscale_authkey }}
|
28 |
+
register: tailscale_result
|
29 |
+
changed_when: "'Success' in tailscale_result.stdout"
|
30 |
+
|
deployment/02_deploy_to_controller/playbooks/main.yml
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
- name: Setup AWS EC2 instance
|
3 |
+
hosts: ec2_instance
|
4 |
+
become: yes
|
5 |
+
vars_files:
|
6 |
+
- ../vars/secrets.yml
|
7 |
+
|
8 |
+
tasks:
|
9 |
+
- name: Install Tailscale
|
10 |
+
include_tasks: install_tailscale.yml
|
11 |
+
|
12 |
+
- name: Setup Ansible
|
13 |
+
include_tasks: setup_ansible.yml
|
14 |
+
|
15 |
+
- name: Clone Git repository
|
16 |
+
git:
|
17 |
+
repo: 'https://github.com/jake-molnia/CS_553'
|
18 |
+
dest: /home/ubuntu/CS_553
|
19 |
+
version: main
|
20 |
+
|
21 |
+
- name: Run initial SSH configuration script
|
22 |
+
script: ../scripts/initial_ssh_config.sh
|
23 |
+
|
24 |
+
- name: Connect using Tailscale
|
25 |
+
command: tailscale up --authkey "{{ tailscale_authkey }}"
|
26 |
+
|
27 |
+
- name: Copy vault password file to EC2 instance
|
28 |
+
copy:
|
29 |
+
src: ../../.secrets/password.txt
|
30 |
+
dest: /home/ubuntu/vault_password.txt
|
31 |
+
mode: '0600'
|
32 |
+
|
33 |
+
- name: Run Ansible playbook for app deployment
|
34 |
+
command: >
|
35 |
+
ansible-playbook -i /home/ubuntu/CS_553/01_deploy_to_app/inventory/hosts.ini
|
36 |
+
/home/ubuntu/CS_553/01_deploy_to_app/playbooks/main.yml
|
37 |
+
--vault-password-file /home/ubuntu/vault_password.txt
|
38 |
+
args:
|
39 |
+
chdir: /home/ubuntu/CS_553/01_deploy_to_app
|
40 |
+
|
41 |
+
- name: Remove vault password file
|
42 |
+
file:
|
43 |
+
path: /home/ubuntu/vault_password.txt
|
44 |
+
state: absent
|
deployment/02_deploy_to_controller/playbooks/setup_ansible.yml
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
- name: Setup Ansible
|
2 |
+
block:
|
3 |
+
- name: Install Ansible and dependencies
|
4 |
+
apt:
|
5 |
+
name:
|
6 |
+
- ansible
|
7 |
+
- git
|
8 |
+
- python3-pip
|
9 |
+
state: present
|
10 |
+
update_cache: yes
|
11 |
+
- name: Install required Python packages
|
12 |
+
pip:
|
13 |
+
name:
|
14 |
+
- boto3
|
15 |
+
- botocore
|
16 |
+
state: present
|
deployment/02_deploy_to_controller/scripts/initial_ssh_config.sh
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/bin/bash
|
2 |
+
ssh -i /path/to/your/private_key.pem ec2-user@paffenroth-23.dyn.wpi.edu <<EOF
|
3 |
+
# Change key (you need to provide the actual commands here)
|
4 |
+
# Install Tailscale (you need to provide the actual commands here)
|
5 |
+
EOF
|
deployment/02_deploy_to_controller/vars/secrets.yml
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
$ANSIBLE_VAULT;1.1;AES256
|
2 |
+
32313364663065623531616639356230653438393737303765313835623165623536313630313134
|
3 |
+
3265653332636634633864316661623463346633623965380a343161313331396535383034636161
|
4 |
+
37373538666530663162383231663437623939343064376435393734343333623734613331643639
|
5 |
+
3565653333663436350a383736383462303739383738623336333636303533393935373666353133
|
6 |
+
64393235656465383662316161623034383230353766356264376332323938316261313032346164
|
7 |
+
34656266336665313434383862303739363766336363313931393133313366393065386136306531
|
8 |
+
62636536376136653961653235366537336233633162306533326564663138353330336330643532
|
9 |
+
36373162306161373336333966666135353136376537623237623465313365336538393261376233
|
10 |
+
6435
|