mirror of
https://github.com/SubtitleEdit/subtitleedit.git
synced 2024-11-22 03:02:35 +01:00
Improve italic detection for "Binary image compare" OCR - thx tormento :)
+ a few related improvements See doom9 posts around http://forum.doom9.net/showthread.php?p=1910580#post1910580
This commit is contained in:
parent
d3039ac40a
commit
44e686593a
@ -2765,6 +2765,16 @@
|
||||
<Word from="AII's" to="All's" />
|
||||
<Word from="FIog" to="Flog" />
|
||||
<Word from="SIit" to="Slit" />
|
||||
<Word from="allsummer" to="all summer" />
|
||||
<Word from="couldhave" to="could have" />
|
||||
<Word from="flrst" to="first" />
|
||||
<Word from="likeyou" to="like you" />
|
||||
<Word from="makeyou" to="make you" />
|
||||
<Word from="ofmysenioryear" to="of my senior year" />
|
||||
<Word from="thatparty" to="that party" />
|
||||
<Word from="thatpeople" to="that people" />
|
||||
<Word from="thatperson" to="that person" />
|
||||
<Word from="thoughyou" to="though you" />
|
||||
</WholeWords>
|
||||
<PartialWordsAlways>
|
||||
<!-- Will be replaced always -->
|
||||
|
@ -2532,7 +2532,7 @@ Keep changes?</KeepChangesMessage>
|
||||
<EditImageDb>Edit image db</EditImageDb>
|
||||
</VobSubOcr>
|
||||
<VobSubOcrCharacter>
|
||||
<Title>VobSub - Manual image to text</Title>
|
||||
<Title>OCR - Manual image to text</Title>
|
||||
<ShrinkSelection>Shrink selection</ShrinkSelection>
|
||||
<ExpandSelection>Expand selection</ExpandSelection>
|
||||
<SubtitleImage>Subtitle image</SubtitleImage>
|
||||
|
BIN
Ocr/Latin.db
BIN
Ocr/Latin.db
Binary file not shown.
@ -2869,7 +2869,7 @@ Keep changes?",
|
||||
|
||||
VobSubOcrCharacter = new LanguageStructure.VobSubOcrCharacter
|
||||
{
|
||||
Title = "VobSub - Manual image to text",
|
||||
Title = "OCR - Manual image to text",
|
||||
Abort = "&Abort",
|
||||
Skip = "&Skip",
|
||||
SubtitleImage = "Subtitle image",
|
||||
|
@ -4031,6 +4031,11 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
|
||||
_vobSubOcrCharacter.Initialize(bitmap, item, _manualOcrDialogPosition, _italicCheckedLast, expandSelectionList.Count > 1, null, _lastAdditions, this);
|
||||
DialogResult result = _vobSubOcrCharacter.ShowDialog(this);
|
||||
_manualOcrDialogPosition = _vobSubOcrCharacter.FormPosition;
|
||||
if (result == DialogResult.Cancel && _vobSubOcrCharacter.SkipImage)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (result == DialogResult.OK && _vobSubOcrCharacter.ShrinkSelection)
|
||||
{
|
||||
shrinkSelection = true;
|
||||
@ -4089,6 +4094,12 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
|
||||
_vobSubOcrCharacter.Initialize(bitmap, item, _manualOcrDialogPosition, _italicCheckedLast, false, bestGuess, _lastAdditions, this, allowExpand);
|
||||
DialogResult result = _vobSubOcrCharacter.ShowDialog(this);
|
||||
_manualOcrDialogPosition = _vobSubOcrCharacter.FormPosition;
|
||||
|
||||
if (result == DialogResult.Cancel && _vobSubOcrCharacter.SkipImage)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (result == DialogResult.OK && _vobSubOcrCharacter.ExpandSelection)
|
||||
{
|
||||
expandSelectionList.Add(item);
|
||||
@ -4171,7 +4182,11 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
|
||||
int wordsNotFound = _ocrFixEngine.CountUnknownWordsViaDictionary(line, out var correctWords);
|
||||
|
||||
// smaller space pixels for italic
|
||||
if (correctWords > 0 && wordsNotFound > 0 && line.Contains("<i>", StringComparison.Ordinal) && matches.Any(p => p?.ImageSplitterItem?.CouldBeSpace == true))
|
||||
if (wordsNotFound > 0 && line.Contains("<i>", StringComparison.Ordinal))
|
||||
{
|
||||
AddItalicCouldBeSpace(matches, parentBitmap, _unItalicFactor);
|
||||
}
|
||||
if (wordsNotFound > 0 && line.Contains("<i>", StringComparison.Ordinal) && matches.Any(p => p?.ImageSplitterItem?.CouldBeSpace == true))
|
||||
{
|
||||
int j = 0;
|
||||
while (j < matches.Count)
|
||||
@ -4196,7 +4211,8 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
|
||||
}
|
||||
|
||||
int tempWordsNotFound = _ocrFixEngine.CountUnknownWordsViaDictionary(tempLine, out var tempCorrectWords);
|
||||
if (tempWordsNotFound == 0 && tempCorrectWords > 0)
|
||||
//if (tempWordsNotFound == 0 && tempCorrectWords > 0)
|
||||
if (tempWordsNotFound < wordsNotFound && tempCorrectWords > 0)
|
||||
{
|
||||
wordsNotFound = tempWordsNotFound;
|
||||
correctWords = tempCorrectWords;
|
||||
@ -4253,6 +4269,74 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
|
||||
return line;
|
||||
}
|
||||
|
||||
private void AddItalicCouldBeSpace(List<CompareMatch> matches, NikseBitmap parentBitmap, double unItalicFactor)
|
||||
{
|
||||
for (int i = 0; i < matches.Count - 1; i++)
|
||||
{
|
||||
var match = matches[i];
|
||||
var matchNext = matches[i + 1];
|
||||
if (!match.Italic || !matchNext.Italic ||
|
||||
string.IsNullOrWhiteSpace(match.Text) || string.IsNullOrWhiteSpace(matchNext.Text) ||
|
||||
match.ImageSplitterItem == null || match.ImageSplitterItem.CouldBeSpace)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int blankVerticalLines = IsVerticalAngledLineTransparent(parentBitmap, match, matchNext, unItalicFactor);
|
||||
if (blankVerticalLines >= _numericUpDownPixelsIsSpace)
|
||||
{
|
||||
matchNext.ImageSplitterItem.CouldBeSpace = true; // TODO: Rename to "could be space before"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int IsVerticalAngledLineTransparent(NikseBitmap parentBitmap, CompareMatch match, CompareMatch next, double unItalicFactor)
|
||||
{
|
||||
int blanks = 0;
|
||||
var min = match.ImageSplitterItem.X + match.ImageSplitterItem.NikseBitmap.Width;
|
||||
var max = next.ImageSplitterItem.X + next.ImageSplitterItem.NikseBitmap.Width / 2;
|
||||
bool abort = false;
|
||||
for (int startX = min; startX < max; startX++)
|
||||
{
|
||||
var lineBlank = true;
|
||||
for (int y = match.ImageSplitterItem.Y; y < match.ImageSplitterItem.Y + match.ImageSplitterItem.NikseBitmap.Height; y++)
|
||||
{
|
||||
var x = startX - (y - match.ImageSplitterItem.Y) * unItalicFactor;
|
||||
if (x >= 0)
|
||||
{
|
||||
var color = parentBitmap.GetPixel((int)Math.Round(x), y);
|
||||
if (color.A == 0)
|
||||
{
|
||||
// parentBitmap.SetPixel((int)Math.Round(x), y, Color.LawnGreen);
|
||||
}
|
||||
else
|
||||
{
|
||||
// parentBitmap.SetPixel((int)Math.Round(x), y, Color.Red);
|
||||
lineBlank = false;
|
||||
if (blanks > 0)
|
||||
{
|
||||
abort = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (abort)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (lineBlank)
|
||||
{
|
||||
blanks++;
|
||||
}
|
||||
}
|
||||
|
||||
//parentBitmap.GetBitmap().Save(@"J:\Temp\" + DateTime.UtcNow.Ticks + "_" + match.Text + "_" + blanks + ".bmp");
|
||||
return blanks;
|
||||
}
|
||||
|
||||
private void SetBinOcrLowercaseUppercase(int height, string text)
|
||||
{
|
||||
if (text == "e" && (height < _binOcrLastLowercaseHeight || _binOcrLastLowercaseHeight < 0))
|
||||
@ -6513,10 +6597,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
|
||||
}
|
||||
}
|
||||
|
||||
if (bmp != null)
|
||||
{
|
||||
bmp.Dispose();
|
||||
}
|
||||
bmp?.Dispose();
|
||||
|
||||
if (mp.Text != null)
|
||||
{
|
||||
@ -7003,6 +7084,31 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
|
||||
form.ShowDialog(this);
|
||||
}
|
||||
}
|
||||
else if (e.Modifiers == (Keys.Control | Keys.Shift) && e.KeyCode == Keys.I && _ocrMethodIndex == _ocrMethodBinaryImageCompare)
|
||||
{
|
||||
var bmp = (Bitmap)pictureBoxSubtitleImage.Image;
|
||||
if (bmp != null)
|
||||
{
|
||||
var nBmp = new NikseBitmap(bmp);
|
||||
bmp.Dispose();
|
||||
var italicFactor = _unItalicFactor;
|
||||
|
||||
for (var startX = 20.0; startX < nBmp.Width; startX += 20.0)
|
||||
{
|
||||
var x = startX;
|
||||
for (int y = 0; y < nBmp.Height; y++)
|
||||
{
|
||||
x = startX - y * italicFactor;
|
||||
if (x >= 0)
|
||||
{
|
||||
nBmp.SetPixel((int)Math.Round(x), y, Color.Red);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pictureBoxSubtitleImage.Image = nBmp.GetBitmap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ComboBoxTesseractLanguagesSelectedIndexChanged(object sender, EventArgs e)
|
||||
|
1
src/Forms/Ocr/VobSubOcrCharacter.Designer.cs
generated
1
src/Forms/Ocr/VobSubOcrCharacter.Designer.cs
generated
@ -206,6 +206,7 @@
|
||||
this.buttonSkip.TabIndex = 3;
|
||||
this.buttonSkip.Text = "&Skip";
|
||||
this.buttonSkip.UseVisualStyleBackColor = true;
|
||||
this.buttonSkip.Click += new System.EventHandler(this.buttonSkip_Click);
|
||||
//
|
||||
// pictureBoxSubtitleImage
|
||||
//
|
||||
|
@ -80,10 +80,13 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
|
||||
|
||||
public bool ShrinkSelection { get; private set; }
|
||||
|
||||
public bool SkipImage { get; private set; }
|
||||
|
||||
internal void Initialize(Bitmap vobSubImage, ImageSplitterItem character, Point position, bool italicChecked, bool showShrink, VobSubOcr.CompareMatch bestGuess, List<VobSubOcr.ImageCompareAddition> additions, VobSubOcr vobSubForm, bool allowExpand = true)
|
||||
{
|
||||
ShrinkSelection = false;
|
||||
ExpandSelection = false;
|
||||
SkipImage = false;
|
||||
|
||||
textBoxCharacters.Text = string.Empty;
|
||||
if (bestGuess != null)
|
||||
@ -292,6 +295,12 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
|
||||
checkBoxItalic.Checked = !checkBoxItalic.Checked;
|
||||
e.SuppressKeyPress = true;
|
||||
}
|
||||
else if (e.Modifiers == (Keys.Control | Keys.Shift) && e.KeyCode == Keys.S)
|
||||
{
|
||||
SkipImage = true;
|
||||
DialogResult = DialogResult.Cancel;
|
||||
e.SuppressKeyPress = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
|
||||
@ -303,5 +312,10 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
|
||||
{
|
||||
TaskbarList.StopBlink(_vobSubForm);
|
||||
}
|
||||
|
||||
private void buttonSkip_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.Cancel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
44
src/Forms/Ocr/VobSubOcrSetItalicFactor.Designer.cs
generated
44
src/Forms/Ocr/VobSubOcrSetItalicFactor.Designer.cs
generated
@ -34,19 +34,19 @@
|
||||
this.pictureBoxSubtitleImage = new System.Windows.Forms.PictureBox();
|
||||
this.contextMenuStripListview = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.saveImageAsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.numericUpDown1 = new System.Windows.Forms.NumericUpDown();
|
||||
this.numericUpDownItalicFactor = new System.Windows.Forms.NumericUpDown();
|
||||
this.labelDescription = new System.Windows.Forms.Label();
|
||||
this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pictureBoxSubtitleImage)).BeginInit();
|
||||
this.contextMenuStripListview.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.numericUpDownItalicFactor)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// buttonCancel
|
||||
//
|
||||
this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.buttonCancel.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
||||
this.buttonCancel.Location = new System.Drawing.Point(680, 312);
|
||||
this.buttonCancel.Location = new System.Drawing.Point(794, 366);
|
||||
this.buttonCancel.Name = "buttonCancel";
|
||||
this.buttonCancel.Size = new System.Drawing.Size(75, 23);
|
||||
this.buttonCancel.TabIndex = 8;
|
||||
@ -58,7 +58,7 @@
|
||||
//
|
||||
this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.buttonOK.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
||||
this.buttonOK.Location = new System.Drawing.Point(599, 312);
|
||||
this.buttonOK.Location = new System.Drawing.Point(713, 366);
|
||||
this.buttonOK.Name = "buttonOK";
|
||||
this.buttonOK.Size = new System.Drawing.Size(75, 23);
|
||||
this.buttonOK.TabIndex = 7;
|
||||
@ -74,7 +74,7 @@
|
||||
this.pictureBoxSubtitleImage.ContextMenuStrip = this.contextMenuStripListview;
|
||||
this.pictureBoxSubtitleImage.Location = new System.Drawing.Point(12, 47);
|
||||
this.pictureBoxSubtitleImage.Name = "pictureBoxSubtitleImage";
|
||||
this.pictureBoxSubtitleImage.Size = new System.Drawing.Size(743, 259);
|
||||
this.pictureBoxSubtitleImage.Size = new System.Drawing.Size(857, 313);
|
||||
this.pictureBoxSubtitleImage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
|
||||
this.pictureBoxSubtitleImage.TabIndex = 9;
|
||||
this.pictureBoxSubtitleImage.TabStop = false;
|
||||
@ -93,36 +93,37 @@
|
||||
this.saveImageAsToolStripMenuItem.Text = "Save image as...";
|
||||
this.saveImageAsToolStripMenuItem.Click += new System.EventHandler(this.saveImageAsToolStripMenuItem_Click);
|
||||
//
|
||||
// numericUpDown1
|
||||
// numericUpDownItalicFactor
|
||||
//
|
||||
this.numericUpDown1.DecimalPlaces = 2;
|
||||
this.numericUpDown1.Increment = new decimal(new int[] {
|
||||
this.numericUpDownItalicFactor.DecimalPlaces = 2;
|
||||
this.numericUpDownItalicFactor.Increment = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
131072});
|
||||
this.numericUpDown1.Location = new System.Drawing.Point(12, 19);
|
||||
this.numericUpDown1.Maximum = new decimal(new int[] {
|
||||
this.numericUpDownItalicFactor.Location = new System.Drawing.Point(12, 19);
|
||||
this.numericUpDownItalicFactor.Maximum = new decimal(new int[] {
|
||||
10,
|
||||
0,
|
||||
0,
|
||||
65536});
|
||||
this.numericUpDown1.Name = "numericUpDown1";
|
||||
this.numericUpDown1.Size = new System.Drawing.Size(57, 20);
|
||||
this.numericUpDown1.TabIndex = 10;
|
||||
this.numericUpDown1.Value = new decimal(new int[] {
|
||||
this.numericUpDownItalicFactor.Name = "numericUpDownItalicFactor";
|
||||
this.numericUpDownItalicFactor.Size = new System.Drawing.Size(57, 20);
|
||||
this.numericUpDownItalicFactor.TabIndex = 10;
|
||||
this.numericUpDownItalicFactor.Value = new decimal(new int[] {
|
||||
31,
|
||||
0,
|
||||
0,
|
||||
131072});
|
||||
this.numericUpDown1.ValueChanged += new System.EventHandler(this.numericUpDown1_ValueChanged);
|
||||
this.numericUpDownItalicFactor.ValueChanged += new System.EventHandler(this.numericUpDownItalicFactor_ValueChanged);
|
||||
//
|
||||
// labelDescription
|
||||
//
|
||||
this.labelDescription.AutoSize = true;
|
||||
this.labelDescription.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.labelDescription.Location = new System.Drawing.Point(76, 21);
|
||||
this.labelDescription.Name = "labelDescription";
|
||||
this.labelDescription.Size = new System.Drawing.Size(431, 13);
|
||||
this.labelDescription.Size = new System.Drawing.Size(529, 13);
|
||||
this.labelDescription.TabIndex = 11;
|
||||
this.labelDescription.Text = "Adjust value until text style is normal and not italic. Note that original image " +
|
||||
"should be italic.";
|
||||
@ -131,24 +132,27 @@
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(767, 345);
|
||||
this.BackColor = System.Drawing.Color.DimGray;
|
||||
this.ClientSize = new System.Drawing.Size(881, 399);
|
||||
this.Controls.Add(this.labelDescription);
|
||||
this.Controls.Add(this.numericUpDown1);
|
||||
this.Controls.Add(this.numericUpDownItalicFactor);
|
||||
this.Controls.Add(this.pictureBoxSubtitleImage);
|
||||
this.Controls.Add(this.buttonCancel);
|
||||
this.Controls.Add(this.buttonOK);
|
||||
this.KeyPreview = true;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.MinimumSize = new System.Drawing.Size(783, 384);
|
||||
this.Name = "VobSubOcrSetItalicFactor";
|
||||
this.ShowIcon = false;
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Set un-italic factor";
|
||||
this.Shown += new System.EventHandler(this.VobSubOcrSetItalicFactor_Shown);
|
||||
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.VobSubOcrSetItalicFactor_KeyDown);
|
||||
((System.ComponentModel.ISupportInitialize)(this.pictureBoxSubtitleImage)).EndInit();
|
||||
this.contextMenuStripListview.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.numericUpDownItalicFactor)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
@ -159,7 +163,7 @@
|
||||
private System.Windows.Forms.Button buttonCancel;
|
||||
private System.Windows.Forms.Button buttonOK;
|
||||
private System.Windows.Forms.PictureBox pictureBoxSubtitleImage;
|
||||
private System.Windows.Forms.NumericUpDown numericUpDown1;
|
||||
private System.Windows.Forms.NumericUpDown numericUpDownItalicFactor;
|
||||
private System.Windows.Forms.Label labelDescription;
|
||||
private System.Windows.Forms.SaveFileDialog saveFileDialog1;
|
||||
private System.Windows.Forms.ContextMenuStrip contextMenuStripListview;
|
||||
|
@ -19,7 +19,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
|
||||
|
||||
_bmp = bmp;
|
||||
_factor = factor;
|
||||
numericUpDown1.Value = (decimal)factor;
|
||||
numericUpDownItalicFactor.Value = (decimal)factor;
|
||||
|
||||
Text = Configuration.Settings.Language.VobSubOcrSetItalicFactor.Title;
|
||||
labelDescription.Text = Configuration.Settings.Language.VobSubOcrSetItalicFactor.Description;
|
||||
@ -28,9 +28,9 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
|
||||
buttonCancel.Text = Configuration.Settings.Language.General.Cancel;
|
||||
}
|
||||
|
||||
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
|
||||
private void numericUpDownItalicFactor_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
pictureBoxSubtitleImage.Image = VobSubOcr.UnItalic(_bmp, (double)numericUpDown1.Value);
|
||||
pictureBoxSubtitleImage.Image = VobSubOcr.UnItalic(_bmp, (double)numericUpDownItalicFactor.Value);
|
||||
}
|
||||
|
||||
internal double GetUnItalicFactor()
|
||||
@ -40,7 +40,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
|
||||
|
||||
private void buttonOK_Click(object sender, EventArgs e)
|
||||
{
|
||||
_factor = (double)numericUpDown1.Value;
|
||||
_factor = (double)numericUpDownItalicFactor.Value;
|
||||
DialogResult = DialogResult.OK;
|
||||
}
|
||||
|
||||
@ -101,5 +101,9 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
|
||||
}
|
||||
}
|
||||
|
||||
private void VobSubOcrSetItalicFactor_Shown(object sender, EventArgs e)
|
||||
{
|
||||
numericUpDownItalicFactor_ValueChanged(null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user