mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-11 02:35:00 +00:00
Adding warming and cooling modal. Warming seems to occasionally not happen
This commit is contained in:
@@ -60,7 +60,7 @@
|
||||
</Reference>
|
||||
<Reference Include="Crestron.SimplSharpPro.Fusion, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Fusion.dll</HintPath>
|
||||
<HintPath>..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Fusion.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Crestron.SimplSharpPro.Remotes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
|
||||
Binary file not shown.
@@ -30,6 +30,10 @@ namespace PepperDash.Essentials.Core
|
||||
/// Shows the timer guage if in use. Bool feedback 3996
|
||||
/// </summary>
|
||||
public const uint TimerVisibleJoin = 3996;
|
||||
/// <summary>
|
||||
/// Visibility join to show "X" button 3997
|
||||
/// </summary>
|
||||
public const uint CancelVisibleJoin = 3997;
|
||||
/// <summary>
|
||||
/// Shows the modal subpage. Boolean feeback join 3999
|
||||
/// </summary>
|
||||
@@ -73,6 +77,11 @@ namespace PepperDash.Essentials.Core
|
||||
get { return TriList.BooleanInput[ModalVisibleJoin].BoolValue; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool CanCancel { get; private set; }
|
||||
|
||||
|
||||
BasicTriList TriList;
|
||||
|
||||
@@ -90,7 +99,8 @@ namespace PepperDash.Essentials.Core
|
||||
// Attach actions to buttons
|
||||
triList.SetSigFalseAction(Button1Join, () => OnModalComplete(1));
|
||||
triList.SetSigFalseAction(Button2Join, () => OnModalComplete(2));
|
||||
triList.SetSigFalseAction(CancelButtonJoin, () => CancelDialog());
|
||||
triList.SetSigFalseAction(CancelButtonJoin, () => { if (CanCancel) CancelDialog(); });
|
||||
CanCancel = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -103,9 +113,8 @@ namespace PepperDash.Essentials.Core
|
||||
/// <returns>True when modal is created.</returns>
|
||||
public bool PresentModalDialog(uint numberOfButtons, string title, string iconName,
|
||||
string message, string button1Text,
|
||||
string button2Text, bool showGauge, Action<uint> completeAction)
|
||||
string button2Text, bool showGauge, bool showCancel, Action<uint> completeAction)
|
||||
{
|
||||
//Debug.Console(0, "Present dialog");
|
||||
// Don't reset dialog if visible now
|
||||
if (!ModalIsVisible)
|
||||
{
|
||||
@@ -137,9 +146,13 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
// Show/hide guage
|
||||
TriList.BooleanInput[TimerVisibleJoin].BoolValue = showGauge;
|
||||
|
||||
CanCancel = showCancel;
|
||||
TriList.BooleanInput[CancelVisibleJoin].BoolValue = showCancel;
|
||||
|
||||
//Reveal and activate
|
||||
TriList.BooleanInput[ModalVisibleJoin].BoolValue = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -21,6 +21,7 @@ namespace PepperDash.Essentials.Devices.Displays
|
||||
|
||||
public byte ID { get; private set; }
|
||||
|
||||
|
||||
bool _PowerIsOn;
|
||||
bool _IsWarmingUp;
|
||||
bool _IsCoolingDown;
|
||||
@@ -35,8 +36,7 @@ namespace PepperDash.Essentials.Devices.Displays
|
||||
protected override Func<bool> PowerIsOnFeedbackFunc { get { return () => _PowerIsOn; } }
|
||||
protected override Func<bool> IsCoolingDownFeedbackFunc { get { return () => _IsCoolingDown; } }
|
||||
protected override Func<bool> IsWarmingUpFeedbackFunc { get { return () => _IsWarmingUp; } }
|
||||
protected override Func<string> CurrentInputFeedbackFunc { get { return () => _CurrentInputPort.Key; } }
|
||||
|
||||
protected override Func<string> CurrentInputFeedbackFunc { get { return () => _CurrentInputPort.Key; } }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for IBasicCommunication
|
||||
@@ -62,7 +62,6 @@ namespace PepperDash.Essentials.Devices.Displays
|
||||
Init();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for COM
|
||||
/// </summary>
|
||||
@@ -120,7 +119,6 @@ namespace PepperDash.Essentials.Devices.Displays
|
||||
MuteFeedback = new BoolFeedback(() => _IsMuted);
|
||||
|
||||
StatusGet();
|
||||
//StatusTimer = new CTimer(o => StatusGet(), null, 0, 30000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -157,13 +155,11 @@ namespace PepperDash.Essentials.Devices.Displays
|
||||
/// <param name="e"></param>
|
||||
void Communication_BytesReceived(object sender, GenericCommMethodReceiveBytesArgs e)
|
||||
{
|
||||
//Debug.Console(2, this, "Socket in: {0}", ComTextHelper.GetEscapedText(e.Bytes));
|
||||
// This is probably not thread-safe buffering
|
||||
// Append the incoming bytes with whatever is in the buffer
|
||||
var newBytes = new byte[IncomingBuffer.Length + e.Bytes.Length];
|
||||
IncomingBuffer.CopyTo(newBytes, 0);
|
||||
e.Bytes.CopyTo(newBytes, IncomingBuffer.Length);
|
||||
//Debug.Console(2, this, "Buffer+new: {0}", ComTextHelper.GetEscapedText(newBytes));
|
||||
|
||||
// Need to find AA FF and have
|
||||
for (int i = 0; i < newBytes.Length; i++)
|
||||
@@ -192,7 +188,8 @@ namespace PepperDash.Essentials.Devices.Displays
|
||||
switch (message[1]) // type byte
|
||||
{
|
||||
case 0x00: // General status
|
||||
UpdatePowerFBWithSource(message[2], message[3]); // "power" can be misrepresented when the display sleeps
|
||||
UpdatePowerFB(message[2]); // "power" can be misrepresented when the display sleeps
|
||||
UpdateInputFb(message[5]);
|
||||
UpdateVolumeFB(message[3]);
|
||||
UpdateMuteFb(message[4]);
|
||||
UpdateInputFb(message[5]);
|
||||
@@ -230,28 +227,17 @@ namespace PepperDash.Essentials.Devices.Displays
|
||||
IncomingBuffer = newBytes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks power feedback AND that source >0x10
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="b"></param>
|
||||
void UpdatePowerFBWithSource(byte pb, byte ib)
|
||||
{
|
||||
var newVal = pb == 1 && ib > 0x10;
|
||||
if (newVal != _PowerIsOn)
|
||||
{
|
||||
_PowerIsOn = newVal;
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdatePowerFB(byte pb)
|
||||
{
|
||||
var newVal = pb == 1;
|
||||
Debug.Console(2, this, "NEW POWER STATE={0}, CURRENT={1}", newVal, _PowerIsOn);
|
||||
if (newVal != _PowerIsOn)
|
||||
{
|
||||
_PowerIsOn = newVal;
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
CrestronEnvironment.Sleep(1500);
|
||||
Debug.Console(2, this, "NEW POWER STATE AFTER PAUSE={0} CURRENT={1}", newVal, _PowerIsOn);
|
||||
if (newVal != _PowerIsOn)
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,7 +246,7 @@ namespace PepperDash.Essentials.Devices.Displays
|
||||
/// </summary>
|
||||
/// <param name="b"></param>
|
||||
void UpdateVolumeFB(byte b)
|
||||
{
|
||||
{
|
||||
var newVol = (ushort)Scale((double)b, 0, 100, 0, 65535);
|
||||
if (!VolumeIsRamping)
|
||||
_LastVolumeSent = newVol;
|
||||
@@ -346,7 +332,7 @@ namespace PepperDash.Essentials.Devices.Displays
|
||||
{
|
||||
// If a display has unreliable-power off feedback, just override this and
|
||||
// remove this check.
|
||||
if (PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
|
||||
if (!_IsWarmingUp && !_IsCoolingDown) // PowerIsOnFeedback.BoolValue &&
|
||||
{
|
||||
//Send(PowerOffCmd);
|
||||
SendBytes(new byte[] { 0xAA, 0x11, 0x00, 0x01, 0x00, 0x00 });
|
||||
|
||||
Binary file not shown.
@@ -29,8 +29,8 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public override void InitializeSystem()
|
||||
{
|
||||
CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Reloads configuration file",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
//CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Reloads configuration file",
|
||||
// ConsoleAccessLevelEnum.AccessOperator);
|
||||
//CrestronConsole.AddNewConsoleCommand(s => TearDown(), "ungo", "Reloads configuration file",
|
||||
// ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(s =>
|
||||
@@ -40,7 +40,7 @@ namespace PepperDash.Essentials
|
||||
},
|
||||
"listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
//GoWithLoad();
|
||||
GoWithLoad();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1050,6 +1050,10 @@ namespace PepperDash.Essentials.Fusion
|
||||
|
||||
void SetUpOccupancy()
|
||||
{
|
||||
|
||||
return;
|
||||
|
||||
|
||||
#warning Add actual object logic check here
|
||||
//if (Room.OccupancyObj != null)
|
||||
//{
|
||||
|
||||
Binary file not shown.
@@ -30,6 +30,45 @@ namespace PepperDash.Essentials
|
||||
};
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override Func<bool> IsWarmingFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
var disp = DefaultDisplay as DisplayBase;
|
||||
if (disp != null)
|
||||
return disp.IsWarmingUpFeedback.BoolValue;
|
||||
else
|
||||
return false;
|
||||
};
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override Func<bool> IsCoolingFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
var disp = DefaultDisplay as DisplayBase;
|
||||
if (disp != null)
|
||||
{
|
||||
Debug.Console(2, this, "IS COOLING FUNC-- Display cooling={0}", disp.IsCoolingDownFeedback.BoolValue);
|
||||
return disp.IsCoolingDownFeedback.BoolValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public EssentialsRoomPropertiesConfig Config { get; private set; }
|
||||
|
||||
@@ -129,6 +168,7 @@ namespace PepperDash.Essentials
|
||||
var disp = DefaultDisplay as DisplayBase;
|
||||
if (disp != null)
|
||||
{
|
||||
// Link power, warming, cooling to display
|
||||
disp.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||
@@ -138,11 +178,15 @@ namespace PepperDash.Essentials
|
||||
OnFeedback.FireUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
disp.IsWarmingUpFeedback.OutputChange += (o, a) => { IsWarmingUpFeedback.FireUpdate(); };
|
||||
disp.IsCoolingDownFeedback.OutputChange += (o, a) => { IsCoolingDownFeedback.FireUpdate(); };
|
||||
}
|
||||
|
||||
SourceListKey = "default";
|
||||
EnablePowerOnToLastSource = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
||||
@@ -22,7 +22,10 @@ namespace PepperDash.Essentials
|
||||
|| (Display1SourceInfo != null
|
||||
&& Display1SourceInfo.Type != eSourceListItemType.Off)
|
||||
|| (Display2SourceInfo != null
|
||||
&& Display2SourceInfo.Type != eSourceListItemType.Off); } }
|
||||
&& Display2SourceInfo.Type != eSourceListItemType.Off); } }
|
||||
|
||||
protected override Func<bool> IsWarmingFeedbackFunc { get { return () =>false;; } }
|
||||
protected override Func<bool> IsCoolingFeedbackFunc { get { return () => false; } }
|
||||
|
||||
public EssentialsPresentationRoomPropertiesConfig Config { get; private set; }
|
||||
|
||||
|
||||
@@ -27,8 +27,11 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public BoolFeedback OnFeedback { get; private set; }
|
||||
|
||||
public BoolFeedback IsWarmingFeedback { get; private set; }
|
||||
public BoolFeedback IsCoolingFeedback { get; private set; }
|
||||
public BoolFeedback IsWarmingUpFeedback { get; private set; }
|
||||
public BoolFeedback IsCoolingDownFeedback { get; private set; }
|
||||
|
||||
protected abstract Func<bool> IsWarmingFeedbackFunc { get; }
|
||||
protected abstract Func<bool> IsCoolingFeedbackFunc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Timer used for informing the UIs of a shutdown
|
||||
@@ -67,8 +70,10 @@ namespace PepperDash.Essentials
|
||||
ShutdownType = ShutdownType.None;
|
||||
|
||||
OnFeedback = new BoolFeedback(OnFeedbackFunc);
|
||||
}
|
||||
|
||||
IsWarmingUpFeedback = new BoolFeedback(IsWarmingFeedbackFunc);
|
||||
IsCoolingDownFeedback = new BoolFeedback(IsCoolingFeedbackFunc);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
||||
@@ -140,6 +140,8 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
CTimer PowerOffTimer;
|
||||
|
||||
ModalDialog WarmingCoolingModal;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
@@ -203,13 +205,17 @@ namespace PepperDash.Essentials
|
||||
ShowInterlockedModal(UIBoolJoin.HelpPageVisible);
|
||||
});
|
||||
|
||||
TriList.SetSigFalseAction(UIBoolJoin.RoomHeaderButtonPress, () =>
|
||||
ShowInterlockedModal(UIBoolJoin.RoomHeaderPageVisible));
|
||||
//TriList.SetSigFalseAction(UIBoolJoin.RoomHeaderButtonPress, () =>
|
||||
// ShowInterlockedModal(UIBoolJoin.RoomHeaderPageVisible));
|
||||
|
||||
#warning Add press and hold to gear button here
|
||||
TriList.BooleanInput[UIBoolJoin.GearButtonVisible].BoolValue = false;
|
||||
#warning Hide Gear on ipad for now
|
||||
TriList.BooleanInput[UIBoolJoin.GearButtonVisible].BoolValue = true;
|
||||
TriList.SetSigFalseAction(UIBoolJoin.GearHeaderButtonPress, () =>
|
||||
ShowInterlockedModal(UIBoolJoin.VolumesPageVisible));
|
||||
ShowInterlockedModal(UIBoolJoin.TechPanelSetupVisible));
|
||||
//ShowInterlockedModal(UIBoolJoin.VolumesPageVisible));
|
||||
TriList.SetSigFalseAction(UIBoolJoin.TechPagesExitButton, () =>
|
||||
HideCurrentInterlockedModal());
|
||||
|
||||
// power-related functions
|
||||
// Note: some of these are not directly-related to the huddle space UI, but are held over
|
||||
@@ -499,7 +505,7 @@ namespace PepperDash.Essentials
|
||||
};
|
||||
onFb.OutputChange += offHandler;
|
||||
|
||||
modal.PresentModalDialog(2, "End Meeting", "Power", message, "Cancel", "End Meeting Now", true,
|
||||
modal.PresentModalDialog(2, "End Meeting", "Power", message, "Cancel", "End Meeting Now", true, true,
|
||||
but =>
|
||||
{
|
||||
if (but != 2) // any button except for End cancels
|
||||
@@ -616,10 +622,10 @@ namespace PepperDash.Essentials
|
||||
void SetCurrentRoom(EssentialsHuddleSpaceRoom room)
|
||||
{
|
||||
if (_CurrentRoom == room) return;
|
||||
// Disconnect current (probably never called)
|
||||
if (_CurrentRoom != null)
|
||||
{
|
||||
// Disconnect current room
|
||||
_CurrentRoom.OnFeedback.OutputChange -= CurrentRoom_OnFeedback_OutputChange;
|
||||
_CurrentRoom.CurrentVolumeDeviceChange -= this.CurrentRoom_CurrentAudioDeviceChange;
|
||||
ClearAudioDeviceConnections();
|
||||
_CurrentRoom.CurrentSingleSourceChange -= this.CurrentRoom_SourceInfoChange;
|
||||
@@ -627,7 +633,11 @@ namespace PepperDash.Essentials
|
||||
_CurrentRoom.ShutdownPromptTimer.HasStarted -= ShutdownPromptTimer_HasStarted;
|
||||
_CurrentRoom.ShutdownPromptTimer.HasFinished -= ShutdownPromptTimer_HasFinished;
|
||||
_CurrentRoom.ShutdownPromptTimer.WasCancelled -= ShutdownPromptTimer_WasCancelled;
|
||||
}
|
||||
|
||||
_CurrentRoom.OnFeedback.OutputChange += CurrentRoom_OnFeedback_OutputChange;
|
||||
_CurrentRoom.IsWarmingUpFeedback.OutputChange -= CurrentRoom_IsWarmingFeedback_OutputChange;
|
||||
_CurrentRoom.IsCoolingDownFeedback.OutputChange -= IsCoolingDownFeedback_OutputChange;
|
||||
}
|
||||
_CurrentRoom = room;
|
||||
|
||||
if (_CurrentRoom != null)
|
||||
@@ -670,6 +680,9 @@ namespace PepperDash.Essentials
|
||||
|
||||
// Link up all the change events from the room
|
||||
_CurrentRoom.OnFeedback.OutputChange += CurrentRoom_OnFeedback_OutputChange;
|
||||
_CurrentRoom.IsWarmingUpFeedback.OutputChange += CurrentRoom_IsWarmingFeedback_OutputChange;
|
||||
_CurrentRoom.IsCoolingDownFeedback.OutputChange += IsCoolingDownFeedback_OutputChange;
|
||||
|
||||
_CurrentRoom.CurrentVolumeDeviceChange += CurrentRoom_CurrentAudioDeviceChange;
|
||||
RefreshAudioDeviceConnections();
|
||||
_CurrentRoom.CurrentSingleSourceChange += CurrentRoom_SourceInfoChange;
|
||||
@@ -688,6 +701,7 @@ namespace PepperDash.Essentials
|
||||
void CurrentRoom_OnFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
var value = _CurrentRoom.OnFeedback.BoolValue;
|
||||
Debug.Console(2, CurrentRoom, "UI: Is on event={0}", value);
|
||||
TriList.BooleanInput[UIBoolJoin.RoomIsOn].BoolValue = value;
|
||||
if (value) //ON
|
||||
{
|
||||
@@ -704,6 +718,46 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void CurrentRoom_IsWarmingFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
var value = CurrentRoom.IsWarmingUpFeedback.BoolValue;
|
||||
Debug.Console(2, CurrentRoom, "UI: WARMING event={0}", value);
|
||||
|
||||
if (value)
|
||||
{
|
||||
WarmingCoolingModal = new ModalDialog(TriList);
|
||||
WarmingCoolingModal.PresentModalDialog(0, "Powering up", "Power", "Room is warming up. Please wait.",
|
||||
"", "", false, false, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (WarmingCoolingModal != null)
|
||||
WarmingCoolingModal.CancelDialog();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IsCoolingDownFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
var value = CurrentRoom.IsCoolingDownFeedback.BoolValue;
|
||||
Debug.Console(2, CurrentRoom, "UI: Cooldown event={0}", value);
|
||||
|
||||
if (value)
|
||||
{
|
||||
WarmingCoolingModal = new ModalDialog(TriList);
|
||||
WarmingCoolingModal.PresentModalDialog(0, "Shutting down", "Power", "Room is shutting down. Please wait.",
|
||||
"", "", false, false, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (WarmingCoolingModal != null)
|
||||
WarmingCoolingModal.CancelDialog();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hides source for provided source info
|
||||
/// </summary>
|
||||
|
||||
@@ -655,7 +655,7 @@ namespace PepperDash.Essentials
|
||||
uint seconds = time / 1000;
|
||||
var message = string.Format("Meeting will end in {0} seconds", seconds);
|
||||
modal.PresentModalDialog(2, "End Meeting", "Power", message,
|
||||
"End Meeting Now", "Cancel", true,
|
||||
"End Meeting Now", "Cancel", true, true,
|
||||
but =>
|
||||
{
|
||||
EndMeetingButtonSig.BoolValue = false;
|
||||
|
||||
@@ -113,6 +113,14 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public const uint VolumesPageVisible = 3870;
|
||||
/// <summary>
|
||||
/// 3901
|
||||
/// </summary>
|
||||
public const uint TechPagesExitButton = 3901;
|
||||
/// <summary>
|
||||
/// 3902
|
||||
/// </summary>
|
||||
public const uint TechPanelSetupVisible = 3902;
|
||||
/// <summary>
|
||||
/// 3999
|
||||
/// </summary>
|
||||
public const uint GenericModalVisible = 3999;
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user