patch-packages #3
401
FHEM/82_LGTV_WebOS.pm
Normal file
401
FHEM/82_LGTV_WebOS.pm
Normal file
@ -0,0 +1,401 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Developed with VSCodium and richterger perl plugin.
|
||||
#
|
||||
# (c) 2017-2022 Copyright: Marko Oldenburg (fhemdevelopment at cooltux dot net)
|
||||
# All rights reserved
|
||||
#
|
||||
# Special thanks goes to comitters:
|
||||
# - Vitolinker / Commandref
|
||||
#
|
||||
#
|
||||
# This script is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# any later version.
|
||||
#
|
||||
# The GNU General Public License can be found at
|
||||
# http://www.gnu.org/copyleft/gpl.html.
|
||||
# A copy is found in the textfile GPL.txt and important notices to the license
|
||||
# from the author is found in LICENSE.txt distributed with these scripts.
|
||||
#
|
||||
# This script is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
#
|
||||
# $Id:
|
||||
#
|
||||
###############################################################################
|
||||
package FHEM::LGTV_WebOS;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
require FHEM::Devices::LGTV::LGTVWebOS;
|
||||
|
||||
use FHEM::Meta;
|
||||
|
||||
use GPUtils qw(GP_Import);
|
||||
|
||||
#-- Run before package compilation
|
||||
BEGIN {
|
||||
#-- Export to main context with different name
|
||||
GP_Import(qw( readingFnAttributes));
|
||||
}
|
||||
|
||||
sub ::LGTV_WebOS_Initialize { goto &Initialize }
|
||||
|
||||
sub Initialize {
|
||||
my $hash = shift;
|
||||
|
||||
# Provider
|
||||
$hash->{ReadFn} = \&FHEM::Devices::LGTV::LGTVWebOS::Read;
|
||||
$hash->{WriteFn} = \&FHEM::Devices::LGTV::LGTVWebOS::Write;
|
||||
|
||||
# Consumer
|
||||
$hash->{SetFn} = \&FHEM::Devices::LGTV::LGTVWebOS::Set;
|
||||
$hash->{DefFn} = \&FHEM::Devices::LGTV::LGTVWebOS::Define;
|
||||
$hash->{UndefFn} = \&FHEM::Devices::LGTV::LGTVWebOS::Undef;
|
||||
$hash->{AttrFn} = \&FHEM::Devices::LGTV::LGTVWebOS::Attr;
|
||||
$hash->{AttrList} =
|
||||
"disable:1 "
|
||||
. "channelGuide:1 "
|
||||
. "pingPresence:1 "
|
||||
. "wakeOnLanMAC "
|
||||
. "wakeOnLanBroadcast "
|
||||
. "wakeupCmd "
|
||||
. "keepAliveCheckTime "
|
||||
. $readingFnAttributes;
|
||||
|
||||
return FHEM::Meta::InitMod( __FILE__, $hash );
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
=item device
|
||||
=item summary Controls LG SmartTVs run with WebOS Operating System
|
||||
=item summary_DE Steuert LG SmartTVs mit WebOS Betriebssystem
|
||||
|
||||
=begin html
|
||||
|
||||
<a name="LGTV_WebOS"></a>
|
||||
<h3>LGTV_WebOS</h3>
|
||||
|
||||
<ul>
|
||||
This module controls SmartTVs from LG based on WebOS as operation system via network. It offers to swtich the TV channel, start and switch applications, send remote control commands, as well as to query the actual status.<p><br /><br />
|
||||
|
||||
<strong>Definition </strong><code>define <name> LGTV_WebOS <IP-Address></code>
|
||||
</p>
|
||||
<ul>
|
||||
<ul>
|
||||
When an LGTV_WebOS-Module is defined, an internal routine is triggered which queries the TV's status every 15s and triggers respective Notify / FileLog Event definitions.
|
||||
</ul>
|
||||
</ul>
|
||||
</p>
|
||||
<ul>
|
||||
<ul>
|
||||
Example:
|
||||
</ul>
|
||||
<ul>
|
||||
<code>define TV LGTV_WebOS 192.168.0.10 <br /></code><br /><br /></p>
|
||||
</ul>
|
||||
</ul>
|
||||
<p><code><strong>Set-Commands </strong><code>set <Name> <Command> [<Parameter>]</code></code></p>
|
||||
<ul>
|
||||
<ul>
|
||||
The following commands are supported in the actual version:
|
||||
</ul>
|
||||
</ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<li><strong>connect </strong> - Connects to the TV at the defined address. When triggered the first time, a pairing is conducted</li>
|
||||
<li><strong>pairing </strong> - Sends a pairing request to the TV which needs to be confirmed by the user with remote control</li>
|
||||
<li><strong>screenMsg</strong> <Text> - Displays a message for 3-5s on the TV in the top right corner of the screen</li>
|
||||
<li><strong>mute</strong> on, off - Turns volume to mute. Depending on the audio connection, this needs to be set on the AV Receiver (see volume) </li>
|
||||
<li><strong>volume </strong>0-100, Slider - Sets the volume. Depending on the audio connection, this needs to be set on the AV Receiver (see mute)</li>
|
||||
<li><strong>volumeUp</strong> - Increases the volume by 1</li>
|
||||
<li><strong>volumeDown</strong> - Decreases the volume by 1</li>
|
||||
<li><strong>channelUp</strong> - Switches the channel to the next one</li>
|
||||
<li><strong>channelDown</strong> - Switches the channel to the previous one</li>
|
||||
<li><strong>getServiceList </strong> - Queries the running services on WebOS (in beta phase)</li>
|
||||
<li><strong>on</strong> - Turns the TV on, depending on type of device. Only working when LAN or Wifi connection remains active during off state.</li>
|
||||
<li><strong>off</strong> - Turns the TV off, when an active connection is established</li>
|
||||
<li><strong>launchApp</strong> <Application> - Activates an application out of the following list (Maxdome, AmazonVideo, YouTube, Netflix, TV, GooglePlay, Browser, Chili, TVCast, Smartshare, Scheduler, Miracast, TV) <br />Note: TV is an application in LG's terms and not an input connection</li>
|
||||
<li><strong>3D</strong> on,off - 3D Mode is turned on and off. Depending on type of TV there might be different modes (e.g. Side-by-Side, Top-Bottom)</li>
|
||||
<li><strong>stop</strong> - Stop command (depending on application)</li>
|
||||
<li><strong>play </strong>- Play command (depending on application)</li>
|
||||
<li><strong>pause </strong>- Pause command (depending on application)</li>
|
||||
<li><strong>rewind </strong>- Rewind command (depending on application)</li>
|
||||
<li><strong>fastForward </strong>- Fast Forward command (depending on application)</li>
|
||||
<li><strong>clearInputList </strong> - Clears list of Inputs</li>
|
||||
<li><strong>input </strong> - Selects the input connection (depending on the actual TV type and connected devices) <br />e.g.: extInput_AV-1, extInput_HDMI-1, extInput_HDMI-2, extInput_HDMI-3)</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</ul><br /><br /></p>
|
||||
<p><strong>Get-Command</strong> <code>get <Name> <Readingname></code><br /></p>
|
||||
<ul>
|
||||
<ul>
|
||||
Currently, GET reads back the values of the current readings. Please see below for a list of Readings / Generated Events.
|
||||
</ul>
|
||||
</ul>
|
||||
<p><br /><strong>Attributes</strong></p>
|
||||
<ul>
|
||||
<ul>
|
||||
<li>disable</li>
|
||||
Optional attribute to deactivate the recurring status updates. Manual trigger of update is alsways possible.</br>
|
||||
Valid Values: 0 => recurring status updates, 1 => no recurring status updates.</p>
|
||||
</ul>
|
||||
</ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<li>channelGuide</li>
|
||||
Optional attribute to deactivate the recurring TV Guide update. Depending on TV and FHEM host, this causes significant network traffic and / or CPU load</br>
|
||||
Valid Values: 0 => no recurring TV Guide updates, 1 => recurring TV Guide updates.
|
||||
</ul>
|
||||
</ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<li>pingPresence</li>
|
||||
current state of ping presence from TV. create a reading presence with values absent or present.
|
||||
</ul>
|
||||
</ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<li>keepAliveCheckTime</li>
|
||||
value in seconds - keepAliveCheck is check read data input from tcp socket and prevented FHEM freeze.
|
||||
</ul>
|
||||
</ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<li>wakeOnLanMAC</li>
|
||||
Network MAC Address of the LG TV Networkdevice.
|
||||
</ul>
|
||||
</ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<li>wakeOnLanBroadcast</li>
|
||||
Broadcast Address of the Network - wakeOnLanBroadcast <network>.255
|
||||
</ul>
|
||||
</ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<li>wakeupCmd</li>
|
||||
Set a command to be executed when turning on an absent device. Can be an FHEM command or Perl command in {}.
|
||||
</ul>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
=end html
|
||||
|
||||
=begin html_DE
|
||||
|
||||
<a name="LGTV_WebOS"></a>
|
||||
<h3>LGTV_WebOS</h3>
|
||||
<ul>
|
||||
<ul>
|
||||
Dieses Modul steuert SmartTV's des Herstellers LG mit dem Betriebssystem WebOS über die Netzwerkschnittstelle. Es bietet die Möglichkeit den aktuellen TV Kanal zu steuern, sowie Apps zu starten, Fernbedienungsbefehle zu senden, sowie den aktuellen Status abzufragen.
|
||||
</ul>
|
||||
<p><br /><br /><strong>Definition </strong><code>define <name> LGTV_WebOS <IP-Addresse></code> <br /><br /></p>
|
||||
<ul>
|
||||
<ul>
|
||||
<ul>Bei der Definition eines LGTV_WebOS-Moduls wird eine interne Routine in Gang gesetzt, welche regelmäßig alle 15s den Status des TV abfragt und entsprechende Notify-/FileLog-Definitionen triggert.</ul>
|
||||
</ul>
|
||||
</ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<ul>Beispiel: <code>define TV LGTV_WebOS 192.168.0.10 <br /></code><br /><br /></ul>
|
||||
</ul>
|
||||
</ul>
|
||||
<strong>Set-Kommandos </strong><code>set <Name> <Kommando> [<Parameter>]</code>
|
||||
<ul>
|
||||
<ul>
|
||||
<ul>Aktuell werden folgende Kommandos unterstützt.</ul>
|
||||
</ul>
|
||||
</ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<li><strong>connect </strong> - Verbindet sich zum Fernseher unter der IP wie definiert, führt beim ersten mal automatisch ein pairing durch</li>
|
||||
<li><strong>pairing </strong> - Berechtigungsanfrage an den Fernseher, hier muss die Anfrage mit der Fernbedienung bestätigt werden</li>
|
||||
<li><strong>screenMsg</strong> <Text> - zeigt für ca 3-5s eine Nachricht auf dem Fernseher oben rechts an</li>
|
||||
<li><strong>mute</strong> on, off - Schaltet den Fernseher Stumm, je nach Anschluss des Audiosignals, muss dieses am Verstärker (AV Receiver) geschehen (siehe Volume)</li>
|
||||
<li><strong>volume </strong>0-100, Schieberegler - Setzt die Lautstärke des Fernsehers, je nach Anschluss des Audiosignals, muss dieses am Verstärker (AV Receiver) geschehen (siehe mute)</li>
|
||||
<li><strong>volumeUp</strong> - Erhöht die Lautstärke um den Wert 1</li>
|
||||
<li><strong>volumeDown</strong> - Verringert die Lautstärke um den Wert 1</li>
|
||||
<li><strong>channelUp</strong> - Schaltet auf den nächsten Kanal um</li>
|
||||
<li><strong>channelDown</strong> - Schaltet auf den vorherigen Kanal um</li>
|
||||
<li><strong>getServiceList </strong> - Fragrt die Laufenden Dienste des Fernsehers an (derzeit noch in Beta-Phase)</li>
|
||||
<li><strong>on</strong> - Schaltet den Fernseher ein, wenn WLAN oder LAN ebenfalls im Aus-Zustand aktiv ist (siehe Bedienungsanleitung da Typabhängig)</li>
|
||||
<li><strong>off</strong> - Schaltet den Fernseher aus, wenn eine Connection aktiv ist</li>
|
||||
<li><strong>launchApp</strong> <Anwendung> - Aktiviert eine Anwendung aus der Liste (Maxdome, AmazonVideo, YouTube, Netflix, TV, GooglePlay, Browser, Chili, TVCast, Smartshare, Scheduler, Miracast, TV) <br />Achtung: TV ist hier eine Anwendung, und kein Geräteeingang</li>
|
||||
<li><strong>3D</strong> on,off - 3D Modus kann hier ein- und ausgeschaltet werden, je nach Fernseher können mehrere 3D Modi unterstützt werden (z.B. Side-by-Side, Top-Bottom)</li>
|
||||
<li><strong>stop</strong> - Stop-Befehl (anwendungsabhängig)</li>
|
||||
<li><strong>play </strong>- Play-Befehl (anwendungsabhängig)</li>
|
||||
<li><strong>pause </strong>- Pause-Befehl (anwendungsabhängig)</li>
|
||||
<li><strong>rewind </strong>- Zurückspulen-Befehl (anwendungsabhängig)</li>
|
||||
<li><strong>fastForward </strong>- Schneller-Vorlauf-Befehl (anwendungsabhängig)</li>
|
||||
<li><strong>clearInputList </strong> - Löscht die Liste der Geräteeingänge</li>
|
||||
<li><strong>input </strong> - Wählt den Geräteeingang aus (Abhängig von Typ und angeschossenen Geräten) <br />Beispiele: extInput_AV-1, extInput_HDMI-1, extInput_HDMI-2, extInput_HDMI-3)</li>
|
||||
</ul>
|
||||
</ul
|
||||
</ul>
|
||||
</ul>
|
||||
<p><strong>Get-Kommandos</strong> <code>get <Name> <Readingname></code><br /><br /></p>
|
||||
<ul>
|
||||
<ul>
|
||||
<ul>Aktuell stehen via GET lediglich die Werte der Readings zur Verfügung. Eine genaue Auflistung aller möglichen Readings folgen unter "Generierte Readings/Events".</ul>
|
||||
</ul>
|
||||
</ul>
|
||||
<p><br /><br /><strong>Attribute</strong></p>
|
||||
<ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<li>disable</li>
|
||||
Optionales Attribut zur Deaktivierung des zyklischen Status-Updates. Ein manuelles Update via statusRequest-Befehl ist dennoch möglich.
|
||||
</ul>
|
||||
</ul>
|
||||
</ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<ul>Mögliche Werte: 0 => zyklische Status-Updates, 1 => keine zyklischen Status-Updates.</ul>
|
||||
</ul>
|
||||
</ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<li>channelGuide</li>
|
||||
Optionales Attribut zur Deaktivierung der zyklischen Updates des TV-Guides, dieses beansprucht je nach Hardware einigen Netzwerkverkehr und Prozessorlast
|
||||
</ul>
|
||||
</ul>
|
||||
</ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<ul>Mögliche Werte: 0 => keine zyklischen TV-Guide-Updates, 1 => zyklische TV-Guide-Updates</ul>
|
||||
</ul>
|
||||
</ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<li>wakeOnLanMAC</li>
|
||||
MAC Addresse der Netzwerkkarte vom LG TV
|
||||
</ul>
|
||||
</ul>
|
||||
</ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<li>wakeOnLanBroadcast</li>
|
||||
Broadcast Netzwerkadresse - wakeOnLanBroadcast <netzwerk>.255
|
||||
</ul>
|
||||
</ul>
|
||||
</ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<li>pingPresence</li>
|
||||
Mögliche Werte: 0 => presence via ping deaktivert, 1 => presence via ping aktiviert
|
||||
</ul>
|
||||
</ul>
|
||||
</ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<li>keepAliveCheckTime</li>
|
||||
Wert in Sekunden - keepAliveCheckTime
|
||||
kontrolliert in einer bestimmten Zeit ob noch Daten über die TCP Schnittstelle kommen und verhindert somit FHEM Freezes
|
||||
</ul>
|
||||
</ul>
|
||||
</ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<ul>
|
||||
<li>wakeupCmd</li>
|
||||
Befehl zum Einschalten des LG TV. Möglich ist ein FHEM Befehl oder Perl in {}.
|
||||
</ul>
|
||||
</ul>
|
||||
</ul>
|
||||
<p><br /><br /><strong>Generierte Readings/Events:</strong></p>
|
||||
<ul>
|
||||
<ul>
|
||||
<li><strong>3D</strong> - Status des 3D-Wiedergabemodus ("on" => 3D Wiedergabemodus aktiv, "off" => 3D Wiedergabemodus nicht aktiv)</li>
|
||||
<li><strong>3DMode</strong> - Anzeigemodus (2d, 2dto3d, side_side_half, line_interleave_half, column_interleave, check_board)</li>
|
||||
<li><strong>channel</strong> - Die Nummer des aktuellen TV-Kanals</li>
|
||||
<li><strong>channelName</strong> - Der Name des aktuellen TV-Kanals</li>
|
||||
<li><strong>channelMedia</strong> - Senderinformation</li>
|
||||
<li><strong>channelCurrentEndTime </strong>- Ende der laufenden Sendung (Beta)</li>
|
||||
<li><strong>channelCurrentStartTime </strong>- Start der laufenden Sendung (Beta)</li>
|
||||
<li><strong>channelCurrentTitle</strong> - Der Name der laufenden Sendung (Beta)</li>
|
||||
<li><strong>channelNextEndTime </strong>- Ende der nächsten Sendung (Beta)</li>
|
||||
<li><strong>channelNextStartTime </strong>- Start der nächsten Sendung (Beta)</li>
|
||||
<li><strong>channelNextTitle</strong> - Der Name der nächsten Sendung (Beta)</li>
|
||||
<li><strong>extInput_<Geräteeingang</strong>> - Status der Eingangsquelle (connect_true, connect_false)</li>
|
||||
<li><strong>input</strong> - Derzeit aktiver Geräteeingang</li>
|
||||
<li><strong>lastResponse </strong>- Status der letzten Anfrage (ok, error <Fehlertext>)</li>
|
||||
<li><strong>launchApp</strong> <Anwendung> - Gegenwärtige aktive Anwendung</li>
|
||||
<li><strong>lgKey</strong> - Der Client-Key, der für die Verbindung verwendet wird</li>
|
||||
<li><strong>mute</strong> on,off - Der aktuelle Stumm-Status ("on" => Stumm, "off" => Laut)</li>
|
||||
<li><strong>pairing</strong> paired, unpaired - Der Status des Pairing</li>
|
||||
<li><strong>presence </strong>absent, present - Der aktuelle Power-Status ("present" => eingeschaltet, "absent" => ausgeschaltet)</li>
|
||||
<li><strong>state</strong> on, off - Status des Fernsehers (ähnlich presence)</li>
|
||||
<li><strong>volume</strong> - Der aktuelle Lautstärkepegel -1, 0-100 (-1 invalider Wert)</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</ul>
|
||||
=end html_DE
|
||||
|
||||
=for :application/json;q=META.json 82_LGTV_WebOS.pm
|
||||
{
|
||||
"abstract": "Module for Controls LG SmartTVs run with WebOS Operating System",
|
||||
"x_lang": {
|
||||
"de": {
|
||||
"abstract": "Modul zur Steuerung von LG SmartTVs mit WebOS Betriebssystem"
|
||||
}
|
||||
},
|
||||
"keywords": [
|
||||
"fhem-mod-device",
|
||||
"fhem-core",
|
||||
"Multimedia",
|
||||
"TV",
|
||||
"LG"
|
||||
],
|
||||
"release_status": "stable",
|
||||
"license": "GPL_2",
|
||||
"version": "v3.6.1",
|
||||
"author": [
|
||||
"Marko Oldenburg <fhemdevelopment@cooltux.net>"
|
||||
],
|
||||
"x_fhem_maintainer": [
|
||||
"CoolTux"
|
||||
],
|
||||
"x_fhem_maintainer_github": [
|
||||
"LeonGaultier"
|
||||
],
|
||||
"prereqs": {
|
||||
"runtime": {
|
||||
"requires": {
|
||||
"FHEM": 5.00918799,
|
||||
"perl": 5.016,
|
||||
"Meta": 1,
|
||||
"JSON": 1,
|
||||
"Date::Parse": 0
|
||||
},
|
||||
"recommends": {
|
||||
"JSON": 0
|
||||
},
|
||||
"suggests": {
|
||||
"Cpanel::JSON::XS": 0,
|
||||
"JSON::XS": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
=end :application/json;q=META.json
|
||||
|
||||
=cut
|
2
controls_LGTV_WebOS.txt
Normal file
2
controls_LGTV_WebOS.txt
Normal file
@ -0,0 +1,2 @@
|
||||
UPD 2022-02-08_07:16:43 18966 FHEM/82_LGTV_WebOS.pm
|
||||
UPD 2022-02-08_07:16:48 54278 lib/FHEM/Devices/LGTV/LGTVWebOS.pm
|
39
hooks/pre-commit
Executable file
39
hooks/pre-commit
Executable file
@ -0,0 +1,39 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use File::Basename;
|
||||
use POSIX qw(strftime);
|
||||
use strict;
|
||||
|
||||
my @filenames =
|
||||
( 'FHEM/82_LGTV_WebOS.pm', 'lib/FHEM/Devices/LGTV/LGTVWebOS.pm' );
|
||||
|
||||
my $controlsfile = 'controls_LGTV_WebOS.txt';
|
||||
|
||||
open( FH, ">$controlsfile" ) || return ("Can't open $controlsfile: $!");
|
||||
|
||||
for my $filename (@filenames) {
|
||||
my @statOutput = stat($filename);
|
||||
|
||||
if ( scalar @statOutput != 13 ) {
|
||||
printf 'error: stat has unexpected return value for '
|
||||
. $filename . "\n";
|
||||
next;
|
||||
}
|
||||
|
||||
my $mtime = $statOutput[9];
|
||||
my $date = POSIX::strftime( "%Y-%m-%d", localtime($mtime) );
|
||||
my $time = POSIX::strftime( "%H:%M:%S", localtime($mtime) );
|
||||
my $filetime = $date . "_" . $time;
|
||||
|
||||
my $filesize = $statOutput[7];
|
||||
|
||||
printf FH 'UPD ' . $filetime . ' ' . $filesize . ' ' . $filename . "\n";
|
||||
}
|
||||
|
||||
close(FH);
|
||||
|
||||
system("git add $controlsfile");
|
||||
|
||||
print 'Create controls File succesfully' . "\n";
|
||||
|
||||
exit 0;
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user