Compare commits
4 Commits
master
...
mikolaj_br
Author | SHA1 | Date | |
---|---|---|---|
83b21994b2 | |||
c10e063881 | |||
592a250491 | |||
0052d2c36f |
57
.gitignore
vendored
@ -1,3 +1,8 @@
|
|||||||
|
|
||||||
|
# Created by https://www.gitignore.io/api/python
|
||||||
|
# Edit at https://www.gitignore.io/?templates=python
|
||||||
|
|
||||||
|
### Python ###
|
||||||
# Byte-compiled / optimized / DLL files
|
# Byte-compiled / optimized / DLL files
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
@ -20,10 +25,14 @@ parts/
|
|||||||
sdist/
|
sdist/
|
||||||
var/
|
var/
|
||||||
wheels/
|
wheels/
|
||||||
|
pip-wheel-metadata/
|
||||||
share/python-wheels/
|
share/python-wheels/
|
||||||
*.egg-info/
|
*.egg-info/
|
||||||
.installed.cfg
|
.installed.cfg
|
||||||
*.egg
|
*.egg
|
||||||
|
.idea
|
||||||
|
|
||||||
|
/idea/workspace.xml
|
||||||
MANIFEST
|
MANIFEST
|
||||||
|
|
||||||
# PyInstaller
|
# PyInstaller
|
||||||
@ -46,31 +55,26 @@ htmlcov/
|
|||||||
nosetests.xml
|
nosetests.xml
|
||||||
coverage.xml
|
coverage.xml
|
||||||
*.cover
|
*.cover
|
||||||
*.py,cover
|
|
||||||
.hypothesis/
|
.hypothesis/
|
||||||
.pytest_cache/
|
.pytest_cache/
|
||||||
cover/
|
.idea
|
||||||
|
.idea/*
|
||||||
|
|
||||||
# Translations
|
# Translations
|
||||||
*.mo
|
*.mo
|
||||||
*.pot
|
*.pot
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
# PyBuilder
|
# PyBuilder
|
||||||
.pybuilder/
|
|
||||||
target/
|
target/
|
||||||
|
|
||||||
# Jupyter Notebook
|
|
||||||
.ipynb_checkpoints
|
|
||||||
|
|
||||||
# IPython
|
|
||||||
profile_default/
|
|
||||||
ipython_config.py
|
|
||||||
|
|
||||||
# pyenv
|
# pyenv
|
||||||
# For a library or package, you might want to ignore these files since the code is
|
.python-version
|
||||||
# intended to run in multiple environments; otherwise, check them in:
|
|
||||||
# .python-version
|
|
||||||
|
|
||||||
# pipenv
|
# pipenv
|
||||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
@ -79,25 +83,12 @@ ipython_config.py
|
|||||||
# install all needed dependencies.
|
# install all needed dependencies.
|
||||||
#Pipfile.lock
|
#Pipfile.lock
|
||||||
|
|
||||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
# celery beat schedule file
|
||||||
__pypackages__/
|
|
||||||
|
|
||||||
# Celery stuff
|
|
||||||
celerybeat-schedule
|
celerybeat-schedule
|
||||||
celerybeat.pid
|
|
||||||
|
|
||||||
# SageMath parsed files
|
# SageMath parsed files
|
||||||
*.sage.py
|
*.sage.py
|
||||||
|
|
||||||
# Environments
|
|
||||||
.env
|
|
||||||
.venv
|
|
||||||
env/
|
|
||||||
venv/
|
|
||||||
ENV/
|
|
||||||
env.bak/
|
|
||||||
venv.bak/
|
|
||||||
|
|
||||||
# Spyder project settings
|
# Spyder project settings
|
||||||
.spyderproject
|
.spyderproject
|
||||||
.spyproject
|
.spyproject
|
||||||
@ -105,6 +96,11 @@ venv.bak/
|
|||||||
# Rope project settings
|
# Rope project settings
|
||||||
.ropeproject
|
.ropeproject
|
||||||
|
|
||||||
|
# Mr Developer
|
||||||
|
.mr.developer.cfg
|
||||||
|
.project
|
||||||
|
.pydevproject
|
||||||
|
|
||||||
# mkdocs documentation
|
# mkdocs documentation
|
||||||
/site
|
/site
|
||||||
|
|
||||||
@ -116,8 +112,5 @@ dmypy.json
|
|||||||
# Pyre type checker
|
# Pyre type checker
|
||||||
.pyre/
|
.pyre/
|
||||||
|
|
||||||
# pytype static type analyzer
|
# End of https://www.gitignore.io/api/python
|
||||||
.pytype/
|
/venv/
|
||||||
|
|
||||||
# Cython debug symbols
|
|
||||||
cython_debug/
|
|
||||||
|
2
.idea/.gitignore
vendored
@ -1,2 +0,0 @@
|
|||||||
# Default ignored files
|
|
||||||
/workspace.xml
|
|
@ -1,10 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="PYTHON_MODULE" version="4">
|
|
||||||
<component name="NewModuleRootManager">
|
|
||||||
<content url="file://$MODULE_DIR$">
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
|
||||||
</content>
|
|
||||||
<orderEntry type="jdk" jdkName="Python 3.7 (ProjektAI)" jdkType="Python SDK" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
@ -1,6 +0,0 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
|
||||||
<settings>
|
|
||||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
|
||||||
<version value="1.0" />
|
|
||||||
</settings>
|
|
||||||
</component>
|
|
@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="JavaScriptSettings">
|
|
||||||
<option name="languageLevel" value="ES6" />
|
|
||||||
</component>
|
|
||||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (ProjektAI)" project-jdk-type="Python SDK" />
|
|
||||||
</project>
|
|
@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/.idea/ProjektAI.iml" filepath="$PROJECT_DIR$/.idea/ProjektAI.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
26
README.md
@ -1,26 +0,0 @@
|
|||||||
## Table of contents
|
|
||||||
* [General info](#general-info)
|
|
||||||
* [Technologies](#technologies)
|
|
||||||
* [Setup](#setup)
|
|
||||||
|
|
||||||
## General info
|
|
||||||
This is AI project of autonomic waiter that recognizes images of placed ordes with CNN algorithm. Orders are generated using the decision tree algoritm while tables by generic algorithm.
|
|
||||||
|
|
||||||
Table of contents
|
|
||||||
* [General info](#general-info)
|
|
||||||
* [Technologies](#technologies)
|
|
||||||
* [Setup](#setup)
|
|
||||||
|
|
||||||
## Technologies
|
|
||||||
Project is created with:
|
|
||||||
* Python 64-bit: 3.6
|
|
||||||
* Tensorflow: 2.0.0
|
|
||||||
|
|
||||||
## Setup
|
|
||||||
The `requirements.txt` file should list all Python libraries that your notebooks
|
|
||||||
depend on, and they will be installed using:
|
|
||||||
|
|
||||||
```
|
|
||||||
pip install -r requirements.txt
|
|
||||||
```
|
|
||||||
|
|
@ -1,104 +0,0 @@
|
|||||||
|
|
||||||
class CrossingOverMethod:
|
|
||||||
FixedQuadrant = 0
|
|
||||||
SingleHorizontalDiv = 1
|
|
||||||
SingleVerticalDiv = 2
|
|
||||||
DoubleHorizontalDiv = 3
|
|
||||||
DoubleVerticalDiv = 4
|
|
||||||
RandomChoice = 5
|
|
||||||
|
|
||||||
|
|
||||||
class SelectionMethod:
|
|
||||||
Roulette = 0
|
|
||||||
Tournament = 1
|
|
||||||
|
|
||||||
|
|
||||||
class MutationMethod:
|
|
||||||
Flip = 0
|
|
||||||
Swap = 1
|
|
||||||
|
|
||||||
|
|
||||||
class GADefaults:
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
|
|
||||||
self.defSelectionMethods = [("ruletka", SelectionMethod.Roulette),
|
|
||||||
("turniej", SelectionMethod.Tournament)]
|
|
||||||
|
|
||||||
self.defCrossingOverMethods = [("pojedynczy poziomy", CrossingOverMethod.SingleHorizontalDiv),
|
|
||||||
("pojedynczy pionowy", CrossingOverMethod.SingleVerticalDiv),
|
|
||||||
("podwójny poziomy", CrossingOverMethod.DoubleHorizontalDiv),
|
|
||||||
("podwójny pionowy", CrossingOverMethod.DoubleVerticalDiv),
|
|
||||||
("ćwiartki", CrossingOverMethod.FixedQuadrant),
|
|
||||||
("losowe", CrossingOverMethod.RandomChoice)]
|
|
||||||
|
|
||||||
self.defMutationMethods = [("inwersja", MutationMethod.Flip),
|
|
||||||
("wymiana", MutationMethod.Swap)]
|
|
||||||
|
|
||||||
self.windowName = "Algorytm genetyczny - parametry"
|
|
||||||
self.windowGeometry = "400x400"
|
|
||||||
|
|
||||||
self.minTablesCount = 1
|
|
||||||
self.maxTablesCount = 100
|
|
||||||
self.defTablesCount = 20
|
|
||||||
self.runTablesCount = self.defTablesCount
|
|
||||||
self.sliderNameTablesCount = "stoliki"
|
|
||||||
|
|
||||||
self.minPopulationSize = 4
|
|
||||||
self.maxPopulationSize = 30
|
|
||||||
self.defPopulationSize = 5
|
|
||||||
self.runPopulationSize = self.defPopulationSize
|
|
||||||
self.sliderNamePopulationSize = "populacja"
|
|
||||||
|
|
||||||
self.minMutation = 0
|
|
||||||
self.maxMutation = 10
|
|
||||||
self.defMutation = 1
|
|
||||||
self.runMutation = self.defMutation
|
|
||||||
self.sliderNameMutation = "mutacje"
|
|
||||||
|
|
||||||
self.minGenerationsNumber = 1
|
|
||||||
self.maxGenerationsNumber = 1000
|
|
||||||
self.defGenerationsNumber = 20
|
|
||||||
self.runGenerationsNumber = self.defGenerationsNumber
|
|
||||||
self.sliderNameGenerationsNumber = "pokolenia"
|
|
||||||
|
|
||||||
self.defInfoFold = 5
|
|
||||||
self.runInfoFold = self.defInfoFold
|
|
||||||
self.sliderInfoFold = "co ile"
|
|
||||||
|
|
||||||
self.defSelectionMethod = SelectionMethod.Tournament
|
|
||||||
self.runSelectionMethod = self.defSelectionMethod
|
|
||||||
self.radioSelectionMethodName = "metoda selekcji"
|
|
||||||
|
|
||||||
self.defCrossingOverMethod = CrossingOverMethod.SingleHorizontalDiv
|
|
||||||
self.runCrossingOverMethod = self.defCrossingOverMethod
|
|
||||||
self.radioCrossingOverMethodName = "metoda krzyżowania"
|
|
||||||
|
|
||||||
self.defMutationMethod = MutationMethod.Swap
|
|
||||||
self.runMutationMethod = self.defMutationMethod
|
|
||||||
self.radioMutationMethodName = "metoda mutacji"
|
|
||||||
|
|
||||||
self.minElitism = 0
|
|
||||||
self.maxElitism = 50
|
|
||||||
self.defElitism = 0
|
|
||||||
self.runElitism = self.defElitism
|
|
||||||
self.sliderElitismName = "elitarność [%]"
|
|
||||||
|
|
||||||
self.buttonStartName = "generuj"
|
|
||||||
self.buttonDefaultsName = "przywróć"
|
|
||||||
|
|
||||||
self.__forbiddenPlaces = None
|
|
||||||
|
|
||||||
self.waiterPosition = None
|
|
||||||
self.kitchenPosition = None
|
|
||||||
|
|
||||||
def getForbiddenPlaces(self):
|
|
||||||
if self.__forbiddenPlaces is None:
|
|
||||||
self.__forbiddenPlaces = [self.waiterPosition, self.kitchenPosition]
|
|
||||||
return self.__forbiddenPlaces
|
|
||||||
|
|
||||||
def getInfo(self):
|
|
||||||
return "populacja: " + str(self.runPopulationSize) \
|
|
||||||
+ ", pokolenia: " + str(self.runGenerationsNumber) \
|
|
||||||
+ ", stoliki: " + str(self.runTablesCount) \
|
|
||||||
+ ", mutacje: " + str(self.runMutation)
|
|
@ -1,82 +0,0 @@
|
|||||||
import tkinter
|
|
||||||
from tkinter import *
|
|
||||||
|
|
||||||
from kelner.gui.GAdialog.GADefaults import CrossingOverMethod
|
|
||||||
|
|
||||||
|
|
||||||
class GADialog:
|
|
||||||
|
|
||||||
def __init__(self, defaults):
|
|
||||||
self.__defaults = defaults
|
|
||||||
self.window = tkinter.Tk()
|
|
||||||
self.window.attributes('-topmost', 'true')
|
|
||||||
self.window.title(defaults.windowName)
|
|
||||||
self.__sliderTablesCount = self.__getSlider(0, defaults.minTablesCount, defaults.maxTablesCount, defaults.runTablesCount, defaults.sliderNameTablesCount)
|
|
||||||
self.__sliderPopulationSize = self.__getSlider(1, defaults.minPopulationSize, defaults.maxPopulationSize, defaults.runPopulationSize, defaults.sliderNamePopulationSize)
|
|
||||||
self.__sliderMutation = self.__getSlider(2, defaults.minMutation, defaults.maxMutation, defaults.runMutation, defaults.sliderNameMutation)
|
|
||||||
self.__sliderGenerationsNumber = self.__getSlider(3, defaults.minGenerationsNumber, defaults.maxGenerationsNumber, defaults.runGenerationsNumber, defaults.sliderNameGenerationsNumber)
|
|
||||||
self.__sliderInfoFold = self.__getSlider(4, defaults.minGenerationsNumber, defaults.maxGenerationsNumber, defaults.runInfoFold, defaults.sliderInfoFold)
|
|
||||||
self.__sliderElitism = self.__getSlider(5, defaults.minElitism, defaults.maxElitism, defaults.runElitism, defaults.sliderElitismName)
|
|
||||||
|
|
||||||
self.__radioSelectionMethodValue = IntVar()
|
|
||||||
self.__radioSelectionMethodValue.set(self.__defaults.runSelectionMethod)
|
|
||||||
self.__getRadioButton(6, defaults.defSelectionMethods, self.__radioSelectionMethodValue, defaults.radioSelectionMethodName)
|
|
||||||
|
|
||||||
self.__radioCrossingOverMethodValue = IntVar()
|
|
||||||
self.__radioCrossingOverMethodValue.set(self.__defaults.runCrossingOverMethod)
|
|
||||||
self.__getRadioButton(8, defaults.defCrossingOverMethods, self.__radioCrossingOverMethodValue, defaults.radioCrossingOverMethodName)
|
|
||||||
|
|
||||||
self.__radioMutationMethodValue = IntVar()
|
|
||||||
self.__radioMutationMethodValue.set(self.__defaults.runMutationMethod)
|
|
||||||
self.__getRadioButton(12, defaults.defMutationMethods, self.__radioMutationMethodValue, defaults.radioMutationMethodName)
|
|
||||||
|
|
||||||
self.__buttonDefaults = self.__getButton(15, 0, W, defaults.buttonDefaultsName, self.__setDefaults)
|
|
||||||
self.__buttonStart = self.__getButton(15, 1, E, defaults.buttonStartName, self.__getAllValues)
|
|
||||||
self.window.mainloop()
|
|
||||||
|
|
||||||
def __getSlider(self, rowNum, minVal, maxVal, runVal, labText):
|
|
||||||
label = Label(self.window, text = labText)
|
|
||||||
label.grid(row = rowNum, column = 0, sticky = S + W, padx = 5, pady = 5)
|
|
||||||
slider = Scale(self.window, variable = IntVar(), from_ = minVal, to = maxVal, orient=HORIZONTAL, length = 200)
|
|
||||||
slider.grid(row = rowNum, column = 1, sticky = E, padx = 5, pady = 3)
|
|
||||||
slider.set(runVal)
|
|
||||||
return slider
|
|
||||||
|
|
||||||
def __getButton(self, rowNum, colNum, stickPos, btnText, action):
|
|
||||||
button = Button(self.window, text = btnText, command = action)
|
|
||||||
button.grid(row = rowNum, column = colNum, stick = stickPos, columnspan = 2, padx=60, pady=5)
|
|
||||||
return button
|
|
||||||
|
|
||||||
def __getRadioButton(self, rowNum, methods, variable, labText):
|
|
||||||
label = LabelFrame(self.window, text = labText)
|
|
||||||
label.grid(row=rowNum, column=0, columnspan=2, padx=5, pady=5, sticky=W)
|
|
||||||
rowNum += 1
|
|
||||||
iteration = 0
|
|
||||||
for text, mode in methods:
|
|
||||||
radio = Radiobutton(label, text = text, variable = variable, value = mode)
|
|
||||||
radio.grid(row = rowNum, column = iteration % 2, sticky = W, padx = 5, pady = 3)
|
|
||||||
rowNum += iteration % 2
|
|
||||||
iteration += 1
|
|
||||||
|
|
||||||
def __setDefaults(self):
|
|
||||||
self.__sliderTablesCount.set(self.__defaults.defTablesCount)
|
|
||||||
self.__sliderPopulationSize.set(self.__defaults.defPopulationSize)
|
|
||||||
self.__sliderMutation.set(self.__defaults.defMutation)
|
|
||||||
self.__sliderGenerationsNumber.set(self.__defaults.defGenerationsNumber)
|
|
||||||
self.__sliderInfoFold.set(self.__defaults.defInfoFold)
|
|
||||||
self.__sliderElitism.set(self.__defaults.defElitism)
|
|
||||||
self.__radioSelectionMethodValue.set(self.__defaults.defSelectionMethod)
|
|
||||||
self.__radioCrossingOverMethodValue.set(self.__defaults.defCrossingOverMethod)
|
|
||||||
self.__radioMutationMethodValue.set(self.__defaults.defMutationMethod)
|
|
||||||
|
|
||||||
def __getAllValues(self):
|
|
||||||
self.__defaults.runTablesCount = self.__sliderTablesCount.get()
|
|
||||||
self.__defaults.runPopulationSize = self.__sliderPopulationSize.get()
|
|
||||||
self.__defaults.runMutation = self.__sliderMutation.get()
|
|
||||||
self.__defaults.runGenerationsNumber = self.__sliderGenerationsNumber.get()
|
|
||||||
self.__defaults.runInfoFold = self.__sliderInfoFold.get()
|
|
||||||
self.__defaults.runElitism = self.__sliderElitism.get()
|
|
||||||
self.__defaults.runSelectionMethod = self.__radioSelectionMethodValue.get()
|
|
||||||
self.__defaults.runCrossingOverMethod = self.__radioCrossingOverMethodValue.get()
|
|
||||||
self.__defaults.runMutationMethod = self.__radioMutationMethodValue.get()
|
|
||||||
self.window.destroy()
|
|
@ -1,22 +0,0 @@
|
|||||||
import matplotlib.pyplot as plt
|
|
||||||
|
|
||||||
|
|
||||||
class Plots:
|
|
||||||
|
|
||||||
def __init__(self, generationNumber, bestFitnesses, bestTabless, worstFitnesses, worstTables, title):
|
|
||||||
self.__generationsNumber = generationNumber
|
|
||||||
self.__bestFitnesses = bestFitnesses
|
|
||||||
self.__bestTables = bestTabless
|
|
||||||
self.__worstTables = worstTables
|
|
||||||
self.__worstFitnesses = worstFitnesses
|
|
||||||
self.__title = title
|
|
||||||
|
|
||||||
def draw(self):
|
|
||||||
generations = [i for i in range(self.__generationsNumber + 1)]
|
|
||||||
plt.figure(num = self.__title)
|
|
||||||
plt.plot(generations, self.__bestTables, label = "stoliki najlepszego")
|
|
||||||
plt.plot(generations, self.__bestFitnesses, label="fitness najlepszego")
|
|
||||||
plt.plot(generations, self.__worstTables, label = "stoliki najgorszego")
|
|
||||||
plt.plot(generations, self.__worstFitnesses, label = "fitness najgorszego")
|
|
||||||
plt.legend()
|
|
||||||
plt.show()
|
|
Before Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 75 KiB |
Before Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 59 KiB |
Before Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 84 KiB |
Before Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 90 KiB |
Before Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 820 B After Width: | Height: | Size: 850 B |
Before Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 40 KiB |