Initial commit
This commit is contained in:
22
actions/apply-settings.php
Normal file
22
actions/apply-settings.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Es gibt nur einen Steckertypen, daher ist dies zunächst irrelvant
|
||||||
|
|
||||||
|
$type = $_GET["type"];
|
||||||
|
|
||||||
|
$settings = json_decode(file_get_contents("../settings.json"), true);
|
||||||
|
|
||||||
|
$plug = $settings["plug"]; //$plug ist die plug-ID!
|
||||||
|
|
||||||
|
|
||||||
|
Weitere Zeilen entfernt. Speicherung wäre notwendig.
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
echo "Sp Dr L30";
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
131
actions/bridge-editor.php
Normal file
131
actions/bridge-editor.php
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
$db = new SQLite3('../db-test/test.db');
|
||||||
|
|
||||||
|
$action = $_GET["action"];
|
||||||
|
$meta = $_GET["meta"];
|
||||||
|
|
||||||
|
$bridgeName = $_SESSION["meta"];
|
||||||
|
|
||||||
|
$plug = json_decode(file_get_contents("../settings.json") , true)["plug"];
|
||||||
|
|
||||||
|
|
||||||
|
// Funktion zur Bereinigung des Formats
|
||||||
|
function cleanPinsArray(&$data) {
|
||||||
|
// Überprüfen, ob das "pins"-Array vorhanden ist und es ein Array ist
|
||||||
|
if (isset($data) && is_array($data)) {
|
||||||
|
// Nur gültige Pins behalten
|
||||||
|
$data = array_filter($data, function($pin) {
|
||||||
|
// Sicherstellen, dass das Element nicht null ist und dass jedes Element im "pins"-Array genau 2 Einträge hat
|
||||||
|
return is_array($pin) && count($pin) === 2 && is_integer($pin[0]) && is_integer($pin[1]);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Neu indexieren, um die Indizes korrekt zu halten
|
||||||
|
$data = array_values($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($action) {
|
||||||
|
case "edit":
|
||||||
|
|
||||||
|
$bridge_name = $bridgeName;
|
||||||
|
|
||||||
|
$nodes = json_decode($meta, true); // Beispielwert
|
||||||
|
$nodes = $nodes["pins"]; // Beispielwert
|
||||||
|
|
||||||
|
cleanPinsArray($nodes); // Dies stellt sicher, dass Javscript valide Werte bringt und die Datenbank nicht verunreinigt wird.
|
||||||
|
|
||||||
|
if (empty($nodes))
|
||||||
|
{
|
||||||
|
$message[0] = false;
|
||||||
|
$message[1] = "Es wurden keine Änderungen gespeichert.";
|
||||||
|
$message = json_encode($message);
|
||||||
|
print ($message);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
$db->exec(" DELETE FROM nodes WHERE required_by = '" . $bridge_name . "' and plug_id = '" . $plug . "'; ");
|
||||||
|
|
||||||
|
foreach($nodes as $node) {
|
||||||
|
$from = $node[0];
|
||||||
|
$to = $node[1];
|
||||||
|
$db->exec(" INSERT INTO nodes (required_by, node_from, node_to, plug_id) VALUES ('" . $bridge_name . "', '" . $from . "', '" . $to . "', '" . $plug . "'); ");
|
||||||
|
}
|
||||||
|
|
||||||
|
$message[0] = true;
|
||||||
|
$message[1] = "Die Änderungen für die Brücke $bridgeName wurden gespeichert!";
|
||||||
|
$message = json_encode($message);
|
||||||
|
print ($message);
|
||||||
|
die();
|
||||||
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "add":
|
||||||
|
|
||||||
|
// Eingabedaten
|
||||||
|
$bridgeName = $bridgeName;
|
||||||
|
$nodes = json_decode($meta, true);
|
||||||
|
$name = $nodes["name"];
|
||||||
|
$nodes = $nodes["pins"];
|
||||||
|
|
||||||
|
cleanPinsArray($nodes); // Dies stellt sicher, dass Javscript valide Werte bringt und die Datenbank nicht verunreinigt wird.
|
||||||
|
|
||||||
|
// sicherstellen, dass Werte gesetzt sind
|
||||||
|
if (empty($nodes) || empty($name))
|
||||||
|
{
|
||||||
|
$message[0] = false;
|
||||||
|
$message[1] = "Es wurden keine Änderungen gespeichert, da Parameter fehlten.";
|
||||||
|
$message = json_encode($message);
|
||||||
|
print ($message);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$result = $db->query("SELECT COUNT(*) as anzahl FROM bridges WHERE id = '" . $name . "';");
|
||||||
|
$row = $result->fetchArray(SQLITE3_ASSOC);
|
||||||
|
$number = $row['anzahl'];
|
||||||
|
|
||||||
|
if($number > 0) {
|
||||||
|
$message[0] = false;
|
||||||
|
$message[1] = "Es gibt bereits eine Brücke, die " . $name . " heißt. Bitte einen anderen Namen wählen oder die andere Brücke " . $name . " löschen/bearbeiten. Stellen Sie zudem sicher, dass Sie den korrekten Steckertypen verwenden.";
|
||||||
|
$message = json_encode($message);
|
||||||
|
print ($message);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
$db->exec(" INSERT INTO bridges (plug_id, id) VALUES (" . $plug . ", '" . $name . "'); ");
|
||||||
|
|
||||||
|
foreach($nodes as $node) {
|
||||||
|
$from = $node[0];
|
||||||
|
$to = $node[1];
|
||||||
|
$db->exec(" INSERT INTO nodes (required_by, node_from, node_to, plug_id) VALUES ('" . $name . "', '" . $from . "', '" . $to . "', '" . $plug . "'); ");
|
||||||
|
}
|
||||||
|
|
||||||
|
$message[0] = true;
|
||||||
|
$message[1] = "Die Brücke $name wurde angelegt!";
|
||||||
|
$message = json_encode($message);
|
||||||
|
print ($message);
|
||||||
|
die();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "remove":
|
||||||
|
|
||||||
|
$bridge_name = $meta;
|
||||||
|
|
||||||
|
$db->exec(" DELETE FROM nodes WHERE required_by = '" . $bridge_name . "' and plug_id = '" . $plug . "'; ");
|
||||||
|
$db->exec(" DELETE FROM bridges WHERE id = '" . $bridge_name . "' and plug_id = '" . $plug . "'; ");
|
||||||
|
|
||||||
|
$message[0] = true;
|
||||||
|
$message[1] = "Die Brücke $bridge_name wurde nun gelöscht.";
|
||||||
|
$message = json_encode($message);
|
||||||
|
print ($message);
|
||||||
|
die();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
5
actions/connection-test.php
Normal file
5
actions/connection-test.php
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
print("true");
|
||||||
|
|
||||||
|
?>
|
||||||
1182
actions/extract-programs.php
Normal file
1182
actions/extract-programs.php
Normal file
File diff suppressed because it is too large
Load Diff
138
actions/inventory.php
Normal file
138
actions/inventory.php
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$db = new SQLite3('../db-test/test.db');
|
||||||
|
|
||||||
|
$page = $_GET["page"];
|
||||||
|
$action = $_GET["action"];
|
||||||
|
$meta = $_GET["meta"];
|
||||||
|
|
||||||
|
$settings = json_decode(file_get_contents("../settings.json"), true);
|
||||||
|
$plug = $settings["plug"]; //$plug ist die plug-ID!
|
||||||
|
|
||||||
|
$bridgeName = $_SESSION["meta"];
|
||||||
|
$programID = json_decode(urldecode($_SESSION["meta"]), true);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
switch($action) {
|
||||||
|
|
||||||
|
case "remove":
|
||||||
|
|
||||||
|
$settings = json_decode(file_get_contents("../settings.json"), true);
|
||||||
|
|
||||||
|
$plug = $settings["plug"]; //$plug ist die plug-ID!
|
||||||
|
|
||||||
|
// Überprüfen, ob die Struktur korrekt ist
|
||||||
|
if (!isset($meta)) {
|
||||||
|
$message[0] = false;
|
||||||
|
$message[1] = "Es gab einen Fehler bei der Datenübermittlung.";
|
||||||
|
$message = json_encode($message);
|
||||||
|
print($message);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hier wichtig! Beim Löschvorgang muss die referenzielle Integrität gewahrt werden! Erst die Fremdschlüssel löschen, dann die Tabelle mit dem Primärschlüssel!
|
||||||
|
|
||||||
|
$db->exec(" DELETE FROM measurement_nodes WHERE required_by = '" . $meta . "'; ");
|
||||||
|
$db->exec(" DELETE FROM measurement_program_id_bits WHERE measurement_id = '" . $meta . "'; ");
|
||||||
|
$db->exec(" DELETE FROM measurements WHERE id = '" . $meta . "'; ");
|
||||||
|
|
||||||
|
|
||||||
|
$message[0] = true;
|
||||||
|
$message[1] = "Die Messung wurde gelöscht.";
|
||||||
|
$message = json_encode($message);
|
||||||
|
print($message);
|
||||||
|
die();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case "add":
|
||||||
|
|
||||||
|
$meta = json_decode($meta, true);
|
||||||
|
|
||||||
|
if(empty($meta["programCache"]) || empty($_SESSION["bridges"]) || empty($meta['name'])) {
|
||||||
|
$message[0] = false;
|
||||||
|
$message[1] = "Es gab einen Fehler beim Speichern!";
|
||||||
|
$message = json_encode($message);
|
||||||
|
print($message);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$db->exec("INSERT INTO places (plug_id, name) VALUES (" . $plug . ", '" . $meta["name"]. "'); ");
|
||||||
|
|
||||||
|
$newdata["plugID"] = $plug;
|
||||||
|
$newdata["place"] = $placeID;
|
||||||
|
$newdata["programID"] = $meta["programCache"];
|
||||||
|
$bridges_original = $_SESSION["bridges"];
|
||||||
|
$newdata["special"] = $meta["special"];
|
||||||
|
$bridges_hidden = json_decode(urldecode($meta["bridges-hidden"]));
|
||||||
|
$newdata["timestamp"] = time();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// $bridges_result = $bridges_original - $bridges_hidden
|
||||||
|
$bridges_original;
|
||||||
|
$bridges_hidden;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Hilfsfunktion: vergleicht zwei Arrays inhaltlich, unabhängig von String/Int
|
||||||
|
function arrays_are_equal($a, $b) {
|
||||||
|
return ((string)$a[0] === (string)$b[0]) && ((string)$a[1] === (string)$b[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ergebnisarray initialisieren
|
||||||
|
$bridges_result = [];
|
||||||
|
|
||||||
|
// Für jedes Originalelement prüfen, ob es in hidden vorkommt
|
||||||
|
foreach ($bridges_original as $orig) {
|
||||||
|
$found = false;
|
||||||
|
foreach ($bridges_hidden as $hidden) {
|
||||||
|
if (arrays_are_equal($orig, $hidden)) {
|
||||||
|
$found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$found) {
|
||||||
|
$bridges_result[] = $orig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$newdata["bridges"] = $bridges_result;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$db->exec("INSERT INTO measurements (place_name, comment, timestamp) VALUES ('" . $meta["name"] . "', '" . $meta["special"] . "', " . time() . ");");
|
||||||
|
|
||||||
|
$measurement_id = $db->lastInsertRowID();
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
foreach($meta["programCache"] as $program_id_char) {
|
||||||
|
$db->exec("INSERT INTO measurement_program_id_bits (value, position, measurement_id) VALUES ('" . $program_id_char . "', '" . $i. "', '" . $measurement_id . "'); ");
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($newdata["bridges"] as $bridge) {
|
||||||
|
$db->exec("INSERT INTO measurement_nodes (required_by, node_from, node_to) VALUES (" . $measurement_id . ", '" . $bridge[0]. "', '" . $bridge[1] . "'); ");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$message[0] = true;
|
||||||
|
$message[1] = "Die Messung wurde am Ort '" . $meta['name'] . "' gespeichert!";
|
||||||
|
$message = json_encode($message);
|
||||||
|
print($message);
|
||||||
|
die();
|
||||||
|
break;
|
||||||
|
}
|
||||||
140
actions/program-editor.php
Normal file
140
actions/program-editor.php
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
$db = new SQLite3('../db-test/test.db');
|
||||||
|
|
||||||
|
$action = $_GET["action"];
|
||||||
|
$meta = $_GET["meta"];
|
||||||
|
|
||||||
|
$bridgeName = $_SESSION["meta"];
|
||||||
|
$programID = json_decode(urldecode($_SESSION["meta"]), true);
|
||||||
|
|
||||||
|
|
||||||
|
$plug = json_decode(file_get_contents("../settings.json"), true)["plug"];
|
||||||
|
|
||||||
|
|
||||||
|
switch ($action) {
|
||||||
|
case "add":
|
||||||
|
|
||||||
|
$meta = json_decode($meta, true);
|
||||||
|
$bridges = $meta["bridges"];
|
||||||
|
$programID = $meta["programID"];
|
||||||
|
$programDescription = $meta["programDescription"];
|
||||||
|
|
||||||
|
if(empty($bridges) || empty($programID)) {
|
||||||
|
$message[0] = false;
|
||||||
|
$message[1] = "Es wurden keine Änderungen gespeichert.";
|
||||||
|
$message = json_encode($message);
|
||||||
|
print($message);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$result = $db->query("SELECT COUNT(*) as anzahl FROM program_id_bits WHERE
|
||||||
|
position = 0 AND value = '" . $programID[0] . "' AND
|
||||||
|
position = 1 AND value = '" . $programID[1] . "' AND
|
||||||
|
position = 2 AND value = '" . $programID[2] . "' AND
|
||||||
|
position = 3 AND value = '" . $programID[3] . "' AND
|
||||||
|
position = 4 AND value = '" . $programID[4] . "'
|
||||||
|
;");
|
||||||
|
|
||||||
|
$row = $result->fetchArray(SQLITE3_ASSOC);
|
||||||
|
$number = $row['anzahl'];
|
||||||
|
|
||||||
|
if($number > 0) {
|
||||||
|
$message[0] = false;
|
||||||
|
$message[1] = "Diese Programm-ID existiert unter dem aktuell gewählten Stecker bereits. Bitte anderen Namen wählen oder den Stecker wechseln.";
|
||||||
|
$message = json_encode($message);
|
||||||
|
print($message);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
$db->exec(" INSERT INTO programs (plug_id, program_description) VALUES ('" . $plug . "', '" . $programDescription . "'); ");
|
||||||
|
|
||||||
|
$program_id = $db->lastInsertRowID();
|
||||||
|
foreach($bridges as $bridge) {
|
||||||
|
$db->exec(" INSERT INTO program_bridge_relation (program_id, bridge_id, plug_id) VALUES ('" . $program_id . "', '" . $bridge . "', '" . $plug . "'); ");
|
||||||
|
}
|
||||||
|
|
||||||
|
for($i=0; $i<=4; $i++) {
|
||||||
|
$db->exec(" INSERT INTO program_id_bits (value, position, program_id) VALUES ('" . $programID[$i] . "', '" . $i . "', '" . $program_id . "'); ");
|
||||||
|
}
|
||||||
|
|
||||||
|
$message[0] = true;
|
||||||
|
$message[1] = 'Das Programm wurde als <div class="label" style="width: 160px; display: inline-block; float: unset; height: unset;margin-bottom: -10px;">
|
||||||
|
<span style="margin: unset;"><span class="label-char">' . $programID[0] . '</span><span class="label-char">' . $programID[1] . '</span><span class="label-char">' . $programID[2] . '</span><span class="label-char">' . $programID[3] . '</span><span class="label-char">' . $programID[4] . '</span>
|
||||||
|
</span>
|
||||||
|
</div> gespeichert!';
|
||||||
|
$message = json_encode($message);
|
||||||
|
print($message);
|
||||||
|
die();
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "edit":
|
||||||
|
|
||||||
|
$meta = json_decode(urldecode($meta),true);
|
||||||
|
$bridges = $meta["bridges"];
|
||||||
|
$programDescription = $meta["programDescription"];
|
||||||
|
|
||||||
|
if(empty($bridges) || empty($programDescription)) {
|
||||||
|
$message[0] = false;
|
||||||
|
$message[1] = "Es wurden keine Änderungen gespeichert.";
|
||||||
|
$message = json_encode($message);
|
||||||
|
print($message);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
$db->exec(" UPDATE programs set program_description = '" . $programDescription . "' WHERE id = '" . $programID . "' AND plug_id = '" . $plug . "'; ");
|
||||||
|
$db->exec(" DELETE FROM program_bridge_relation WHERE program_id = '" . $programID . "' and plug_id = '" . $plug . "'; ");
|
||||||
|
|
||||||
|
foreach($bridges as $bridge) {
|
||||||
|
$db->exec(" INSERT INTO program_bridge_relation (program_id, bridge_id, plug_id) VALUES ('" . $programID . "', '" . $bridge . "', '" . $plug . "'); ");
|
||||||
|
}
|
||||||
|
|
||||||
|
$message[0] = true;
|
||||||
|
$message[1] = 'Die Änderungen an <div class="label" style="width: 160px; display: inline-block; float: unset; height: unset;margin-bottom: -10px;"><span style="margin: unset;">';
|
||||||
|
|
||||||
|
$program_identifiers = $db->query("SELECT * FROM program_id_bits WHERE program_id = '" . $programID . "';");
|
||||||
|
|
||||||
|
while ($program_identifier = $program_identifiers->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
$message[1] .= '<span class="label-char">' . $program_identifier["value"] . '</span>';
|
||||||
|
}
|
||||||
|
|
||||||
|
$message[1] .= '</span></div> wurden gespeichert!';
|
||||||
|
|
||||||
|
$message = json_encode($message);
|
||||||
|
print($message);
|
||||||
|
die();
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "remove":
|
||||||
|
$programID = $meta;
|
||||||
|
|
||||||
|
// Überprüfen, ob die Struktur korrekt ist
|
||||||
|
if (!isset($meta)) {
|
||||||
|
$message[0] = false;
|
||||||
|
$message[1] = "Es gab einen Fehler bei der Datenübermittlung.";
|
||||||
|
$message = json_encode($message);
|
||||||
|
print($message);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hier wichtig! Beim Löschvorgang muss die referenzielle Integrität gewahrt werden! Erst die Fremdschlüssel löschen, dann die Tabelle mit dem Primärschlüssel!
|
||||||
|
|
||||||
|
$db->exec(" DELETE FROM program_bridge_relation WHERE program_id = '" . $meta . "' and plug_id = '" . $plug . "'; ");
|
||||||
|
$db->exec(" DELETE FROM program_id_bits WHERE program_id = '" . $meta . "'; ");
|
||||||
|
$db->exec(" DELETE FROM programs WHERE id = '" . $meta . "' and plug_id = '" . $plug . "'; ");
|
||||||
|
|
||||||
|
|
||||||
|
$message[0] = true;
|
||||||
|
$message[1] = "Das Programm wurde nun gelöscht.";
|
||||||
|
$message = json_encode($message);
|
||||||
|
print ($message);
|
||||||
|
die();
|
||||||
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
16
actions/save-settings.php
Normal file
16
actions/save-settings.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
$type = $_GET["type"];
|
||||||
|
$value = $_GET["value"];
|
||||||
|
|
||||||
|
$settings = json_decode(file_get_contents("../settings.json"), true);
|
||||||
|
|
||||||
|
$settings[$type] = $value;
|
||||||
|
|
||||||
|
file_put_contents("../temp.json",json_encode($settings, true));
|
||||||
|
|
||||||
|
|
||||||
|
print("true");
|
||||||
|
|
||||||
|
?>
|
||||||
5
alt/actions/connection-test.php
Normal file
5
alt/actions/connection-test.php
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
print("true");
|
||||||
|
|
||||||
|
?>
|
||||||
32
alt/index.php
Normal file
32
alt/index.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script src="/vendor/jquery.min.js"></script>
|
||||||
|
<script src="script.js"></script>
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
</head>
|
||||||
|
<body onload="pageload(), checkConnection(), applySettings('plug')" onhashchange="pageload()">
|
||||||
|
<div class="main">
|
||||||
|
<div class="navigation">
|
||||||
|
<div class="navigation-header" onclick="secondaryNavigation('open','plug-select')">
|
||||||
|
Steckerauswahl
|
||||||
|
<div>Wird geladen...</div>
|
||||||
|
</div>
|
||||||
|
<div id="index" id="start" onclick="window.location.href='#index'; pageload();"><img src="/vendor/icons/electric-plug-icon.svg" />Federleiste prüfen</div>
|
||||||
|
<div id="cable-check" onclick="window.location.href='#cable-check'; pageload();"><img src="/vendor/icons/fiber-cable-icon.svg" />Spurkabel prüfen</div>
|
||||||
|
<div id="index" class="navigation-footer">
|
||||||
|
<div class="connection-indicator unknown"></div>Verbinde...<br>
|
||||||
|
<img class="infrago-logo" src="/vendor/DB_InfraGo_logo_red_black_100px_rgb.svg" width="100%" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="navigation secondary" id="navigation-secondary">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div id="message-box" style="display: none;position: absolute; bottom: 10px; left: 260px; right: 10px; background-color:grey;height:auto;padding:20px;box-sizing:border-box;transform: translateY(calc(100% + 5px));transition-duration:.5s; border-radius: 10px;background-color: #d2d2d2;z-index: 502;"></div>
|
||||||
|
<div class="content" id="content">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
24
alt/pagecontent/index.php
Normal file
24
alt/pagecontent/index.php
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
header('Content-Type: text/plain');
|
||||||
|
header('Cache-Control: no-cache');
|
||||||
|
ob_implicit_flush(true);
|
||||||
|
ob_end_flush();
|
||||||
|
|
||||||
|
$view = $_GET["view"];
|
||||||
|
$meta = $_GET["meta"];
|
||||||
|
|
||||||
|
$_SESSION["meta"]=$meta;
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
|
<div class="content-header">Federleiste prüfen</div>
|
||||||
|
<hr />
|
||||||
|
<p>Automatische Erkennung</p>
|
||||||
|
<i>Verbinden Sie den zu messenden Stecker mit dem Gerät. Vermeiden Sie Bewegungen während der Messung.</i>
|
||||||
|
|
||||||
|
<div class="save-button" onclick="window.location.href='#start';$('.save-button').html('<img src=\'/vendor/icons/load.gif\' \>Initialisieren...'); "><img src="/vendor/icons/play.svg" \>Jetzt prüfen</div>
|
||||||
|
|
||||||
|
|
||||||
339
alt/pagecontent/start.php
Normal file
339
alt/pagecontent/start.php
Normal file
@@ -0,0 +1,339 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
|
||||||
|
header('Content-Type: text/plain');
|
||||||
|
header('Cache-Control: no-cache');
|
||||||
|
ob_implicit_flush(true);
|
||||||
|
ob_end_flush();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$translationMap = [
|
||||||
|
"A" => "30",
|
||||||
|
"B" => "20",
|
||||||
|
"C" => "10",
|
||||||
|
"D" => "39",
|
||||||
|
"E" => "29",
|
||||||
|
"F" => "19",
|
||||||
|
"G" => "38",
|
||||||
|
"H" => "28",
|
||||||
|
"I" => "18",
|
||||||
|
"J" => "37",
|
||||||
|
"K" => "27",
|
||||||
|
"L" => "17",
|
||||||
|
"M" => "36",
|
||||||
|
"N" => "26",
|
||||||
|
"O" => "16",
|
||||||
|
"P" => "35",
|
||||||
|
"Q" => "25",
|
||||||
|
"R" => "15",
|
||||||
|
"S" => "34",
|
||||||
|
"T" => "24",
|
||||||
|
"U" => "14",
|
||||||
|
"V" => "33",
|
||||||
|
"W" => "23",
|
||||||
|
"X" => "13",
|
||||||
|
"Y" => "32",
|
||||||
|
"Z" => "22",
|
||||||
|
"AA" => "12",
|
||||||
|
"AB" => "31",
|
||||||
|
"AC" => "21",
|
||||||
|
"AD" => "11"
|
||||||
|
];
|
||||||
|
|
||||||
|
function translateArray($inputArray, $translationMap) {
|
||||||
|
return array_map(function($subArray) use ($translationMap) {
|
||||||
|
return array_map(function($item) use ($translationMap) {
|
||||||
|
return $translationMap[$item] ?? $item; // Falls kein Mapping existiert, bleibt das Original erhalten
|
||||||
|
}, $subArray);
|
||||||
|
}, $inputArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
flush();
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
div.check-loading-screen {
|
||||||
|
width: 250px;
|
||||||
|
height: auto;
|
||||||
|
background-color: #ebebeb;
|
||||||
|
margin: 0 auto;
|
||||||
|
text-align: left;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 25px;
|
||||||
|
}
|
||||||
|
div.check-loading-screen div {
|
||||||
|
|
||||||
|
padding: 5px;
|
||||||
|
margin: 10px;
|
||||||
|
line-height: 30px;
|
||||||
|
transition-duration: .4s;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 10px;
|
||||||
|
|
||||||
|
}
|
||||||
|
div.check-loading-screen div img {
|
||||||
|
width: 30px;
|
||||||
|
margin-right: 20px;
|
||||||
|
vertical-align: middle;
|
||||||
|
filter: contrast(0.3);
|
||||||
|
line-height: 30px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="check-loading-screen" id="_1">
|
||||||
|
<div>
|
||||||
|
<img src="/vendor/icons/load.gif">Initialisieren
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<img src="/vendor/icons/clock-rotate-right.svg">Prüfung 1/2
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<img src="/vendor/icons/clock-rotate-right.svg">Prüfung 2/2
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
flush();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// To Run the Python program
|
||||||
|
$command = escapeshellcmd('python3 /var/www/html/alt/python/plug-check.py');
|
||||||
|
|
||||||
|
// Use shell_exec to execute the command and capture the output
|
||||||
|
$output0 = shell_exec($command);
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#_1 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="check-loading-screen" id="_2">
|
||||||
|
<div>
|
||||||
|
<img src="/vendor/icons/check.svg">Initialisieren
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<img src="/vendor/icons/load.gif">Prüfung 1/2
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<img src="/vendor/icons/clock-rotate-right.svg">Prüfung 2/2
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$command = escapeshellcmd('python3 /var/www/html/alt/python/plug-check.py');
|
||||||
|
|
||||||
|
|
||||||
|
// Use shell_exec to execute the command and capture the output
|
||||||
|
$bridges1 = shell_exec($command);
|
||||||
|
|
||||||
|
|
||||||
|
$number_bridges1 = count(json_decode($bridges1, true));
|
||||||
|
|
||||||
|
?>
|
||||||
|
<style>
|
||||||
|
#_2 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="check-loading-screen" id="_3">
|
||||||
|
<div>
|
||||||
|
<img src="/vendor/icons/check.svg">Initialisieren
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<img src="/vendor/icons/check.svg">Prüfung 1/2 (<?php echo $number_bridges1; ?>x)
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<img src="/vendor/icons/load.gif">Prüfung 2/2
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$command = escapeshellcmd('python3 /var/www/html/alt/python/plug-check.py');
|
||||||
|
|
||||||
|
// Use shell_exec to execute the command and capture the output
|
||||||
|
$bridges2 = shell_exec($command);
|
||||||
|
|
||||||
|
?>
|
||||||
|
<style>
|
||||||
|
#_3 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$bridges1 = $bridges2;
|
||||||
|
|
||||||
|
if($bridges1 == $bridges2) {
|
||||||
|
|
||||||
|
|
||||||
|
$output = translateArray(json_decode($bridges1, true), $translationMap);
|
||||||
|
|
||||||
|
|
||||||
|
if($output == "error") {
|
||||||
|
die("Fehler");
|
||||||
|
}
|
||||||
|
|
||||||
|
//$output = [ ["16", "30"], ["30", "16"]];
|
||||||
|
|
||||||
|
$array = $output;
|
||||||
|
|
||||||
|
|
||||||
|
$doubles = []; // Array zur Verfolgung von Doppelungen
|
||||||
|
$errors = []; // Array für fehlende Doppelungen
|
||||||
|
|
||||||
|
// Schritt 1: Prüfung auf Doppelungen
|
||||||
|
foreach ($array as $pair) {
|
||||||
|
|
||||||
|
// Sortiere die Paare, um `[23,14]` und `[14,23]` gleich zu behandeln
|
||||||
|
sort($pair);
|
||||||
|
$key = implode("-", $pair);
|
||||||
|
|
||||||
|
if (isset($doubles[$key])) {
|
||||||
|
$doubles[$key]++; // Verbindung erneut gefunden
|
||||||
|
} else {
|
||||||
|
$doubles[$key] = 1; // Erstmaliges Auftreten
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Schritt 2: Bereinigung der doppelten Einträge
|
||||||
|
$unique = []; // Array für eindeutige Verbindungen
|
||||||
|
$seen = []; // Array zur Verfolgung bereits bearbeiteter Verbindungen
|
||||||
|
|
||||||
|
foreach ($array as $pair) {
|
||||||
|
// Sortiere das Paar
|
||||||
|
sort($pair);
|
||||||
|
$key = implode("-", $pair);
|
||||||
|
|
||||||
|
// Füge nur ein Exemplar hinzu
|
||||||
|
if (!isset($seen[$key])) {
|
||||||
|
$unique[] = $pair;
|
||||||
|
$seen[$key] = true; // Markiere als verarbeitet
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$cleaned_output = json_encode($unique);
|
||||||
|
|
||||||
|
|
||||||
|
$url = '../stecker.php?data=' . urlencode($cleaned_output); // Kodiert es für die URL
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="content-header">Ergebnis</div>
|
||||||
|
<hr />
|
||||||
|
<div class="toggle-switch">
|
||||||
|
<div align="right"><p>Gesamtergebnis</p></div>
|
||||||
|
<div><label class="switch"><input type="checkbox" onchange='$("#op-1").toggle(this.unchecked);$("#op-2").toggle(this.checked);'><span class="slider"></span></label></div>
|
||||||
|
<div align="left"><p>Einzelbrücken</p></div>
|
||||||
|
</div>
|
||||||
|
<div id="op-1">
|
||||||
|
<img src="<?php echo $url; ?>" />
|
||||||
|
</div>
|
||||||
|
<div id="op-2" style="display: none;">
|
||||||
|
<?php
|
||||||
|
|
||||||
|
foreach($unique as $unique_element) {
|
||||||
|
$cleaned_output = "[" . json_encode($unique_element) . "]";
|
||||||
|
$url = 'stecker.php?data=' . urlencode($cleaned_output); // Kodiert es für die URL
|
||||||
|
?>
|
||||||
|
<img style="margin-bottom: 5px;" src="<?php echo $url; ?>" />
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$output = "error";
|
||||||
|
|
||||||
|
/*
|
||||||
|
$url1 = 'stecker.php?data=' . urlencode(translateArray($bridges1, $translationMap)); // Kodiert es für die URL
|
||||||
|
$url2 = 'stecker.php?data=' . urlencode(translateArray($bridges2, $translationMap)); // Kodiert es für die URL
|
||||||
|
*/
|
||||||
|
|
||||||
|
?>
|
||||||
|
<style>
|
||||||
|
#_3 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="check-loading-screen" id="_4">
|
||||||
|
<div>
|
||||||
|
<img src="/vendor/icons/check.svg">Initialisieren
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<img src="/vendor/icons/xmark.svg">Prüfung 1/2
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<img src="/vendor/icons/xmark.svg">Prüfung 2/2
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p>Es gab einen Fehler bei der Messung!</br>Messung 1 und Messung 2 lieferten keine übereinstimmenden Ergebnisse.<br>Bitte prüfen Sie, ob alle Steckverbindungen fest sitzen und vermeiden Sie Bewegungen, welche die Messung beeinträchtigen können.</br>Stellen Sie sicher, dass keine der Verbindungen gegen Erde kurzgeschlossen ist, da dies die Messung beeinträchtigt.<br>Erwägen Sie, eine erneute Messung zurchzuführen.</p>
|
||||||
|
<br>
|
||||||
|
<p>Ergebnis Messung 1:</p>
|
||||||
|
<i><?php echo $bridges1; ?><i>
|
||||||
|
<img src="<?php echo $url1; ?>" />
|
||||||
|
<p>Ergebnis Messung 2:</p>
|
||||||
|
<i><?php echo $bridges2; ?><i>
|
||||||
|
<img src="<?php echo $url2; ?>" />
|
||||||
|
<div class="save-button" onclick="window.location.href='#index'; pageload();$('.save-button').html('<img src=\'load.gif\' \>Bitte warten...');"><img src="/vendor/icons/nav-arrow-left.svg" \>Zurück</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
144
alt/python/plug-check.py
Normal file
144
alt/python/plug-check.py
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
import smbus
|
||||||
|
import time
|
||||||
|
import json
|
||||||
|
|
||||||
|
# Adressen der beiden MCP23017 Chips
|
||||||
|
AusgangRechts = 0x20 # Ausgang rechte Hälfte
|
||||||
|
AusgangLinks = 0x21 # Ausgang linke Hälfte
|
||||||
|
EingangRechts = 0x24 # Eingang rechte Hälfte
|
||||||
|
EingangLinks = 0x23 # Eingang linke Hälfte
|
||||||
|
|
||||||
|
# Register-Adressen für den MCP23017
|
||||||
|
IODIRA = 0x00 # Eingang / Ausgang A
|
||||||
|
IODIRB = 0x01 # Eingang / Ausgang B
|
||||||
|
GPIOA = 0x12 # GPIO A
|
||||||
|
GPIOB = 0x13 # GPIO B
|
||||||
|
|
||||||
|
# Initialisiere den I2C Bus
|
||||||
|
bus = smbus.SMBus(1)
|
||||||
|
|
||||||
|
RechtsA_ausgang = ["Z", "AA", "W", "AB", "AC", "AD", "AE", "AF"]
|
||||||
|
RechtsB_ausgang = ["Q", "U", "V", "T", "S", "R", "Y", "X"]
|
||||||
|
|
||||||
|
RechtsA_eingang = ["R", "T", "V", "X", "Z", "AB", "AD", "AE"]
|
||||||
|
RechtsB_eingang = ["Q", "S", "W", "U", "AA", "Y", "AC", "AF"]
|
||||||
|
|
||||||
|
LinksA_ausgang = ["C", "D", "E", "J", "F", "G", "H", "I"]
|
||||||
|
LinksB_ausgang = ["A", "B", "P", "O", "K", "L", "M", "N"]
|
||||||
|
|
||||||
|
LinksA_eingang = ["B", "D", "F", "H", "J", "K", "M", "I"]
|
||||||
|
LinksB_eingang = ["A", "C", "E", "G", "L", "N", "O", "P"]
|
||||||
|
|
||||||
|
|
||||||
|
array = []
|
||||||
|
|
||||||
|
def default():
|
||||||
|
adressen = [AusgangRechts, AusgangLinks, EingangRechts, EingangLinks]
|
||||||
|
|
||||||
|
# Schleife für alle Registeradressen (0x00 bis 0x15)
|
||||||
|
for register in range(0x00, 0x16):
|
||||||
|
for adresse in adressen:
|
||||||
|
bus.write_byte_data(adresse, register, 0x00)
|
||||||
|
|
||||||
|
# Konfiguriere alle Pins auf Chip 1 als Ausgang (A und B)
|
||||||
|
def configure_chip1_as_output():
|
||||||
|
bus.write_byte_data(AusgangRechts, IODIRA, 0x00) # Setze alle Pins von A als Ausgang
|
||||||
|
bus.write_byte_data(AusgangRechts, IODIRB, 0x00) # Setze alle Pins von B als Ausgang
|
||||||
|
|
||||||
|
bus.write_byte_data(AusgangLinks, IODIRA, 0x00) # Setze alle Pins von A als Ausgang
|
||||||
|
bus.write_byte_data(AusgangLinks, IODIRB, 0x00) # Setze alle Pins von B als Ausgang
|
||||||
|
|
||||||
|
# Konfiguriere alle Pins auf Chip 2 als Eingang (A und B)
|
||||||
|
def configure_chip2_as_input():
|
||||||
|
bus.write_byte_data(EingangRechts, IODIRA, 0xFF) # Setze alle Pins von A als Eingang
|
||||||
|
bus.write_byte_data(EingangRechts, IODIRB, 0xFF) # Setze alle Pins von B als Eingang
|
||||||
|
|
||||||
|
bus.write_byte_data(EingangLinks, IODIRA, 0xFF) # Setze alle Pins von A als Eingang
|
||||||
|
bus.write_byte_data(EingangLinks, IODIRB, 0xFF) # Setze alle Pins von B als Eingang
|
||||||
|
|
||||||
|
|
||||||
|
# Hauptprogramm
|
||||||
|
def main():
|
||||||
|
default()
|
||||||
|
time.sleep(0.5)
|
||||||
|
configure_chip1_as_output()
|
||||||
|
configure_chip2_as_input()
|
||||||
|
|
||||||
|
# Teste alle Pins auf Chip 1 (A0-A7, B0-B7)
|
||||||
|
for pin in range(32): # 0 bis 31
|
||||||
|
#print(f"Setze Pin {pin} auf HIGH auf Chip 1")
|
||||||
|
|
||||||
|
|
||||||
|
bus.write_byte_data(AusgangRechts, GPIOA, 0x00)
|
||||||
|
bus.write_byte_data(AusgangRechts, GPIOB, 0x00)
|
||||||
|
|
||||||
|
bus.write_byte_data(AusgangLinks, GPIOA, 0x00)
|
||||||
|
bus.write_byte_data(AusgangLinks, GPIOB, 0x00)
|
||||||
|
|
||||||
|
|
||||||
|
if pin < 16:
|
||||||
|
# Setze den gewählten Pin auf HIGH
|
||||||
|
if pin < 8: # Pins A0-A7
|
||||||
|
bus.write_byte_data(AusgangRechts, GPIOA, 1 << pin)
|
||||||
|
aktuellAn = RechtsA_ausgang[pin]
|
||||||
|
else: # Pins B0-B7
|
||||||
|
bus.write_byte_data(AusgangRechts, GPIOB, 1 << (pin - 8))
|
||||||
|
aktuellAn = RechtsB_ausgang[pin - 8]
|
||||||
|
else:
|
||||||
|
# Setze den gewählten Pin auf HIGH
|
||||||
|
if pin < 24: # Pins A0-A7
|
||||||
|
bus.write_byte_data(AusgangLinks, GPIOA, 1 << pin - 16)
|
||||||
|
aktuellAn = LinksA_ausgang[pin - 16]
|
||||||
|
else: # Pins B0-B7
|
||||||
|
bus.write_byte_data(AusgangLinks, GPIOB, 1 << (pin - 24))
|
||||||
|
aktuellAn = LinksB_ausgang[pin - 24]
|
||||||
|
|
||||||
|
#print("====================" + aktuellAn + "==========================")
|
||||||
|
|
||||||
|
time.sleep(0.02) # Kurze Pause, damit die Änderung sichtbar wird
|
||||||
|
|
||||||
|
Wert_Rechts_A = bus.read_byte_data(EingangRechts, GPIOA)
|
||||||
|
Wert_Links_A = bus.read_byte_data(EingangLinks, GPIOA)
|
||||||
|
|
||||||
|
Wert_Rechts_B = bus.read_byte_data(EingangRechts, GPIOB)
|
||||||
|
Wert_Links_B = bus.read_byte_data(EingangLinks, GPIOB)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for j in range(8): # Lese 4*8=32 Pins
|
||||||
|
bitmaske = 1 << j # Erstelle eine Maske: 1, 2, 4, 8, 16, ...
|
||||||
|
|
||||||
|
Bit_Rechts_A = bool(Wert_Rechts_A & bitmaske) # Isoliere das entsprechende Bit
|
||||||
|
Bit_Links_A = bool(Wert_Links_A & bitmaske) # Isoliere das entsprechende Bit
|
||||||
|
Bit_Rechts_B = bool(Wert_Rechts_B & bitmaske) # Isoliere das entsprechende Bit
|
||||||
|
Bit_Links_B = bool(Wert_Links_B & bitmaske) # Isoliere das entsprechende Bit
|
||||||
|
|
||||||
|
if Bit_Rechts_A == True:
|
||||||
|
if aktuellAn != RechtsA_eingang[j]:
|
||||||
|
array.append([aktuellAn ,RechtsA_eingang[j]])
|
||||||
|
#print("Gefunden: " + RechtsA_eingang[j])
|
||||||
|
|
||||||
|
if Bit_Links_A == True:
|
||||||
|
if aktuellAn != LinksA_eingang[j]:
|
||||||
|
array.append([aktuellAn ,LinksA_eingang[j]])
|
||||||
|
#print("Gefunden: " + LinksA_eingang[j])
|
||||||
|
|
||||||
|
if Bit_Rechts_B == True:
|
||||||
|
if aktuellAn != RechtsB_eingang[j]:
|
||||||
|
array.append([aktuellAn ,RechtsB_eingang[j]])
|
||||||
|
#print("Gefunden: " + RechtsB_eingang[j])
|
||||||
|
|
||||||
|
if Bit_Links_B == True:
|
||||||
|
if aktuellAn != LinksB_eingang[j]:
|
||||||
|
array.append([aktuellAn ,LinksB_eingang[j]])
|
||||||
|
#print("Gefunden: " + LinksB_eingang[j])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
json_output = json.dumps(array)
|
||||||
|
print(json_output)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
||||||
117
alt/script.js
Normal file
117
alt/script.js
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
function pageload(view, meta) { // Funktion zum Laden des Inhalts
|
||||||
|
|
||||||
|
secondaryNavigation("close"); // Schließe das Stecker-Menü
|
||||||
|
page = window.location.hash.substr(1); // Hole die aufzurufende Seite über den URL-Hash (#xy)
|
||||||
|
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: "pagecontent/" + page + ".php?view=" + view + "&meta=" + meta, // Pfad der zu ladenden Seite aufbauen
|
||||||
|
success: function(result){ // Abfrage erfolgreich
|
||||||
|
$("#content").html(result);
|
||||||
|
$("div.navigation>div").removeClass("active"); // Alle Buttons inaktiv
|
||||||
|
$("#" + page).addClass("active"); // Button mit Klasse "page" wird aktiv geschaltet (im Menü)
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function checkConnection(last) { // Verbindunsstatus überwachen // Last ist der letzte gemessene Netzwerkzustand
|
||||||
|
$.ajax({
|
||||||
|
url: "actions/connection-test.php?a=" + Date.now(), // verändere idr URL leicht, damit der Server nicht cached
|
||||||
|
timeout: 5000, // maximale Wartezeit sind 5 Sekunden; alles darüber wird als zu unzuverlässig angesehen
|
||||||
|
error: function(jqXHR, textStatus, errorThrown) { // Wenn ein Fehler bei der Anfrage auftritt (z.B. Netzwerkprobleme)
|
||||||
|
|
||||||
|
$(".navigation-footer").html('<div class="connection-indicator false"></div>Keine Verbindung<img class="infrago-logo" src="/vendor/DB_InfraGo_logo_red_black_100px_rgb.svg" width="100%" />');
|
||||||
|
console.error("Fehler bei der Anfrage:", textStatus, errorThrown);
|
||||||
|
|
||||||
|
if (last != 1) { // letzter Zustand war "online" // Vermeiden von ständigen Nachrichten
|
||||||
|
message("Keine Verbindung"); // Werfe eine Nachricht
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(function() { // nächste Prüfung in 5 Sekunden
|
||||||
|
checkConnection(1); // der Status offline wird mit übertragen
|
||||||
|
}, 5000);
|
||||||
|
},
|
||||||
|
success: function(data) { // Verbindung iO
|
||||||
|
setTimeout(function() { // nächste Prüfung in 5 Sekunden
|
||||||
|
checkConnection();
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
|
if (data == 'true') { // der Rückgabewert ist true, alles IO
|
||||||
|
$(".navigation-footer").html('<div class="connection-indicator true"></div>Verbunden<img class="infrago-logo" src="/vendor/DB_InfraGo_logo_red_black_100px_rgb.svg" width="100%" />');
|
||||||
|
if (last == 1) { // war der letzte Status noch "offline", wird der Nutzer benachrichtigt
|
||||||
|
message("Verbindung wiederhergestellt!");
|
||||||
|
}
|
||||||
|
} else { // außergewöhnlicher Fehler, aber möglich
|
||||||
|
message("Keine Verbindung"); // Verbindung dennoch unbrauchbar, wenn keine Daten geladen werden
|
||||||
|
$(".navigation-footer").html('<div class="connection-indicator false"></div>Keine Verbindung<img class="infrago-logo" src="/vendor/DB_InfraGo_logo_red_black_100px_rgb.svg" width="100%" />');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function secondaryNavigation(animation, content) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (animation == "open") {
|
||||||
|
|
||||||
|
|
||||||
|
$.get("pagecontent/plug-select.php", {
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
function(data, status) {
|
||||||
|
if (status == "success") {
|
||||||
|
if (data != 'false') {
|
||||||
|
$("#navigation-secondary").css("left", "250px");
|
||||||
|
$(".navigation-header").attr("onclick", "secondaryNavigation('close','plug-select')");
|
||||||
|
setTimeout(function() {
|
||||||
|
$("#navigation-secondary").html(data);
|
||||||
|
console.log(data);
|
||||||
|
}, 200);
|
||||||
|
} else {
|
||||||
|
window.location.href = "#";
|
||||||
|
|
||||||
|
alert("Die Inhalte konnten nicht abgerufen werden. Vergewissern Sie sich, dass Sie mit dem WLAN-Netzwerk verbunden sind und laden Sie bei Bedarf die Seite neu.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$("#navigation-secondary").css("left", "-250px");
|
||||||
|
$(".navigation-header").attr("onclick", "secondaryNavigation('open','plug-select')");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function message(content) {
|
||||||
|
$("#message-box").html(content);
|
||||||
|
$("#message-box").css("display", "block");
|
||||||
|
setTimeout(function() {
|
||||||
|
$("#message-box").css("transform", "translateY(0)");
|
||||||
|
}, 50);
|
||||||
|
setTimeout(function() {
|
||||||
|
setTimeout(function() {
|
||||||
|
$("#message-box").css("display", "none");
|
||||||
|
}, 500);
|
||||||
|
$("#message-box").css("transform", "translateY(calc(100% + 5px))");
|
||||||
|
}, 3000);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$(window).bind('beforeunload', function() {
|
||||||
|
$("#warning").css("display", "block");
|
||||||
|
return 'Are you sure you want to leave?';
|
||||||
|
|
||||||
|
});
|
||||||
120
alt/stecker.php
Normal file
120
alt/stecker.php
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
<?php
|
||||||
|
// Setze den Content-Type-Header für SVG
|
||||||
|
header('Content-Type: image/svg+xml');
|
||||||
|
echo '<?xml version="1.0" encoding="UTF-8"?>';
|
||||||
|
?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="500" height="100">
|
||||||
|
|
||||||
|
<defs>
|
||||||
|
<style>
|
||||||
|
@font-face {
|
||||||
|
font-family: LexendDecaBold;
|
||||||
|
src: url(http://192.168.37.103/vendor/fonts/LexendDeca-Bold.ttf);
|
||||||
|
}
|
||||||
|
* {
|
||||||
|
font-family: LexendDecaBold;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<text x="30" y="5" fill="black" text-anchor="middle" transform="translate(50,50) rotate(-90)">30</text>
|
||||||
|
|
||||||
|
<text x="-30" y="5" fill="black" text-anchor="middle" transform="translate(50,50) rotate(-90)">10</text>
|
||||||
|
|
||||||
|
<text x="30" y="405" fill="black" text-anchor="middle" transform="translate(50,50) rotate(-90)">31</text>
|
||||||
|
|
||||||
|
<text x="-30" y="405" fill="black" text-anchor="middle" transform="translate(50,50) rotate(-90)">11</text>
|
||||||
|
|
||||||
|
<path d="M500 0 L50 0" style="stroke:black;stroke-width:5; fill:none;" />
|
||||||
|
<path d="M50 0 L0 25" style="stroke:black;stroke-width:3; fill:none;" />
|
||||||
|
<path d="M0 25 L0 75" style="stroke:black;stroke-width:5; fill:none;" />
|
||||||
|
<path d="M0 75 L50 100" style="stroke:black;stroke-width:3; fill:none;" />
|
||||||
|
<path d="M50 100 L500 100" style="stroke:black;stroke-width:5; fill:none;" />
|
||||||
|
<path d="M500 100 L500 0" style="stroke:black;stroke-width:5; fill:none;" />
|
||||||
|
|
||||||
|
<rect width="35" height="35" x="452" y="32" rx="5" ry="5" style="stroke:black;stroke-width:3;fill:none" />
|
||||||
|
<circle r="8" cx="470" cy="50" fill="none" style="stroke:black;stroke-width:3;" />
|
||||||
|
|
||||||
|
<rect width="35" height="35" x="13" y="32" rx="5" ry="5" style="stroke:black;stroke-width:3;fill:none" />
|
||||||
|
<circle r="8" cx="30" cy="50" fill="none" style="stroke:black;stroke-width:3;" />
|
||||||
|
|
||||||
|
|
||||||
|
<rect width="380" height="80" x="60" y="10" rx="5" ry="5" style="stroke:black;stroke-width:3;fill:none" />
|
||||||
|
|
||||||
|
<?php
|
||||||
|
$pin_coordinates = [
|
||||||
|
10 => [70, 68],
|
||||||
|
20 => [70, 44],
|
||||||
|
30 => [70, 20],
|
||||||
|
11 => [405, 68],
|
||||||
|
12 => [370, 68],
|
||||||
|
13 => [335, 68],
|
||||||
|
14 => [300, 68],
|
||||||
|
15 => [265, 68],
|
||||||
|
16 => [230, 68],
|
||||||
|
17 => [195, 68],
|
||||||
|
18 => [160, 68],
|
||||||
|
19 => [125, 68],
|
||||||
|
21 => [405, 44],
|
||||||
|
22 => [370, 44],
|
||||||
|
23 => [335, 44],
|
||||||
|
24 => [300, 44],
|
||||||
|
25 => [265, 44],
|
||||||
|
26 => [220, 44],
|
||||||
|
27 => [185, 44],
|
||||||
|
28 => [150, 44],
|
||||||
|
29 => [115, 44],
|
||||||
|
31 => [405, 20],
|
||||||
|
32 => [370, 20],
|
||||||
|
33 => [335, 20],
|
||||||
|
34 => [300, 20],
|
||||||
|
35 => [265, 20],
|
||||||
|
36 => [230, 20],
|
||||||
|
37 => [195, 20],
|
||||||
|
38 => [160, 20],
|
||||||
|
39 => [125, 20],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($pin_coordinates as $coordinates) {
|
||||||
|
echo '<rect width="25" height="10" x="' . $coordinates[0] . '" y="' . $coordinates[1] . '" rx="1" ry="1" style="stroke:black;stroke-width:3;fill:none" />';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($_GET['data'])) {
|
||||||
|
print "</svg>";
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
$inputArray = json_decode($_GET['data'], true); // JSON in ein PHP-Array umwandeln
|
||||||
|
|
||||||
|
// Neues Array mit übersetzten Koordinaten
|
||||||
|
$translatedArray = array_map(function ($pair) use ($pin_coordinates) {
|
||||||
|
return [
|
||||||
|
$pin_coordinates[$pair[0]], // Übersetze den ersten Wert
|
||||||
|
$pin_coordinates[$pair[1]], // Übersetze den zweiten Wert
|
||||||
|
];
|
||||||
|
}, $inputArray);
|
||||||
|
|
||||||
|
$colors = ["#1a5fb4", "#26a269", "#e5a50a", "#c64600", "#a51d2d", "#613583", "#63452c", "#3d3846"];
|
||||||
|
|
||||||
|
// Schleife durch das übersetzte Array
|
||||||
|
$colorNumber = 0;
|
||||||
|
foreach ($translatedArray as $line) {
|
||||||
|
$point1 = $line[0]; // Erster Punkt [x, y]
|
||||||
|
$point2 = $line[1]; // Zweiter Punkt [x, y]
|
||||||
|
|
||||||
|
$point1x = $point1[0] + 10;
|
||||||
|
$point1y = $point1[1] + 5;
|
||||||
|
$point2x = $point2[0] + 10;
|
||||||
|
$point2y = $point2[1] + 5;
|
||||||
|
|
||||||
|
// Ausgabe eines Pfades (Linie zwischen zwei Punkten)
|
||||||
|
echo '<path d="M' . $point1x . " " . $point1y . " L" . $point2x . " " . $point2y . '" style="stroke:' . $colors[$colorNumber] . ';stroke-width:3; fill:none;" />';
|
||||||
|
|
||||||
|
$colorNumber++;
|
||||||
|
if ($colorNumber > 7) {
|
||||||
|
$colorNumber = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</svg>
|
||||||
241
alt/style.css
Normal file
241
alt/style.css
Normal file
@@ -0,0 +1,241 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: LexendDecaBold;
|
||||||
|
src: url(/vendor/fonts/LexendDeca-Bold.ttf);
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: LexendDecaMedium;
|
||||||
|
src: url(/vendor/fonts/LexendDeca-Medium.ttf);
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
padding: 20px;
|
||||||
|
margin: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-family: LexendDecaBold;
|
||||||
|
font-weight: light;
|
||||||
|
color: #2e3436;
|
||||||
|
}
|
||||||
|
div.main {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 900px;
|
||||||
|
height: auto;
|
||||||
|
border-radius: 15px;
|
||||||
|
overflow: hidden;
|
||||||
|
margin: 0 auto;
|
||||||
|
border: 5px solid #c3c3c3;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
div.navigation {
|
||||||
|
width: 250px;
|
||||||
|
height: 600px;
|
||||||
|
background-color: #ebebeb;
|
||||||
|
float: left;
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
z-index: 501;
|
||||||
|
}
|
||||||
|
div.navigation.secondary {
|
||||||
|
position: absolute;
|
||||||
|
left: -250px;
|
||||||
|
top: 0;
|
||||||
|
overflow-y: auto;
|
||||||
|
z-index: 500;
|
||||||
|
transition-duration: .6s;
|
||||||
|
width: 500px;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
background-color: #ebebeb8c;
|
||||||
|
|
||||||
|
}
|
||||||
|
div.navigation.secondary img {
|
||||||
|
width: 100px !important;
|
||||||
|
}
|
||||||
|
div.navigation>div, div.save-button {
|
||||||
|
padding: 5px;
|
||||||
|
margin: 10px;
|
||||||
|
line-height: 30px;
|
||||||
|
transition-duration: .4s;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
div.navigation>div:hover,div.navigation>div.active,div.navigation-footer,div.navigation-header,div.save-button:hover {
|
||||||
|
background-color: #d2d2d2;
|
||||||
|
}
|
||||||
|
div.navigation div.navigation-header {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
div.navigation div.navigation-header>div {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 0 0 7px 7px;
|
||||||
|
color: grey;
|
||||||
|
line-height: 20px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
div.navigation>div>img:not(.infrago-logo),div.content div.save-button>img {
|
||||||
|
width: 30px;
|
||||||
|
max-height: 30px;
|
||||||
|
margin-right:20px;
|
||||||
|
vertical-align:middle;
|
||||||
|
filter: contrast(0.3);
|
||||||
|
}
|
||||||
|
div.navigation>div>img.infrago-logo {
|
||||||
|
width: 100%;
|
||||||
|
display:block;
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
div.content {
|
||||||
|
width: calc(100% - 250px);
|
||||||
|
float: right;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 15px 20px;
|
||||||
|
height: 600px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow-y: auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.content div.content-header {
|
||||||
|
text-align: center;
|
||||||
|
line-height: 30px;
|
||||||
|
padding: 0;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
display: block;
|
||||||
|
font-size: 2em;
|
||||||
|
margin-block-start: 0.67em;
|
||||||
|
margin-block-end: 0.67em;
|
||||||
|
margin-inline-start: 0px;
|
||||||
|
margin-inline-end: 0px;
|
||||||
|
font-weight: bold;
|
||||||
|
unicode-bidi: isolate;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.content img {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
div.navigation-footer {
|
||||||
|
position: absolute;
|
||||||
|
bottom:0;
|
||||||
|
width: calc(100% - 40px);
|
||||||
|
padding: 10px !important;
|
||||||
|
cursor: auto !important;
|
||||||
|
}
|
||||||
|
div.connection-indicator {
|
||||||
|
height: 15px;
|
||||||
|
width: 15px;
|
||||||
|
border-radius: 100%;
|
||||||
|
float: left;
|
||||||
|
vertical-align:middle;
|
||||||
|
margin: 7.5px;
|
||||||
|
}
|
||||||
|
div.connection-indicator.true {
|
||||||
|
background-color: #2ec27e;
|
||||||
|
}
|
||||||
|
div.connection-indicator.unknown {
|
||||||
|
background-color: #f6d32d;
|
||||||
|
}
|
||||||
|
div.connection-indicator.false {
|
||||||
|
background-color: #ed333b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
div.save-button img {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
div.save-button {
|
||||||
|
background-color: #ebebeb
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Track */
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: #ebebeb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle */
|
||||||
|
::-webkit-scrollbar-thumb, ::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: #d2d2d2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
div.toggle-switch {
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
div.toggle-switch div {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
div.toggle-switch div:nth-child(1), div.toggle-switch div:nth-child(3) {
|
||||||
|
width: 39%;
|
||||||
|
}
|
||||||
|
div.toggle-switch div:nth-child(2) {
|
||||||
|
width: 20%;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.switch {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
height: 34px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch input {
|
||||||
|
opacity: 0;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider {
|
||||||
|
position: absolute;
|
||||||
|
cursor: pointer;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: #ccc;
|
||||||
|
-webkit-transition: .4s;
|
||||||
|
transition: .4s;
|
||||||
|
border-radius: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider:before {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
height: 26px;
|
||||||
|
width: 26px;
|
||||||
|
left: 4px;
|
||||||
|
bottom: 4px;
|
||||||
|
background-color: white;
|
||||||
|
-webkit-transition: .4s;
|
||||||
|
transition: .4s;
|
||||||
|
border-radius: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rounded sliders */
|
||||||
|
.slider.round {
|
||||||
|
border-radius: 34px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider.round:before {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.simple-devider th,table.simple-devider td {
|
||||||
|
padding: 15px;
|
||||||
|
|
||||||
|
}
|
||||||
|
table.simple-devider * {
|
||||||
|
margin: 0;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
77
alt/vendor/DB_InfraGo_logo_red_black_100px_rgb.svg
vendored
Normal file
77
alt/vendor/DB_InfraGo_logo_red_black_100px_rgb.svg
vendored
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?><svg id="DB_InfraGO_logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 316.5 70"><desc>Das ist das Firmenlogo der gemeinwohlorientierten Infrastrukturgesellschaft DB InfraGO AG.</desc>
|
||||||
|
<metadata><?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
|
||||||
|
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 9.1-c001 79.a8d4753, 2023/03/23-08:56:37 ">
|
||||||
|
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||||
|
<rdf:Description rdf:about=""
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/"
|
||||||
|
xmlns:xmp="http://ns.adobe.com/xap/1.0/"
|
||||||
|
xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
|
||||||
|
xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
|
||||||
|
xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/">
|
||||||
|
<dc:creator>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li>Deutsche Bahn</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</dc:creator>
|
||||||
|
<dc:description>
|
||||||
|
<rdf:Alt>
|
||||||
|
<rdf:li xml:lang="x-default">Das ist das Firmenlogo der gemeinwohlorientierten Infrastrukturgesellschaft DB InfraGO AG.</rdf:li>
|
||||||
|
</rdf:Alt>
|
||||||
|
</dc:description>
|
||||||
|
<Iptc4xmpCore:AltTextAccessibility>
|
||||||
|
<rdf:Alt>
|
||||||
|
<rdf:li xml:lang="x-default">Das ist das Firmenlogo der gemeinwohlorientierten Infrastrukturgesellschaft DB InfraGO AG.</rdf:li>
|
||||||
|
</rdf:Alt>
|
||||||
|
</Iptc4xmpCore:AltTextAccessibility>
|
||||||
|
<Iptc4xmpCore:ExtDescrAccessibility>
|
||||||
|
<rdf:Alt>
|
||||||
|
<rdf:li xml:lang="x-default">Das ist das Firmenlogo der gemeinwohlorientierten Infrastrukturgesellschaft DB InfraGO AG.</rdf:li>
|
||||||
|
</rdf:Alt>
|
||||||
|
</Iptc4xmpCore:ExtDescrAccessibility>
|
||||||
|
<xmp:MetadataDate>2023-12-20T16:18:38+01:00</xmp:MetadataDate>
|
||||||
|
<xmpMM:InstanceID>xmp.iid:f4896118-a5fc-4ec6-884b-265e34b1ca9a</xmpMM:InstanceID>
|
||||||
|
<xmpMM:DocumentID>xmp.did:8feca862-1f36-49d9-a283-4022945ab9e2</xmpMM:DocumentID>
|
||||||
|
<xmpMM:OriginalDocumentID>xmp.did:8feca862-1f36-49d9-a283-4022945ab9e2</xmpMM:OriginalDocumentID>
|
||||||
|
<xmpMM:History>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li>
|
||||||
|
<rdf:Description>
|
||||||
|
<stEvt:action>saved</stEvt:action>
|
||||||
|
<stEvt:instanceID>xmp.iid:8feca862-1f36-49d9-a283-4022945ab9e2</stEvt:instanceID>
|
||||||
|
<stEvt:when>2023-12-20T16:13:32+01:00</stEvt:when>
|
||||||
|
<stEvt:softwareAgent>Adobe Bridge 2024</stEvt:softwareAgent>
|
||||||
|
<stEvt:changed>/metadata</stEvt:changed>
|
||||||
|
</rdf:Description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li>
|
||||||
|
<rdf:Description>
|
||||||
|
<stEvt:action>saved</stEvt:action>
|
||||||
|
<stEvt:instanceID>xmp.iid:f4896118-a5fc-4ec6-884b-265e34b1ca9a</stEvt:instanceID>
|
||||||
|
<stEvt:when>2023-12-20T16:18:38+01:00</stEvt:when>
|
||||||
|
<stEvt:softwareAgent>Adobe Bridge 2024</stEvt:softwareAgent>
|
||||||
|
<stEvt:changed>/metadata</stEvt:changed>
|
||||||
|
</rdf:Description>
|
||||||
|
</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</xmpMM:History>
|
||||||
|
<photoshop:CaptionWriter>Deutsche Bahn</photoshop:CaptionWriter>
|
||||||
|
</rdf:Description>
|
||||||
|
</rdf:RDF>
|
||||||
|
</x:xmpmeta>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<?xpacket end="w"?></metadata>
|
||||||
|
<g id="DB_Logo"><path d="M90,0H10C4.6,0,0,4.3,0,10v50c0,5.5,4.6,10,10,10h80c5.5,0,10-4.5,10-10.1V10c0-5.7-4.6-10-10-10ZM92.7,59.9c0,1.6-1.2,2.9-2.7,2.9H10c-1.6,0-2.7-1.3-2.7-2.9V10c0-1.6,1.2-2.9,2.7-2.9h80c1.6,0,2.7,1.3,2.7,2.9v49.9Z" style="fill:#ec0016; stroke-width:0px;"/><path d="M30.6,57.9H13.8V12.1h16.8c11.9,0,18.4,7.4,18.4,22.7,0,13.2-4.5,23-18.4,23.1ZM37.9,35.7c0-9.2-1-16.4-10.9-16.4h-2.2v31.2h3.9c5.8,0,9.2-4.7,9.2-14.8Z" style="fill:#ec0016; stroke-width:0px;"/><path d="M78,33.9c3.2-.9,8-4.6,8-10.7,0-1-.2-11.2-13.1-11.2h-19.1v45.8h16.2c4.3,0,17.7,0,17.7-12.9,0-3.1-1.4-9.1-9.7-11ZM64.7,19.2h3.5c4.9,0,6.9,1.7,6.9,5.5,0,3-2.2,5.5-6,5.5h-4.4v-11ZM69.2,50.5h-4.5v-11.8h4.8c5.7,0,7.1,3.3,7.1,5.9,0,5.9-5.6,5.9-7.4,5.9Z" style="fill:#ec0016; stroke-width:0px;"/></g><g id="InfraGo"><path d="M125,19.1h10v38.9h-10V19.1Z" style="stroke-width:0px;"/><path d="M148.3,28.5h2.2v5.2c3.1-3.5,6.2-5.1,9.9-5.1,4.9,0,7.7,3.3,7.7,9v20.3h-9.3v-18.2c0-2.4-1.1-3.5-3.4-3.5-1.6,0-2.8.4-4.9,1.5v20.2h-9.3v-27.6c3.7-.1,6-.7,7.1-1.8Z" style="stroke-width:0px;"/><path d="M175,37.2h-3.6v-6.6h3.6v-2c0-6.3,3.8-10.2,11.3-10.2,1.9,0,3.3.2,4.6.3v6.4c-.7-.1-1.3-.2-2-.2-3.2,0-4.5,1.2-4.5,4v1.7h4.8v6.6h-4.8v20.7h-9.4v-20.7Z" style="stroke-width:0px;"/><path d="M199.3,28.6h2.2v5.7c2.4-3.8,4.9-5.6,7.6-5.6.3,0,.5.1.7.1v8.3l-.6.1c-2.5.2-5.3.8-7.7,1.9v18.9h-9.3v-27.6c3.6-.1,5.9-.7,7.1-1.8Z" style="stroke-width:0px;"/><path d="M226.7,54.2c-2.1,3-4.9,4.5-8.4,4.5-5.3,0-8.4-3-8.4-8.6,0-8.1,7-8.6,16.3-9v-1.5c0-3-1.4-4.1-4.2-4.1s-5.9.5-9.8,1.2v-7.2c4.1-.9,7.2-1.3,10.8-1.3,8.9,0,12.5,3.3,12.5,11.2v11.7c0,3.2.3,4.3,1.2,5v1.6h-9l-1-3.5ZM222.1,52.6c1.5,0,2.9-.5,4.2-1.6v-5.7c-5.3.2-7.2.5-7.2,4-.1,2.3.8,3.3,3,3.3Z" style="stroke-width:0px;"/><path d="M240.1,39v-.2c0-13.6,7.2-20.3,20.4-20.3,4.3,0,7.6.5,11.6,1.7v7.9c-3.9-1.3-7.3-1.9-11.1-1.9-7.9,0-10,4-10,12.6v.3c0,8.8,2.4,12.2,9.4,12.2,1.6,0,2.7-.2,4.2-.6v-6.5h-6.2v-7.4h15.6v19c-4.8,1.8-9,2.8-13.9,2.8-13.6,0-20-5-20-19.6Z" style="stroke-width:0px;"/><path d="M278.7,38.6v-.2c0-12.5,7.1-20,18.9-20,11.9,0,18.9,7.6,18.9,20.1v.2c0,12.5-7,19.9-18.9,19.9-12,0-18.9-7.5-18.9-20ZM305.6,38.7v-.3c0-9-2.4-12.7-8-12.7-5.7,0-8,3.7-8,12.8v.3c0,8.8,2.4,12.4,8,12.4,5.7,0,8-3.6,8-12.5Z" style="stroke-width:0px;"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 6.9 KiB |
BIN
alt/vendor/fonts/LexendDeca-Bold.ttf
vendored
Normal file
BIN
alt/vendor/fonts/LexendDeca-Bold.ttf
vendored
Normal file
Binary file not shown.
BIN
alt/vendor/fonts/LexendDeca-Medium.ttf
vendored
Normal file
BIN
alt/vendor/fonts/LexendDeca-Medium.ttf
vendored
Normal file
Binary file not shown.
1
alt/vendor/icons/electric-plug-icon.svg
vendored
Normal file
1
alt/vendor/icons/electric-plug-icon.svg
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 99.15 123.38" style="enable-background:new 0 0 99.15 123.38" xml:space="preserve"><style type="text/css">.st0{fill-rule:evenodd;clip-rule:evenodd;stroke:#000000;stroke-width:0.5;stroke-miterlimit:2.6131;}</style><g><path class="st0" d="M5.44,40.34h15.84V8.47c0-4.52,3.7-8.22,8.22-8.22l0,0c4.52,0,8.22,3.7,8.22,8.22v31.87h24.13V8.47 c0-4.52,3.7-8.22,8.22-8.22l0,0c4.52,0,8.22,3.7,8.22,8.22v31.87h15.42c2.86,0,5.19,2.34,5.19,5.19v6.02 c0,2.86-2.34,5.19-5.19,5.19l-88.27,0c-2.86,0-5.19-2.34-5.19-5.19v-6.02C0.25,42.67,2.59,40.34,5.44,40.34L5.44,40.34z M9.52,56.84l0,12.58c-0.01,22.06,9.79,32.85,32.27,35.56v18.15h16.44v-18.35c22.25-2.14,32.27-15.22,32.27-36.59V56.84H9.52 L9.52,56.84z M28.11,61.42H71.9v6.51H28.11V61.42L28.11,61.42z"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 919 B |
1
alt/vendor/icons/fiber-cable-icon.svg
vendored
Normal file
1
alt/vendor/icons/fiber-cable-icon.svg
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 85.74 122.88" style="enable-background:new 0 0 85.74 122.88" xml:space="preserve"><style type="text/css">.st0{fill-rule:evenodd;clip-rule:evenodd;}</style><g><path class="st0" d="M78.27,38.12c3.55-0.53,6.86,1.91,7.4,5.46c0.53,3.55-1.91,6.86-5.46,7.39c-2.5,0.38-4.89-0.73-6.26-2.66 c-3.57,0.93-6.69,2.33-9.49,4.22c-2.45,1.65-4.67,3.69-6.77,6.13c0.49,0.44,0.97,0.92,1.42,1.43c-0.01,0.55-0.42,1.34-0.8,1.79 c-10.22,12.67-19.42,32.79-22.49,54.84c-0.28,2.04-0.51,4.09-0.69,6.15h-5.2c0.19-2.3,0.44-4.58,0.76-6.85 c3-21.46,11.58-41.2,21.41-54.56l-0.14-0.1c-0.43-0.33-0.74-0.75-0.92-1.22l-4.97-2.97c-0.27-0.09-0.54-0.23-0.78-0.4 c-0.1-0.07-0.19-0.15-0.27-0.23l-13.19-7.89C18.9,63.78,11.24,82.96,7.6,102.58c-1.26,6.77-2.05,13.58-2.41,20.3H0 c0.37-7.03,1.18-14.16,2.5-21.24C6.43,80.5,14.85,59.81,29.27,43.69c0.81-0.99,2.23-1.27,3.35-0.6l0.35,0.21 c1.31-2.91,2.24-5.92,2.85-9c0.58-2.95,0.87-5.96,0.89-9.02c-2.35-0.79-4.18-2.83-4.58-5.45c-0.56-3.72,2-7.2,5.73-7.76 c3.72-0.56,7.2,2,7.76,5.73c0.42,2.81-0.94,5.48-3.23,6.86c0.02,3.67-0.29,7.25-0.98,10.73c-0.73,3.71-1.89,7.33-3.54,10.86 l1.64,0.99c3.86-4.82,7.05-10.17,9.59-16c2.5-5.73,4.39-11.93,5.71-18.58c-1.67-1.01-2.9-2.73-3.21-4.82 c-0.56-3.72,2-7.2,5.73-7.76c3.72-0.56,7.2,2,7.76,5.73c0.5,3.34-1.51,6.48-4.62,7.5c-1.41,7.23-3.44,13.98-6.16,20.2 c-2.65,6.07-5.93,11.65-9.88,16.69l0.87,0.52l0.62,0.37c3.14-4.22,6.38-8.37,9.69-12.45c3.6-4.42,7.29-8.77,11.06-13.05 c-0.05-0.22-0.1-0.43-0.13-0.66c-0.55-3.66,1.97-7.08,5.63-7.63c3.66-0.55,7.08,1.97,7.63,5.63c0.55,3.66-1.97,7.08-5.63,7.63 c-1.35,0.2-2.67-0.01-3.82-0.55c-3.48,3.96-6.92,8.03-10.32,12.21c-3.11,3.82-6.17,7.75-9.18,11.78l1.21,0.72l1,0.6 c2.52-2.99,5.21-5.49,8.22-7.51c3.46-2.33,7.31-4.03,11.75-5.13C73.71,40.35,75.7,38.5,78.27,38.12L78.27,38.12z M19.21,122.88 c0.13-1.7,0.29-3.39,0.48-5.07c2.53-21.67,10.92-41.79,20.71-55.55c0.52-0.72,1.53-0.9,2.27-0.38c0.72,0.52,0.9,1.53,0.38,2.27 c-9.51,13.37-17.65,32.94-20.12,54.03c-0.18,1.56-0.33,3.12-0.45,4.69H19.21L19.21,122.88z M78.86,42 c1.41-0.21,2.72,0.76,2.93,2.17c0.21,1.41-0.76,2.72-2.17,2.93c-1.41,0.21-2.72-0.76-2.93-2.17C76.48,43.52,77.45,42.21,78.86,42 L78.86,42z M57.97,4.27c1.41-0.21,2.72,0.76,2.93,2.17c0.21,1.41-0.76,2.72-2.17,2.93c-1.41,0.21-2.72-0.76-2.93-2.17 C55.59,5.8,56.56,4.48,57.97,4.27L57.97,4.27z M38.5,16.26c1.41-0.21,2.72,0.76,2.93,2.17c0.21,1.41-0.76,2.72-2.17,2.93 c-1.41,0.21-2.72-0.76-2.93-2.17C36.12,17.79,37.09,16.48,38.5,16.26L38.5,16.26z M72.79,21.38c1.41-0.21,2.72,0.76,2.93,2.17 c0.21,1.41-0.76,2.72-2.17,2.93c-1.41,0.21-2.72-0.76-2.93-2.17C70.41,22.9,71.38,21.59,72.79,21.38L72.79,21.38z"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 2.7 KiB |
1
alt/vendor/icons/play.svg
vendored
Normal file
1
alt/vendor/icons/play.svg
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?><svg width="24px" height="24px" stroke-width="1.5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" color="#000000"><path d="M6.90588 4.53682C6.50592 4.2998 6 4.58808 6 5.05299V18.947C6 19.4119 6.50592 19.7002 6.90588 19.4632L18.629 12.5162C19.0211 12.2838 19.0211 11.7162 18.629 11.4838L6.90588 4.53682Z" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg>
|
||||||
|
After Width: | Height: | Size: 458 B |
2
alt/vendor/jquery.min.js
vendored
Normal file
2
alt/vendor/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
75
db-test/defaults.php
Normal file
75
db-test/defaults.php
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$data = '10.97.109.112 - - [04/Aug/2025:08:46:17 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B18%2C28%5D%5D%2C%22name%22%3A%2232%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:46:45 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B28%2C38%5D%5D%2C%22name%22%3A%2233%22%7D HTTP/1.1" 200 367 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:47:03 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B39%2C28%5D%5D%2C%22name%22%3A%2234%22%7D HTTP/1.1" 200 367 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:47:22 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B19%2C28%5D%5D%2C%22name%22%3A%2235%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:47:49 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B22%2C29%5D%5D%2C%22name%22%3A%2236%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:48:15 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B13%2C14%5D%5D%2C%22name%22%3A%2237%22%7D HTTP/1.1" 200 367 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:48:31 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B10%2C20%5D%5D%2C%22name%22%3A%2238%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:48:42 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B30%2C20%5D%5D%2C%22name%22%3A%2239%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:49:37 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B30%2C39%5D%5D%2C%22name%22%3A%2290%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:51:15 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B20%2C29%5D%2C%5B39%2C19%5D%5D%2C%22name%22%3A%2293%22%7D HTTP/1.1" 200 367 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:51:50 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B30%2C20%5D%2C%5B35%2C36%5D%5D%2C%22name%22%3A%2245%22%7D HTTP/1.1" 200 367 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:52:22 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B15%2C16%5D%2C%5B20%2C10%5D%5D%2C%22name%22%3A%2255%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:52:52 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B18%2C27%5D%5D%2C%22name%22%3A%2241%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:53:06 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B31%2C32%5D%5D%2C%22name%22%3A%2242%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:53:20 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B32%2C33%5D%5D%2C%22name%22%3A%2243%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:54:00 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B28%2C18%5D%5D%2C%22name%22%3A%2240%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:54:38 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B37%2C36%5D%5D%2C%22name%22%3A%2244%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:55:14 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B34%2C24%5D%5D%2C%22name%22%3A%2246%22%7D HTTP/1.1" 200 367 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:55:33 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B34%2C25%5D%5D%2C%22name%22%3A%2247%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:55:47 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B34%2C23%5D%5D%2C%22name%22%3A%2248%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:56:23 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B22%2C34%5D%5D%2C%22name%22%3A%2249%22%7D HTTP/1.1" 200 367 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:56:38 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B38%2C28%5D%5D%2C%22name%22%3A%2250%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:56:54 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B38%2C27%5D%5D%2C%22name%22%3A%2251%22%7D HTTP/1.1" 200 367 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:57:29 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B11%2C12%5D%5D%2C%22name%22%3A%2252%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:57:48 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B13%2C14%5D%5D%2C%22name%22%3A%2253%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:58:25 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B17%2C16%5D%5D%2C%22name%22%3A%2254%22%7D HTTP/1.1" 200 367 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:59:07 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B24%2C14%5D%5D%2C%22name%22%3A%2256%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:59:34 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B14%2C25%5D%5D%2C%22name%22%3A%2257%22%7D HTTP/1.1" 200 367 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:08:59:56 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B15%2C24%5D%5D%2C%22name%22%3A%2258%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:00:30 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B22%2C14%5D%5D%2C%22name%22%3A%2259%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:01:34 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B21%2C26%5D%5D%2C%22name%22%3A%2294%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:01:56 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B35%2C16%5D%5D%2C%22name%22%3A%2295%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:07:39 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B30%2C20%5D%2C%5B35%2C36%5D%5D%2C%22name%22%3A%2268%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:08:12 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B37%2C26%5D%2C%5B25%2C34%5D%5D%2C%22name%22%3A%2271%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:08:41 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B25%2C14%5D%2C%5B26%2C17%5D%5D%2C%22name%22%3A%2273%22%7D HTTP/1.1" 200 367 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:08:56 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B38%2C28%5D%5D%2C%22name%22%3A%2260%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:09:08 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B28%2C18%5D%5D%2C%22name%22%3A%2261%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:09:31 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B33%2C23%5D%5D%2C%22name%22%3A%2262%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:09:57 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B32%2C33%5D%5D%2C%22name%22%3A%2263%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:10:12 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B13%2C23%5D%5D%2C%22name%22%3A%2264%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:10:46 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B12%2C13%5D%5D%2C%22name%22%3A%2265%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:11:05 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B29%2C19%5D%5D%2C%22name%22%3A%2266%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:11:17 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B29%2C10%5D%5D%2C%22name%22%3A%2267%22%7D HTTP/1.1" 200 367 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:11:37 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B20%2C23%5D%5D%2C%22name%22%3A%2269%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:11:56 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B34%2C24%5D%5D%2C%22name%22%3A%2270%22%7D HTTP/1.1" 200 367 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:12:31 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B24%2C14%5D%5D%2C%22name%22%3A%2272%22%7D HTTP/1.1" 200 367 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:12:48 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B37%2C27%5D%5D%2C%22name%22%3A%2274%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:13:04 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B17%2C27%5D%5D%2C%22name%22%3A%2275%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:13:24 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B21%2C22%5D%5D%2C%22name%22%3A%2276%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:13:35 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B21%2C11%5D%5D%2C%22name%22%3A%2277%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:13:53 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B11%2C22%5D%5D%2C%22name%22%3A%2278%22%7D HTTP/1.1" 200 367 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:14:02 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B31%2C21%5D%5D%2C%22name%22%3A%2279%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:14:12 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B31%2C22%5D%5D%2C%22name%22%3A%2280%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:14:32 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B15%2C16%5D%5D%2C%22name%22%3A%2281%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:14:43 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B39%2C38%5D%5D%2C%22name%22%3A%2282%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
||||||
|
10.97.109.112 - - [04/Aug/2025:09:15:22 +0200] "GET /actions/bridge-editor.php?action=add&meta=%7B%22pins%22%3A%5B%5B39%2C18%5D%5D%2C%22name%22%3A%2283%22%7D HTTP/1.1" 200 366 "http://10.97.109.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"';
|
||||||
|
|
||||||
|
// Alle passenden URLs extrahieren
|
||||||
|
preg_match_all('/GET (\/actions\/bridge-editor\.php\?action=(add|edit)&meta=[^ ]+)/', $data, $matches);
|
||||||
|
|
||||||
|
// URLs in ein Array
|
||||||
|
$urls = $matches[1];
|
||||||
|
|
||||||
|
// Wiederholen der Requests
|
||||||
|
foreach ($urls as $url) {
|
||||||
|
$fullUrl = "http://localhost" . $url;
|
||||||
|
echo "▶️ Sende: $fullUrl\n";
|
||||||
|
@file_get_contents($fullUrl); // @ unterdrückt Warnungen bei Fehlern
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "✅ Wiederherstellung abgeschlossen.\n";
|
||||||
|
|
||||||
|
?>
|
||||||
97
db-test/index.php
Executable file
97
db-test/index.php
Executable file
@@ -0,0 +1,97 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$db = new SQLite3('test.db');
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
|
||||||
|
$db->exec('CREATE TABLE "bridges" (
|
||||||
|
"plug_id" INTEGER,
|
||||||
|
"id" INTEGER UNIQUE,
|
||||||
|
PRIMARY KEY("id"),
|
||||||
|
FOREIGN KEY("plug_id") REFERENCES "plugs"("id")
|
||||||
|
)');
|
||||||
|
|
||||||
|
$db->exec('CREATE TABLE "measurement_nodes" (
|
||||||
|
"required_by" INTEGER,
|
||||||
|
"node_from" INTEGER,
|
||||||
|
"node_to" INTEGER,
|
||||||
|
UNIQUE("required_by","node_from","node_to"),
|
||||||
|
FOREIGN KEY("required_by") REFERENCES ""
|
||||||
|
)');
|
||||||
|
|
||||||
|
$db->exec('CREATE TABLE "measurement_program_id_bits" (
|
||||||
|
"value" TEXT,
|
||||||
|
"position" INTEGER,
|
||||||
|
"measurement_id" INTEGER,
|
||||||
|
UNIQUE("position","measurement_id"),
|
||||||
|
FOREIGN KEY("measurement_id") REFERENCES ""
|
||||||
|
)');
|
||||||
|
|
||||||
|
$db->exec('CREATE TABLE "measurements" (
|
||||||
|
"id" INTEGER UNIQUE,
|
||||||
|
"place_name" TEXT,
|
||||||
|
"comment" TEXT,
|
||||||
|
"timestamp" INTEGER,
|
||||||
|
PRIMARY KEY("id" AUTOINCREMENT),
|
||||||
|
FOREIGN KEY("place_name") REFERENCES ""
|
||||||
|
)');
|
||||||
|
|
||||||
|
$db->exec('CREATE TABLE "nodes" (
|
||||||
|
"plug_id" INTEGER,
|
||||||
|
"required_by" INTEGER,
|
||||||
|
"node_from" INTEGER,
|
||||||
|
"node_to" INTEGER,
|
||||||
|
UNIQUE("plug_id","required_by","node_from","node_to"),
|
||||||
|
FOREIGN KEY("required_by") REFERENCES "bridges"("id")
|
||||||
|
)');
|
||||||
|
|
||||||
|
$db->exec('CREATE TABLE "places" (
|
||||||
|
"plug_id" INTEGER,
|
||||||
|
"name" TEXT UNIQUE,
|
||||||
|
PRIMARY KEY("name"),
|
||||||
|
FOREIGN KEY("plug_id") REFERENCES "plugs"("id")
|
||||||
|
)');
|
||||||
|
|
||||||
|
$db->exec('CREATE TABLE "plugs" (
|
||||||
|
"id" INTEGER UNIQUE,
|
||||||
|
"name" TEXT,
|
||||||
|
"char_number" INTEGER,
|
||||||
|
PRIMARY KEY("id")
|
||||||
|
)');
|
||||||
|
|
||||||
|
$db->exec('CREATE TABLE "program_bridge_relation" (
|
||||||
|
"program_id" INTEGER,
|
||||||
|
"bridge_id" INTEGER,
|
||||||
|
"plug_id" INTEGER,
|
||||||
|
UNIQUE("program_id","bridge_id","plug_id"),
|
||||||
|
FOREIGN KEY("bridge_id") REFERENCES "bridges"("id"),
|
||||||
|
FOREIGN KEY("plug_id") REFERENCES "plugs"("id"),
|
||||||
|
FOREIGN KEY("program_id") REFERENCES "programs"("id")
|
||||||
|
)');
|
||||||
|
|
||||||
|
$db->exec('CREATE TABLE "program_id_bits" (
|
||||||
|
"value" TEXT,
|
||||||
|
"position" INTEGER,
|
||||||
|
"program_id" INTEGER,
|
||||||
|
UNIQUE("position","program_id"),
|
||||||
|
FOREIGN KEY("program_id") REFERENCES "programs"("id")
|
||||||
|
)');
|
||||||
|
|
||||||
|
|
||||||
|
$db->exec('CREATE TABLE "programs" (
|
||||||
|
"id" INTEGER UNIQUE,
|
||||||
|
"plug_id" INTEGER,
|
||||||
|
"program_description" TEXT,
|
||||||
|
PRIMARY KEY("id"),
|
||||||
|
FOREIGN KEY("plug_id") REFERENCES "plugs"("id")
|
||||||
|
)');
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
$db->exec('DELETE FROM "places" WHERE 1');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
BIN
db-test/test.db
Normal file
BIN
db-test/test.db
Normal file
Binary file not shown.
2
errorcodes.php
Normal file
2
errorcodes.php
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<hr><h3>Fehlercodes:</h3>
|
||||||
|
<table id="errorcodes" style="min-width: 75px"><colgroup><col style="min-width: 25px"><col style="min-width: 25px"><col style="min-width: 25px"></colgroup><tbody><tr><th colspan="1" rowspan="1">Gruppe</th><th colspan="1" rowspan="1"></th><th colspan="1" rowspan="1">Beschreibung</th></tr><tr><td colspan="1" rowspan="5"><p style="text-align: center">Eine einzelne Prüfung betreffend</td><td colspan="1" rowspan="1">00</td><td colspan="1" rowspan="1">Fehlerfrei</td></tr><tr><td colspan="1" rowspan="1">01</td><td colspan="1" rowspan="1">Brücke angeblich erkannt, vom redundanten Multiplexer jedoch nicht bestätigt (ungleichen Pin betreffend)</td></tr><tr><td colspan="1" rowspan="1">02</td><td colspan="1" rowspan="1">Unterschiedliche Ergebnisse: Prüfer misst LOW, Redundanz misst HIGH</td></tr><tr><td colspan="1" rowspan="1">03</td><td colspan="1" rowspan="1">Unterschiedliche Ergebnisse: Prüfer misst HIGH, Redundanz misst LOW</td></tr><tr><td colspan="1" rowspan="1">04</td><td colspan="1" rowspan="1">Prüfspannung angeblich gesetzt, von der Redundanz jedoch nicht bestätigt</td></tr><tr><td colspan="1" rowspan="3"><p style="text-align: center">Die gesamte Prüfung betreffend</td><td colspan="1" rowspan="1">10</td><td colspan="1" rowspan="1">Fehlerfrei</td></tr><tr><td colspan="1" rowspan="1">11</td><td colspan="1" rowspan="1">Ein/mehrere Multiplexer nicht ansprechbar, i2c ordnungsgemäß gestartet</td></tr><tr><td colspan="1" rowspan="1">12</td><td colspan="1" rowspan="1">i2c-Bus nicht startfähig, keine Kommunikation möglich</td></tr><tr><td colspan="1" rowspan="1"></td><td colspan="1" rowspan="1">13</td><td colspan="1" rowspan="1">Fehlerursache nicht weiter spezifizierbar</td></tr></tbody></table><style>table#errorcodes td {border: 1px solid black;}</style>
|
||||||
198
functions.php
Normal file
198
functions.php
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// ===========================================================================================
|
||||||
|
// Analyse-Funktionen für die Spurkabelprüfung, Federleistenprüfung und Selbstidiagnose
|
||||||
|
// ===========================================================================================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Übsersetzungstabelle (Intern -> Steckerpin, gilt für Programmsteckerprüfung)
|
||||||
|
$translationMap = [
|
||||||
|
"0" => "18",
|
||||||
|
"1" => "19",
|
||||||
|
"2" => "20",
|
||||||
|
"3" => "21",
|
||||||
|
"4" => "22",
|
||||||
|
"5" => "23",
|
||||||
|
"6" => "24",
|
||||||
|
"7" => "25",
|
||||||
|
"8" => "10",
|
||||||
|
"9" => "11",
|
||||||
|
"10" => "12",
|
||||||
|
"11" => "13",
|
||||||
|
"12" => "14",
|
||||||
|
"13" => "15",
|
||||||
|
"14" => "16",
|
||||||
|
"15" => "17",
|
||||||
|
"16" => "34",
|
||||||
|
"17" => "35",
|
||||||
|
"18" => "36",
|
||||||
|
"19" => "37",
|
||||||
|
"20" => "38",
|
||||||
|
"21" => "39",
|
||||||
|
"22" => "40",
|
||||||
|
"23" => "41",
|
||||||
|
"24" => "26",
|
||||||
|
"25" => "27",
|
||||||
|
"26" => "28",
|
||||||
|
"27" => "29",
|
||||||
|
"28" => "30",
|
||||||
|
"29" => "31",
|
||||||
|
"30" => "32",
|
||||||
|
"31" => "33"
|
||||||
|
];
|
||||||
|
|
||||||
|
//Übsersetzungstabelle (Intern -> Steckerpin, gilt für Spurkabelprüfung)
|
||||||
|
$translationMap2 = [
|
||||||
|
"0" => "25",
|
||||||
|
"1" => "24",
|
||||||
|
"2" => "23",
|
||||||
|
"3" => "22",
|
||||||
|
"4" => "21",
|
||||||
|
"5" => "20",
|
||||||
|
"6" => "19",
|
||||||
|
"7" => "18",
|
||||||
|
"8" => "17",
|
||||||
|
"9" => "16",
|
||||||
|
"10" => "15",
|
||||||
|
"11" => "14",
|
||||||
|
"12" => "13",
|
||||||
|
"13" => "12",
|
||||||
|
"14" => "11",
|
||||||
|
"15" => "10",
|
||||||
|
"16" => "41",
|
||||||
|
"17" => "40",
|
||||||
|
"18" => "39",
|
||||||
|
"19" => "38",
|
||||||
|
"20" => "37",
|
||||||
|
"21" => "36",
|
||||||
|
"22" => "35",
|
||||||
|
"23" => "34",
|
||||||
|
"24" => "33",
|
||||||
|
"25" => "32",
|
||||||
|
"26" => "31",
|
||||||
|
"27" => "30",
|
||||||
|
"28" => "29",
|
||||||
|
"29" => "28",
|
||||||
|
"30" => "27",
|
||||||
|
"31" => "26"
|
||||||
|
];
|
||||||
|
|
||||||
|
// Diese Funktion übersetzt die interne Pin-Bezeichnung in die des Herstellers gem. translationMap
|
||||||
|
// weil die Hardware der Spurkabelprüfer anders verschaltet ist, als die des Programmsetckerprüfers, wird nach zwei Übersetzungstabellen bei der Spurkabelprüfung gearbeitet
|
||||||
|
// nodes[0] wird gem Standardtabelle gehandhabt, nodes[1] nach translationMap2 - unsauber, aber nur durhc Software lösbar
|
||||||
|
function translateArray($inputArray, $translationMap, $translationMap2 = null) {
|
||||||
|
return array_map(function($subArray) use ($translationMap, $translationMap2) {
|
||||||
|
$map1 = $translationMap;
|
||||||
|
$map2 = $translationMap2 ?? $translationMap; // Wenn keine zweite Map, nimm die erste
|
||||||
|
return [
|
||||||
|
$map1[$subArray[0]] ?? $subArray[0],
|
||||||
|
$map2[$subArray[1]] ?? $subArray[1]
|
||||||
|
];
|
||||||
|
}, $inputArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
function measurementsDiffer($bridges1, $bridges2) {
|
||||||
|
//Isoliere die Brücken
|
||||||
|
$bridges1 = array_map(function($entry) {
|
||||||
|
return $entry[0];
|
||||||
|
}, $bridges1);
|
||||||
|
|
||||||
|
$bridges2 = array_map(function($entry) {
|
||||||
|
return $entry[0];
|
||||||
|
}, $bridges2);
|
||||||
|
|
||||||
|
//Zeichne die Steckergrafik
|
||||||
|
$url1 = "../stecker.php?data=" . urlencode(json_encode(translateArray($bridges1, $translationMap)));
|
||||||
|
$url2 = "../stecker.php?data=" . urlencode(json_encode(translateArray($bridges2, $translationMap)));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
|
<p>
|
||||||
|
Es gab einen Fehler bei der Messung!</br>Messung 1 und Messung 2 lieferten keine übereinstimmenden Ergebnisse.<br>Bitte prüfen Sie, ob alle Steckverbindungen fest sitzen und vermeiden Sie Bewegungen, welche die Messung beeinträchtigen können.</br>Stellen Sie sicher, dass keine der Verbindungen gegen Erde kurzgeschlossen ist, da dies die Messung beeinträchtigt.<br>Erwägen Sie, eine erneute Messung durchzuführen.
|
||||||
|
</p>
|
||||||
|
<br>
|
||||||
|
<p>Ergebnis Messung 1:</p>
|
||||||
|
<i><?php print_r($output1); ?><i>
|
||||||
|
<img src="<?php echo $url1; ?>" />
|
||||||
|
<p>Ergebnis Messung 2:</p>
|
||||||
|
<i><?php print_r($output2); ?><i>
|
||||||
|
<img src="<?php echo $url2; ?>" />
|
||||||
|
<div class="save-button" onclick="window.location.href='#index'; pageload();$('.save-button').html('<img src=\'load.gif\' \>Bitte warten...');"><img src="/vendor/icons/nav-arrow-left.svg" \>Zurück</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function measurementsContainErrors($bridges) {
|
||||||
|
|
||||||
|
?>
|
||||||
|
<h3>Eine oder mehrere Prüfungen versagten. Vollständige Fehlerausgabe:</h3>
|
||||||
|
<table>
|
||||||
|
<tr><td>Brücke von</td><td>nach</td><td>Aufgetretene Fehler</td>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
foreach($bridges as $bridge) {
|
||||||
|
echo "<tr><td>" . $bridge[0][0] . "</td><td>" . $bridge[0][1] . "</td><td>" . $bridge[1] . "</td></tr>";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
<hr>
|
||||||
|
<h3>Fehlercodes:</h3>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
include("../errorcodes.php");
|
||||||
|
die();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Ootionale Funktion, die implizite Verbindungen herleitet (KI-generiert)
|
||||||
|
|
||||||
|
|
||||||
|
function completeCycleEdges(array $edges): array {
|
||||||
|
// 1. Alle einzigartigen Knoten extrahieren
|
||||||
|
$nodes = [];
|
||||||
|
foreach ($edges as $edge) {
|
||||||
|
foreach ($edge as $node) {
|
||||||
|
$nodes[$node] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$nodes = array_keys($nodes);
|
||||||
|
|
||||||
|
// 2. Sortiere Knoten (optional, für konsistente Reihenfolge)
|
||||||
|
sort($nodes);
|
||||||
|
|
||||||
|
// 3. Erstelle vollständigen Kreis (Verbindung i -> i+1, letzter -> erster)
|
||||||
|
$completeEdges = [];
|
||||||
|
$numNodes = count($nodes);
|
||||||
|
for ($i = 0; $i < $numNodes; $i++) {
|
||||||
|
$from = $nodes[$i];
|
||||||
|
$to = $nodes[($i + 1) % $numNodes]; // Kreis schließen
|
||||||
|
$completeEdges[] = [$from, $to];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $completeEdges;
|
||||||
|
}
|
||||||
|
|
||||||
|
$edges = [[0,1], [2,0]];
|
||||||
|
$result = completeCycleEdges($edges);
|
||||||
|
|
||||||
|
print_r($result);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
38
index.php
Normal file
38
index.php
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script src="/vendor/jquery.min.js"></script>
|
||||||
|
<script src="script.js"></script>
|
||||||
|
<link rel="stylesheet" href="style3.css">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=0.9">
|
||||||
|
</head>
|
||||||
|
<body onload="pageload(), checkConnection(), applySettings('plug')" onhashchange="pageload()">
|
||||||
|
<div class="main">
|
||||||
|
<div class="navigation">
|
||||||
|
<div class="navigation-header" onclick="secondaryNavigation('open','plug-select')">
|
||||||
|
<span>Steckerauswahl</span>
|
||||||
|
<div>Wird geladen...</div>
|
||||||
|
</div>
|
||||||
|
<div id="index" id="start" onclick="checkForReload('index');window.location.href='#index';"><img src="/vendor/icons/plug-type-l.svg" /><span>Federleiste prüfen</span></div>
|
||||||
|
<div id="cable-check" onclick="checkForReload('cable-check');window.location.href='#cable-check';"><img src="/vendor/icons/fiber-cable-icon.svg" /><span>Spurkabel prüfen</span></div>
|
||||||
|
<div id="inventory" onclick="checkForReload('inventory');window.location.href='#inventory';"><img src="/vendor/icons/product-delivery-tracking-icon.svg" /><span>Bestand</span></div>
|
||||||
|
<div id="bridge-editor" onclick="checkForReload('bridge-editor');window.location.href='#bridge-editor';"><img src="/vendor/icons/share-line-icon.svg" /><span>Brücken-Editor</span></div>
|
||||||
|
<div id="program-editor" onclick="checkForReload('program-editor');window.location.href='#program-editor';"><img src="/vendor/icons/plug-type-a.svg" /><span>Programm-Editor</span></div>
|
||||||
|
<div id="system" onclick="checkForReload('system');window.location.href='#system';"><img src="/vendor/icons/cpu.svg" /><span>System</span></div>
|
||||||
|
<div id="index" class="navigation-footer">
|
||||||
|
<div class="connection-indicator unknown"></div>Verbinde...<br>
|
||||||
|
<img class="infrago-logo" src="/vendor/DB_InfraGo_logo_red_black_100px_rgb.svg" width="100%" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="navigation secondary" id="navigation-secondary">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div id="message-box" style="display: none;position: absolute; bottom: 10px; left: 260px; right: 10px; background-color:grey;height:auto;padding:20px;box-sizing:border-box;transform: translateY(calc(100% + 5px));transition-duration:.5s; border-radius: 10px;background-color: #d2d2d2;z-index: 502;"></div>
|
||||||
|
<div class="content" id="content">
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
410
pagecontent/bridge-editor.php
Executable file
410
pagecontent/bridge-editor.php
Executable file
@@ -0,0 +1,410 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// Diese Seite ist für den Brücken-Editor
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
$db = new SQLite3('../db-test/test.db');
|
||||||
|
|
||||||
|
$view = $_GET["view"];
|
||||||
|
$meta = $_GET["meta"];
|
||||||
|
$_SESSION["meta"]=$meta;
|
||||||
|
|
||||||
|
switch($view) {
|
||||||
|
case "add": // Neue Brücke anlegen
|
||||||
|
?>
|
||||||
|
<div class="content-header">Brücken-Editor - Neu anlegen</div>
|
||||||
|
<div class="plug-table">
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$url = '../stecker.php?data=';
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<canvas id="bridge-editor-img" meta="<?php echo urlencode('[]'); ?>" style="background-image: url('<?php echo $url; ?>');" width="500" height="100"></canvas>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Dieses Skript ist zum Großteil aus dem Internet kopiert, jedoch dann an die eigenen Bedürfnisse angepasst worden - Quelle: keine Ahnung
|
||||||
|
var canvas = document.getElementById('bridge-editor-img');
|
||||||
|
var ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
var offscreenCanvas = document.createElement('canvas');
|
||||||
|
offscreenCanvas.width = canvas.width;
|
||||||
|
offscreenCanvas.height = canvas.height;
|
||||||
|
var offCtx = offscreenCanvas.getContext('2d');
|
||||||
|
|
||||||
|
var rects = [
|
||||||
|
// Obere Zeile
|
||||||
|
{id: 31, x: 405, y: 20}, {id: 32, x: 370, y: 20}, {id: 33, x: 335, y: 20},
|
||||||
|
{id: 34, x: 300, y: 20}, {id: 35, x: 265, y: 20}, {id: 36, x: 230, y: 20},
|
||||||
|
{id: 37, x: 195, y: 20}, {id: 38, x: 160, y: 20}, {id: 39, x: 125, y: 20},
|
||||||
|
{id: 30, x: 70, y: 20},
|
||||||
|
|
||||||
|
// Mittlere Zeile
|
||||||
|
{id: 21, x: 405, y: 44}, {id: 22, x: 370, y: 44}, {id: 23, x: 335, y: 44},
|
||||||
|
{id: 24, x: 300, y: 44}, {id: 25, x: 265, y: 44}, {id: 26, x: 220, y: 44},
|
||||||
|
{id: 27, x: 185, y: 44}, {id: 28, x: 150, y: 44}, {id: 29, x: 115, y: 44},
|
||||||
|
{id: 20, x: 70, y: 44},
|
||||||
|
|
||||||
|
// Untere Zeile
|
||||||
|
{id: 11, x: 405, y: 68}, {id: 12, x: 370, y: 68}, {id: 13, x: 335, y: 68},
|
||||||
|
{id: 14, x: 300, y: 68}, {id: 15, x: 265, y: 68}, {id: 16, x: 230, y: 68},
|
||||||
|
{id: 17, x: 195, y: 68}, {id: 18, x: 160, y: 68}, {id: 19, x: 125, y: 68},
|
||||||
|
{id: 10, x: 70, y: 68}
|
||||||
|
];
|
||||||
|
|
||||||
|
var colorID = 0;
|
||||||
|
|
||||||
|
var RECT_WIDTH = 25;
|
||||||
|
var RECT_HEIGHT = 10;
|
||||||
|
|
||||||
|
var drawing = false;
|
||||||
|
var startPoint = null;
|
||||||
|
|
||||||
|
function getCenterIfInRect(x, y) {
|
||||||
|
for (var rect of rects) {
|
||||||
|
if (
|
||||||
|
x >= rect.x &&
|
||||||
|
x <= rect.x + RECT_WIDTH &&
|
||||||
|
y >= rect.y &&
|
||||||
|
y <= rect.y + RECT_HEIGHT
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
x: rect.x + RECT_WIDTH / 2,
|
||||||
|
y: rect.y + RECT_HEIGHT / 2,
|
||||||
|
id: rect.id
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.addEventListener('mousedown', (e) => {
|
||||||
|
var rect = canvas.getBoundingClientRect();
|
||||||
|
var mouseX = e.clientX - rect.left;
|
||||||
|
var mouseY = e.clientY - rect.top;
|
||||||
|
|
||||||
|
var center = getCenterIfInRect(mouseX, mouseY);
|
||||||
|
if (center) {
|
||||||
|
startPoint = center;
|
||||||
|
drawing = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
canvas.addEventListener('mousemove', (e) => {
|
||||||
|
if (!drawing || !startPoint) return;
|
||||||
|
|
||||||
|
var rect = canvas.getBoundingClientRect();
|
||||||
|
var mouseX = e.clientX - rect.left;
|
||||||
|
var mouseY = e.clientY - rect.top;
|
||||||
|
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
ctx.drawImage(offscreenCanvas, 0, 0);
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(startPoint.x, startPoint.y);
|
||||||
|
ctx.lineTo(mouseX, mouseY);
|
||||||
|
ctx.strokeStyle = "red";
|
||||||
|
offCtx.lineWidth = 3;
|
||||||
|
ctx.stroke();
|
||||||
|
});
|
||||||
|
|
||||||
|
canvas.addEventListener('mouseup', (e) => {
|
||||||
|
if (!drawing || !startPoint) return;
|
||||||
|
|
||||||
|
var rect = canvas.getBoundingClientRect();
|
||||||
|
var mouseX = e.clientX - rect.left;
|
||||||
|
var mouseY = e.clientY - rect.top;
|
||||||
|
|
||||||
|
var endPoint = getCenterIfInRect(mouseX, mouseY);
|
||||||
|
drawing = false;
|
||||||
|
|
||||||
|
if (endPoint && startPoint.id !== endPoint.id) {
|
||||||
|
connectPins(startPoint.id, endPoint.id, "canvas");
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
} else {
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
ctx.drawImage(offscreenCanvas, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
startPoint = null;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
echo '
|
||||||
|
</div>
|
||||||
|
<div class="pin-table">'; // Hier folgt die eigentliche Bearbeitungs-Fläche
|
||||||
|
|
||||||
|
|
||||||
|
$pinTable_row = 0;
|
||||||
|
foreach ($nodes as $nodeItem) { // Anzahl an Gesamt-Brücken-Elementen (Dies ist Wichtig, da appliedPinRowNumber ein Funktionsparameter ist, damit JS weiß, an welcher Stelle ein neues Element mit welchem Index erstellt werden muss!)
|
||||||
|
$pinTable_row++;
|
||||||
|
}
|
||||||
|
$appliedPinRowNumber = $pinTable_row;
|
||||||
|
|
||||||
|
// im Folgenden die Eingabefelder anzeigen (mit aufsteigender ID)
|
||||||
|
$pinTable_row = 0;
|
||||||
|
foreach ($nodes as $nodeItem) {
|
||||||
|
echo '
|
||||||
|
<div class="row" id="pinRow_' . $pinTable_row . '">
|
||||||
|
<span>' . $nodeItem[0] . '</span>
|
||||||
|
<img src="/vendor/icons/data-transfer-both.svg" height="30px" />
|
||||||
|
<span>' . $nodeItem[1] . '</span>
|
||||||
|
<img style="transform: rotate(0deg); padding-top: 17.5px;" src="/vendor/icons/trash.svg" onclick="removePin(' . $pinTable_row . ')" height="30px"/>
|
||||||
|
</div>';
|
||||||
|
$pinTable_row++;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<button hidden id="bridge-editor-edit" value=""></button>
|
||||||
|
|
||||||
|
<div class="save-button" onclick="save('bridge-editor','add')"><img src="/vendor/icons/floppy-disk.svg" \>Speichern</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
break;
|
||||||
|
case "edit": // Bestehende Brücke bearbeiten
|
||||||
|
?>
|
||||||
|
<div class="content-header">Brücken-Editor - Bearbeiten</div>
|
||||||
|
<div class="plug-table">
|
||||||
|
<?php
|
||||||
|
$settings = json_decode(file_get_contents("../settings.json"), true);
|
||||||
|
$plug = $settings["plug"]; //$plug ist die plug-ID!
|
||||||
|
|
||||||
|
|
||||||
|
$result = $db->query("
|
||||||
|
SELECT * FROM bridges WHERE plug_id = '" . $plug . "' AND id = '" . $meta . "';
|
||||||
|
");
|
||||||
|
$result = $result->fetchArray(SQLITE3_ASSOC);
|
||||||
|
|
||||||
|
// Skelettstruktur: Die "Row" sorgt hier für das typische Layout, insbesodere für die Darstellung der Brückennummer
|
||||||
|
?>
|
||||||
|
<div class="row">
|
||||||
|
<?php
|
||||||
|
print('
|
||||||
|
<div class="label">
|
||||||
|
<span>' . $result["id"] . '</span>
|
||||||
|
</div>'); // Brückennummer
|
||||||
|
|
||||||
|
$nodes_url = [];
|
||||||
|
|
||||||
|
$nodes = $db->query("
|
||||||
|
SELECT node_from,node_to
|
||||||
|
FROM nodes WHERE required_by = '". $result['id'] ."';
|
||||||
|
");
|
||||||
|
|
||||||
|
while ($node = $nodes->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
$nodes_url[] = [$node['node_from'], $node['node_to']];
|
||||||
|
}
|
||||||
|
|
||||||
|
$url = '../stecker.php?data=' . urlencode(json_encode($nodes_url)); // URL parsen
|
||||||
|
$nodes = $nodes_url; // die Nodes speichern (hier stecken alle Daten drin)
|
||||||
|
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<canvas id="bridge-editor-img" meta="<?php echo urlencode(json_encode($nodes_url)); ?>" style="background-image: url('<?php echo $url; ?>');" width="500" height="100"></canvas>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Dieses Skript ist zum Großteil aus dem Internet kopiert, jedoch dann an die eigenen Bedürfnisse angepasst worden - Quelle: keine Ahnung
|
||||||
|
var canvas = document.getElementById('bridge-editor-img');
|
||||||
|
var ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
var offscreenCanvas = document.createElement('canvas');
|
||||||
|
offscreenCanvas.width = canvas.width;
|
||||||
|
offscreenCanvas.height = canvas.height;
|
||||||
|
var offCtx = offscreenCanvas.getContext('2d');
|
||||||
|
|
||||||
|
var rects = [
|
||||||
|
// Obere Zeile
|
||||||
|
{id: 31, x: 405, y: 20}, {id: 32, x: 370, y: 20}, {id: 33, x: 335, y: 20},
|
||||||
|
{id: 34, x: 300, y: 20}, {id: 35, x: 265, y: 20}, {id: 36, x: 230, y: 20},
|
||||||
|
{id: 37, x: 195, y: 20}, {id: 38, x: 160, y: 20}, {id: 39, x: 125, y: 20},
|
||||||
|
{id: 30, x: 70, y: 20},
|
||||||
|
|
||||||
|
// Mittlere Zeile
|
||||||
|
{id: 21, x: 405, y: 44}, {id: 22, x: 370, y: 44}, {id: 23, x: 335, y: 44},
|
||||||
|
{id: 24, x: 300, y: 44}, {id: 25, x: 265, y: 44}, {id: 26, x: 220, y: 44},
|
||||||
|
{id: 27, x: 185, y: 44}, {id: 28, x: 150, y: 44}, {id: 29, x: 115, y: 44},
|
||||||
|
{id: 20, x: 70, y: 44},
|
||||||
|
|
||||||
|
// Untere Zeile
|
||||||
|
{id: 11, x: 405, y: 68}, {id: 12, x: 370, y: 68}, {id: 13, x: 335, y: 68},
|
||||||
|
{id: 14, x: 300, y: 68}, {id: 15, x: 265, y: 68}, {id: 16, x: 230, y: 68},
|
||||||
|
{id: 17, x: 195, y: 68}, {id: 18, x: 160, y: 68}, {id: 19, x: 125, y: 68},
|
||||||
|
{id: 10, x: 70, y: 68}
|
||||||
|
];
|
||||||
|
|
||||||
|
var colorID = 0;
|
||||||
|
|
||||||
|
var RECT_WIDTH = 25;
|
||||||
|
var RECT_HEIGHT = 10;
|
||||||
|
|
||||||
|
var drawing = false;
|
||||||
|
var startPoint = null;
|
||||||
|
|
||||||
|
function getCenterIfInRect(x, y) {
|
||||||
|
for (var rect of rects) {
|
||||||
|
if (
|
||||||
|
x >= rect.x &&
|
||||||
|
x <= rect.x + RECT_WIDTH &&
|
||||||
|
y >= rect.y &&
|
||||||
|
y <= rect.y + RECT_HEIGHT
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
x: rect.x + RECT_WIDTH / 2,
|
||||||
|
y: rect.y + RECT_HEIGHT / 2,
|
||||||
|
id: rect.id
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.addEventListener('mousedown', (e) => {
|
||||||
|
var rect = canvas.getBoundingClientRect();
|
||||||
|
var mouseX = e.clientX - rect.left;
|
||||||
|
var mouseY = e.clientY - rect.top;
|
||||||
|
|
||||||
|
var center = getCenterIfInRect(mouseX, mouseY);
|
||||||
|
if (center) {
|
||||||
|
startPoint = center;
|
||||||
|
drawing = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
canvas.addEventListener('mousemove', (e) => {
|
||||||
|
if (!drawing || !startPoint) return;
|
||||||
|
|
||||||
|
var rect = canvas.getBoundingClientRect();
|
||||||
|
var mouseX = e.clientX - rect.left;
|
||||||
|
var mouseY = e.clientY - rect.top;
|
||||||
|
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
ctx.drawImage(offscreenCanvas, 0, 0);
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(startPoint.x, startPoint.y);
|
||||||
|
ctx.lineTo(mouseX, mouseY);
|
||||||
|
ctx.strokeStyle = "red";
|
||||||
|
offCtx.lineWidth = 3;
|
||||||
|
ctx.stroke();
|
||||||
|
});
|
||||||
|
|
||||||
|
canvas.addEventListener('mouseup', (e) => {
|
||||||
|
if (!drawing || !startPoint) return;
|
||||||
|
|
||||||
|
var rect = canvas.getBoundingClientRect();
|
||||||
|
var mouseX = e.clientX - rect.left;
|
||||||
|
var mouseY = e.clientY - rect.top;
|
||||||
|
|
||||||
|
var endPoint = getCenterIfInRect(mouseX, mouseY);
|
||||||
|
drawing = false;
|
||||||
|
|
||||||
|
if (endPoint && startPoint.id !== endPoint.id) {
|
||||||
|
connectPins(startPoint.id, endPoint.id, "canvas");
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
} else {
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
ctx.drawImage(offscreenCanvas, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
startPoint = null;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
echo '
|
||||||
|
</div>
|
||||||
|
<div class="pin-table">'; // Hier folgt die eigentliche Bearbeitungs-Fläche
|
||||||
|
|
||||||
|
$pinTable_row = 0;
|
||||||
|
foreach ($nodes as $nodeItem) { // Anzahl an Gesamt-Brücken-Elementen (Dies ist Wichtig, da appliedPinRowNumber ein Funktionsparameter ist, damit JS weiß, an welcher Stelle ein neues Element mit welchem Index erstellt werden muss!)
|
||||||
|
$pinTable_row++;
|
||||||
|
}
|
||||||
|
$appliedPinRowNumber = $pinTable_row;
|
||||||
|
|
||||||
|
// im Folgenden die Eingabefelder anzeigen (mit aufsteigender ID)
|
||||||
|
$pinTable_row = 0;
|
||||||
|
foreach ($nodes as $nodeItem) {
|
||||||
|
echo '
|
||||||
|
<div class="row" id="pinRow_' . $pinTable_row . '">
|
||||||
|
<span>' . $nodeItem[0] . '</span>
|
||||||
|
<img src="/vendor/icons/data-transfer-both.svg" height="30px" />
|
||||||
|
<span>' . $nodeItem[1] . '</span>
|
||||||
|
<img style="transform: rotate(0deg); padding-top: 17.5px;" src="/vendor/icons/trash.svg" onclick="removePin(' . $pinTable_row . ')" height="30px"/>
|
||||||
|
</div>';
|
||||||
|
$pinTable_row++;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<button id="bridge-editor-edit" value="" onclick="save('bridge-editor','edit','<?php echo $meta; ?>')">Speichern</button>
|
||||||
|
<?php
|
||||||
|
break;
|
||||||
|
default: // Standard: Übersicht
|
||||||
|
?>
|
||||||
|
<div class="content-header">Brücken-Editor - Übersicht</div>
|
||||||
|
<div class="action-menu">
|
||||||
|
<img src="/vendor/icons/plus.svg" onclick="window.location.href='#bridge-editor'; pageload('add');" />
|
||||||
|
</div>
|
||||||
|
<div class="plug-table">
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$settings = json_decode(file_get_contents("../settings.json"), true);
|
||||||
|
$plug = $settings["plug"]; //$plug ist die plug-ID!
|
||||||
|
|
||||||
|
|
||||||
|
$result = $db->query("SELECT * FROM bridges WHERE plug_id = '" . $plug . "';");
|
||||||
|
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
|
||||||
|
?>
|
||||||
|
<div class="row">
|
||||||
|
<?php
|
||||||
|
print('
|
||||||
|
<div class="label">
|
||||||
|
<span>' . $row['id'] . '</span>
|
||||||
|
</div>');
|
||||||
|
|
||||||
|
$nodes_url = [];
|
||||||
|
|
||||||
|
$nodes = $db->query("
|
||||||
|
SELECT node_from,node_to
|
||||||
|
FROM nodes WHERE required_by = ". $row['id'] .";
|
||||||
|
");
|
||||||
|
|
||||||
|
while ($node = $nodes->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
$nodes_url[] = [$node['node_from'], $node['node_to']];
|
||||||
|
}
|
||||||
|
|
||||||
|
$url = '../stecker.php?data=' . urlencode(json_encode($nodes_url)); // URL parsen
|
||||||
|
print('<img id="bridge-editor-img" src="' . $url . '" />');
|
||||||
|
print('
|
||||||
|
<div class="options">
|
||||||
|
<img src="/vendor/icons/edit-pencil.svg" onclick="window.location.href=\'#bridge-editor\'; pageload(\'edit\',\'' . $row["id"] . '\');"/>
|
||||||
|
<img src="/vendor/icons/trash.svg" onclick="if(confirm(\'Sicher? Diese Änderung kann nicht rückgängig gemacht werden!\') == true){save(\'bridge-editor\',\'remove\',\'' . $row["id"] . '\')}" />
|
||||||
|
</div>
|
||||||
|
');
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $db->query("SELECT COUNT(*) as anzahl FROM bridges WHERE plug_id = '" . $plug . "';");
|
||||||
|
$row = $result->fetchArray(SQLITE3_ASSOC);
|
||||||
|
$number = $row['anzahl'];
|
||||||
|
|
||||||
|
if($number <= 0) {
|
||||||
|
print("<p align='center'>Es sind keine Brücken für diesen Stecker gespeichert.<br>Eventuell muss ein anderer Stecker gewählt werden.</p>");
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
break;
|
||||||
|
}
|
||||||
13
pagecontent/cable-check.php
Executable file
13
pagecontent/cable-check.php
Executable file
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
?>
|
||||||
|
<div class="content-header">Spurkabel prüfen</div>
|
||||||
|
<hr />
|
||||||
|
<p>Automatische Erkennung</p>
|
||||||
|
<i>Verbinden Sie die Enden des Spurkabels mit dem Gerät. Vermeiden Sie Bewegungen während der Messung.</i>
|
||||||
|
|
||||||
|
<div class="save-button" onclick="window.location.href='#start-cable';$('.save-button').html('<img src=\'/vendor/icons/load.gif\' \>Initialisieren...'); "><img src="/vendor/icons/play.svg" \>Jetzt prüfen</div>
|
||||||
|
|
||||||
|
|
||||||
322
pagecontent/database-search.php
Executable file
322
pagecontent/database-search.php
Executable file
@@ -0,0 +1,322 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// Diese Seite durchsucht die Datenbank nach gespeicherten Werten (keine Brücken, Programme, etc..)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$meta = $_GET["meta"];
|
||||||
|
$view = $_GET["view"];
|
||||||
|
|
||||||
|
$db = new SQLite3('../db-test/test.db');
|
||||||
|
|
||||||
|
// Die Suche, auf welche nach der Durchführung einer Messung zugegriffen wird (ganz unten: möchten Sie die Messung in die Datenbank aufnehmen...)
|
||||||
|
if($view == "results") {
|
||||||
|
|
||||||
|
?>
|
||||||
|
<div class="inventory-table">
|
||||||
|
<?php
|
||||||
|
$result = 0;
|
||||||
|
|
||||||
|
// Hole die Orte
|
||||||
|
$result = $db->query(" SELECT * FROM places WHERE name LIKE '%" . strtolower($meta) . "%' ");
|
||||||
|
|
||||||
|
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
|
||||||
|
// Wenn die suche leer ist, sollen auch keine Ergebnisse kommen (siehe Vorschläge ignorieren)
|
||||||
|
if($meta == "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
<div class="row" style="cursor: pointer" onclick="$('#database-search-term').val('<?php echo $row["name"]; ?>'); search('results');">
|
||||||
|
<img src="/vendor/icons/map-pin.svg" class="map" /><span><?php echo $row["name"]; ?></span>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wenn ein Ergebnis gefunden wird...
|
||||||
|
if($result == 1) {
|
||||||
|
// ... biete an, alle Vorschläge zu ignorieren
|
||||||
|
?>
|
||||||
|
<div class="row" style="cursor: pointer; width:50%;margin:15px auto;background-color: #f6615173" onclick="$('#database-search-term').attr('onkeyup',''); search('results','x');">
|
||||||
|
<img src="/vendor/icons/xmark.svg" class="" /><span align="center">Vorschläge ignorieren</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
// Ende der Sucherergebnisse
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hier wird der Bestand angezeigt, der in der Bestandsuche nach einem Tastenanschlag erscheint
|
||||||
|
if($view == "program" && isset($meta) && !empty($meta)) {
|
||||||
|
|
||||||
|
|
||||||
|
// weil die Bestandssuche (im Gegensatz zur Ortssuche) die Programmbezeichnung durhcsucht, ist hier etwas mehr Aufwand erforderlich
|
||||||
|
// hole die Programmbezeichnung via 2x JOIN aus der Datenbank
|
||||||
|
$result = $db->query("
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
m.id AS measurement_id,
|
||||||
|
m.comment AS comment,
|
||||||
|
m.timestamp AS timestamp,
|
||||||
|
m.place_name AS place_name,
|
||||||
|
b.value AS bit_value,
|
||||||
|
b.position AS bit_position
|
||||||
|
FROM
|
||||||
|
measurements m
|
||||||
|
JOIN places p ON p.name = m.place_name
|
||||||
|
JOIN measurement_program_id_bits b ON b.measurement_id = m.id
|
||||||
|
ORDER BY m.id
|
||||||
|
|
||||||
|
");
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ausgabe sieht z.B. so aus:
|
||||||
|
|
||||||
|
| measurement_id | comment | timestamp | place_name | bit_value | bit_position |
|
||||||
|
| -------------- | ------- | --------- | ------------ | --------- | ------------ |
|
||||||
|
| 1 | xyz.. | 34535454 | Dudweiler Df | S | 0 |
|
||||||
|
| 1 | xyz.. | 34535454 | Dudweiler Df | - | 1 |
|
||||||
|
| 1 | xyz.. | 34535454 | Dudweiler Df | 4 | 2 |
|
||||||
|
| 1 | xyz.. | 34535454 | Dudweiler Df | - | 3 |
|
||||||
|
| 1 | xyz.. | 34535454 | Dudweiler Df | - | 4 |
|
||||||
|
| 7 | abc.. | 48548574 | Mannheim Hbf | A | 0 |
|
||||||
|
| 7 | abc.. | 48548574 | Mannheim Hbf | 6 | 1 |
|
||||||
|
| 7 | abc.. | 48548574 | Mannheim Hbf | 4 | 2 |
|
||||||
|
| 7 | abc.. | 48548574 | Mannheim Hbf | - | 3 |
|
||||||
|
| 7 | abc.. | 48548574 | Mannheim Hbf | S | 4 |
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Die Datenbank wird als dreifach indexiertes Array gespeichert
|
||||||
|
$database_db = [];
|
||||||
|
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
$database_db[$row["place_name"]][$row["measurement_id"]]["program_id_bits"][$row["bit_position"]] = $row["bit_value"];
|
||||||
|
$database_db[$row["place_name"]][$row["measurement_id"]]["comment"] = $row["comment"];
|
||||||
|
$database_db[$row["place_name"]][$row["measurement_id"]]["timestamp"] = $row["timestamp"];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
$database_db
|
||||||
|
└── $row["place_name"]
|
||||||
|
└── $row["measurement_id"]
|
||||||
|
├── "program_id_bits"
|
||||||
|
│ └── $row["bit_position"]
|
||||||
|
│ └── $row["bit_value"]
|
||||||
|
├── "program_id_string"
|
||||||
|
│ └── implode('', $bits)
|
||||||
|
├── "comment"
|
||||||
|
│ └── $row["comment"]
|
||||||
|
└── "timestamp"
|
||||||
|
└── $row["timestamp"]
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// speichere die Bits als String, damit diese einfacher durchsuchbar sind
|
||||||
|
foreach ($database_db as $place => $entries) {
|
||||||
|
foreach ($entries as $index => $info) {
|
||||||
|
$bits = $info['program_id_bits'];
|
||||||
|
$database_db[$place][$index]['program_id_string'] = implode('', $bits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// durchsuche nach der Query im Programm-ID-String
|
||||||
|
foreach($database_db as $place_name => $measurements) {
|
||||||
|
$found = false;
|
||||||
|
foreach ($measurements as $measurement_id => $measurement) {
|
||||||
|
if(str_contains(strtolower($measurement["program_id_string"]), strtolower($meta))) {
|
||||||
|
$found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($found != true) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<img src="/vendor/icons/map-pin.svg" class="map" />
|
||||||
|
<span>
|
||||||
|
<?php echo $place_name; ?>
|
||||||
|
</span>
|
||||||
|
<div class="plug-table" style="display: block;" id="<?php echo $database_db[$place_name]; ?>">
|
||||||
|
<?php
|
||||||
|
foreach ($measurements as $measurement_id => $measurement) {
|
||||||
|
|
||||||
|
if(!str_contains(strtolower($measurement["program_id_string"]), strtolower($meta))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
print('
|
||||||
|
<div class="row">
|
||||||
|
<div class="label" style="width: 180px;">
|
||||||
|
<span>');
|
||||||
|
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
foreach($measurement["program_id_bits"] as $programIDChar) {
|
||||||
|
echo '<span class="label-char">' . $programIDChar . '</span>';
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
print('
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="label" style="width: 50%;">
|
||||||
|
<span>' . date("d.m.Y H:i:s", $measurement["timestamp"]) . '</span>
|
||||||
|
</div>');
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="options">
|
||||||
|
<img src="/vendor/icons/trash.svg" onclick="if(confirm('Sicher? Diese Änderung kann nicht rückgängig gemacht werden! )') == true){save('inventory','remove','<?php echo $measurement_id; ?>')}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
print('
|
||||||
|
</div>
|
||||||
|
</div>');
|
||||||
|
|
||||||
|
if(!empty($measurement["comment"])) {
|
||||||
|
|
||||||
|
print('
|
||||||
|
<div class="row" style="position: relative; height: auto;padding: 0 15;padding-left: 40px;box-sizing:border-box;">
|
||||||
|
<img src="/vendor/icons/info-circle.svg" style=" top: 2.5px;left: 10px;" />');
|
||||||
|
echo $measurement["comment"];
|
||||||
|
print('
|
||||||
|
</div>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hier wird der Bestand angezeigt, der in der Bestandssuche nach dem Klick auf "Alle Einträge holen" angezeigt wird
|
||||||
|
elseif ($view == "program") {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ausgabe sieht z.B. so aus:
|
||||||
|
|
||||||
|
| measurement_id | comment | timestamp | place_name | bit_value | bit_position |
|
||||||
|
| -------------- | ------- | --------- | ------------ | --------- | ------------ |
|
||||||
|
| 1 | xyz.. | 34535454 | Dudweiler Df | S | 0 |
|
||||||
|
| 1 | xyz.. | 34535454 | Dudweiler Df | - | 1 |
|
||||||
|
| 1 | xyz.. | 34535454 | Dudweiler Df | 4 | 2 |
|
||||||
|
| 1 | xyz.. | 34535454 | Dudweiler Df | - | 3 |
|
||||||
|
| 1 | xyz.. | 34535454 | Dudweiler Df | - | 4 |
|
||||||
|
| 7 | abc.. | 48548574 | Mannheim Hbf | A | 0 |
|
||||||
|
| 7 | abc.. | 48548574 | Mannheim Hbf | 6 | 1 |
|
||||||
|
| 7 | abc.. | 48548574 | Mannheim Hbf | 4 | 2 |
|
||||||
|
| 7 | abc.. | 48548574 | Mannheim Hbf | - | 3 |
|
||||||
|
| 7 | abc.. | 48548574 | Mannheim Hbf | S | 4 |
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
$result = $db->query("
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
m.id AS measurement_id,
|
||||||
|
m.comment AS comment,
|
||||||
|
m.timestamp AS timestamp,
|
||||||
|
m.place_name AS place_name,
|
||||||
|
b.value AS bit_value,
|
||||||
|
b.position AS bit_position
|
||||||
|
FROM
|
||||||
|
measurements m
|
||||||
|
JOIN places p ON p.name = m.place_name
|
||||||
|
JOIN measurement_program_id_bits b ON b.measurement_id = m.id
|
||||||
|
ORDER BY m.id
|
||||||
|
|
||||||
|
");
|
||||||
|
|
||||||
|
// Die Datenbank wird als dreifach indexiertes Array gespeichert
|
||||||
|
$database_db = [];
|
||||||
|
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
$database_db[$row["place_name"]][$row["measurement_id"]]["program_id_bits"][$row["bit_position"]] = $row["bit_value"];
|
||||||
|
$database_db[$row["place_name"]][$row["measurement_id"]]["comment"] = $row["comment"];
|
||||||
|
$database_db[$row["place_name"]][$row["measurement_id"]]["timestamp"] = $row["timestamp"];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
$database_db
|
||||||
|
└── $row["place_name"]
|
||||||
|
└── $row["measurement_id"]
|
||||||
|
├── "program_id_bits"
|
||||||
|
│ └── $row["bit_position"]
|
||||||
|
│ └── $row["bit_value"]
|
||||||
|
├── "program_id_string"
|
||||||
|
│ └── implode('', $bits)
|
||||||
|
├── "comment"
|
||||||
|
│ └── $row["comment"]
|
||||||
|
└── "timestamp"
|
||||||
|
└── $row["timestamp"]
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
foreach($database_db as $place_name => $measurements) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<img src="/vendor/icons/map-pin.svg" class="map" /><span>[<?php echo count($database_db[$place_name]); ?>] <?php echo $place_name; ?></span>
|
||||||
|
<img src="/vendor/icons/arrow-down-tag.svg" class="down" onclick="$('#<?php echo preg_replace('/[^a-zA-Z0-9]/', '',$place_name); ?>').css('display','block');"/>
|
||||||
|
<div class="plug-table" style="display: none;" id="<?php echo preg_replace('/[^a-zA-Z0-9]/', '',$place_name); ?>">
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
foreach ($measurements as $measurement_id => $measurement) {
|
||||||
|
|
||||||
|
print('
|
||||||
|
<div class="row" style="margin-bottom: 0;">
|
||||||
|
<div class="label" style="width: 180px;">
|
||||||
|
<span>');
|
||||||
|
|
||||||
|
foreach($measurement["program_id_bits"] as $programIDChar) {
|
||||||
|
echo '
|
||||||
|
<span class="label-char">' . $programIDChar . '</span>';
|
||||||
|
}
|
||||||
|
|
||||||
|
print('
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="label" style="width: 50%;">
|
||||||
|
<span>' . date("d.m.Y H:i:s", $measurement["timestamp"]) . '</span>
|
||||||
|
</div>');
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="options"><img src="/vendor/icons/trash.svg" onclick="if(confirm('Sicher? Diese Änderung kann nicht rückgängig gemacht werden! )') == true){save('inventory','remove','<?php echo $measurement_id; ?>')}"></div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
print('
|
||||||
|
</div>
|
||||||
|
</div>');
|
||||||
|
|
||||||
|
if(!empty($measurement["comment"])) {
|
||||||
|
|
||||||
|
print('
|
||||||
|
<div class="row" style="position: relative; height: auto;padding: 0 15;padding-left: 40px;box-sizing:border-box;"><img src="/vendor/icons/info-circle.svg" style=" top: 2.5px;left: 10px;" />');
|
||||||
|
echo $measurement["comment"];
|
||||||
|
print('
|
||||||
|
</div>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
}
|
||||||
220
pagecontent/export.php
Executable file
220
pagecontent/export.php
Executable file
@@ -0,0 +1,220 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$_SESSION["meta"]=$meta;
|
||||||
|
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$db = new SQLite3('../db-test/test.db');
|
||||||
|
|
||||||
|
|
||||||
|
// weil die Bestandssuche (im Gegensatz zur Ortssuche) die Programmbezeichnung durhcsucht, ist hier etwas mehr Aufwand erforderlich
|
||||||
|
// hole die Programmbezeichnung via 2x JOIN aus der Datenbank
|
||||||
|
$result = $db->query("
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
m.id AS measurement_id,
|
||||||
|
m.comment AS comment,
|
||||||
|
m.timestamp AS timestamp,
|
||||||
|
m.place_name AS place_name,
|
||||||
|
b.value AS bit_value,
|
||||||
|
b.position AS bit_position,
|
||||||
|
n.node_from AS node_from,
|
||||||
|
n.node_to AS node_to
|
||||||
|
FROM
|
||||||
|
measurements m
|
||||||
|
JOIN places p ON p.name = m.place_name
|
||||||
|
JOIN measurement_program_id_bits b ON b.measurement_id = m.id
|
||||||
|
JOIN measurement_nodes n ON n.required_by = m.id
|
||||||
|
|
||||||
|
");
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ausgabe sieht z.B. so aus:
|
||||||
|
|
||||||
|
| measurement_id | comment | timestamp | place_name | bit_value | bit_position | node_from | node_to |
|
||||||
|
| -------------- | ------- | --------- | ------------ | --------- | ------------ | --------- | ------- |
|
||||||
|
| 1 | xyz.. | 34535454 | Dudweiler Df | S | 0 | 20 | 28 |
|
||||||
|
| 1 | xyz.. | 34535454 | Dudweiler Df | S | 0 | 28 | 30 |
|
||||||
|
| 1 | xyz.. | 34535454 | Dudweiler Df | - | 1 | 20 | 28 |
|
||||||
|
| 1 | xyz.. | 34535454 | Dudweiler Df | - | 1 | 28 | 30 |
|
||||||
|
| 1 | xyz.. | 34535454 | Dudweiler Df | 4 | 2 | 20 | 28 |
|
||||||
|
| 1 | xyz.. | 34535454 | Dudweiler Df | 4 | 2 | 28 | 30 |
|
||||||
|
| 1 | xyz.. | 34535454 | Dudweiler Df | - | 3 | 20 | 28 |
|
||||||
|
| 1 | xyz.. | 34535454 | Dudweiler Df | - | 3 | 28 | 30 |
|
||||||
|
| 1 | xyz.. | 34535454 | Dudweiler Df | - | 4 | 20 | 28 |
|
||||||
|
| 1 | xyz.. | 34535454 | Dudweiler Df | - | 4 | 28 | 30 |
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// Die Datenbank wird als dreifach indexiertes Array gespeichert
|
||||||
|
$database_db = [];
|
||||||
|
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
$id = $row["measurement_id"];
|
||||||
|
|
||||||
|
// Basisdaten setzen (überschreiben macht nichts)
|
||||||
|
$database_db[$id]["comment"] = $row["comment"];
|
||||||
|
$database_db[$id]["timestamp"] = $row["timestamp"];
|
||||||
|
$database_db[$id]["place_name"] = $row["place_name"];
|
||||||
|
|
||||||
|
// Programmbits: nur setzen, wenn nicht schon vorhanden
|
||||||
|
if (!isset($database_db[$id]["program_id_bits"][$row["bit_position"]])) {
|
||||||
|
$database_db[$id]["program_id_bits"][$row["bit_position"]] = $row["bit_value"];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nodes: nur hinzufügen, wenn noch nicht vorhanden
|
||||||
|
$node_pair = [$row["node_from"], $row["node_to"]];
|
||||||
|
if (
|
||||||
|
!isset($database_db[$id]["nodes"]) ||
|
||||||
|
!in_array($node_pair, $database_db[$id]["nodes"])
|
||||||
|
) {
|
||||||
|
$database_db[$id]["nodes"][] = $node_pair;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Ersetzen der $database_db[$id]["nodes"] zu einem String
|
||||||
|
$bitLength = 5;
|
||||||
|
$placeholder = '?';
|
||||||
|
foreach ($database_db as $index => $row) {
|
||||||
|
$programIdBits = isset($row['program_id_bits']) ? $row['program_id_bits'] : [];
|
||||||
|
$programIdString = '';
|
||||||
|
|
||||||
|
// Baue ein Array mit fester Länge ($bitLength), fülle fehlende Positionen mit Platzhalter
|
||||||
|
for ($i = 0; $i < $bitLength; $i++) {
|
||||||
|
$programIdString .= isset($programIdBits[$i]) ? $programIdBits[$i] : $placeholder;
|
||||||
|
}
|
||||||
|
|
||||||
|
$database_db[$index]['program_id_string'] = $programIdString;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// $list ist die CSV-Datei
|
||||||
|
|
||||||
|
//$list[] = array("Gemessen am / um", "Stw-Name / Ort" ,"Erkannte Brücken (Pin-zu-Pin)", "(automatisch) ermittelte Programm-Nummer", "Freitext-Besonderheiten");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// gehe jeden Datenwankeintrag durch
|
||||||
|
foreach($database_db as $database_entry) {
|
||||||
|
// leere dne node_string zu Beginn
|
||||||
|
$node_string = "";
|
||||||
|
// erstelle einen Brücken-String, der erweitert wird
|
||||||
|
foreach($database_entry["nodes"] as $node) {
|
||||||
|
$node_string .= $node[0] . "<->" . $node[1] . ", ";
|
||||||
|
}
|
||||||
|
|
||||||
|
$imagePath = 'http://localhost/stecker.php?data=' . urlencode(json_encode($database_entry["nodes"])); // URL parsen
|
||||||
|
|
||||||
|
// Schreibe ins Array
|
||||||
|
$list[] = array(date('d.m.Y H:i:s',$database_entry["timestamp"]), $database_entry["place_name"] ,$node_string, $database_entry["program_id_string"], $database_entry["comment"], $imagePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function svgUrlToPngViaRsvg(string $svgUrl, string $outputPath): bool {
|
||||||
|
$svgData = file_get_contents($svgUrl);
|
||||||
|
if ($svgData === false) return false;
|
||||||
|
|
||||||
|
$tempSvg = '../tmp/stecker_' . uniqid() . '.svg';
|
||||||
|
file_put_contents($tempSvg, $svgData);
|
||||||
|
|
||||||
|
|
||||||
|
$cmd = escapeshellcmd("rsvg-convert -o " . escapeshellarg($outputPath) . " " . escapeshellarg($tempSvg));
|
||||||
|
$result = shell_exec($cmd);
|
||||||
|
|
||||||
|
unlink($tempSvg);
|
||||||
|
|
||||||
|
return file_exists($outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
require '../vendor/composer/vendor/autoload.php';
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Neue Excel-Datei erzeugen
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
|
||||||
|
// Spaltenüberschriften
|
||||||
|
$sheet->setCellValue('A1', 'Zeitstempel');
|
||||||
|
$sheet->setCellValue('B1', 'Ort');
|
||||||
|
$sheet->setCellValue('C1', 'Brücken');
|
||||||
|
$sheet->setCellValue('D1', 'Programmbezeichnung');
|
||||||
|
$sheet->setCellValue('E1', 'Notizen');
|
||||||
|
|
||||||
|
// Durch das Array iterieren und Daten + Bild einfügen
|
||||||
|
$row = 2; // Start in Zeile 2
|
||||||
|
foreach ($list as $entry) {
|
||||||
|
[$timestamp,$place,$bridges,$program_number, $extra, $imagePath] = $entry;
|
||||||
|
|
||||||
|
// Namen einfügen
|
||||||
|
$sheet->setCellValue("A$row", $timestamp);
|
||||||
|
$sheet->setCellValue("B$row", $place);
|
||||||
|
$sheet->setCellValue("C$row", $bridges);
|
||||||
|
$sheet->setCellValue("D$row", $program_number);
|
||||||
|
$sheet->setCellValue("E$row", $extra);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$svgUrl = $imagePath;
|
||||||
|
$tmpPng = '../tmp/stecker_' . uniqid() . '.png';
|
||||||
|
|
||||||
|
// Bild einfügen, wenn Datei existiert
|
||||||
|
if (svgUrlToPngViaRsvg($svgUrl, $tmpPng)) {
|
||||||
|
$drawing = new Drawing();
|
||||||
|
$drawing->setPath($tmpPng);
|
||||||
|
$drawing->setCoordinates("F$row");
|
||||||
|
$drawing->setHeight(80);
|
||||||
|
$sheet->getRowDimension($row)->setRowHeight(80 * 0.75);
|
||||||
|
$drawing->setWorksheet($sheet);
|
||||||
|
} else {
|
||||||
|
$sheet->setCellValue("F$row", 'Bildkonvertierung fehlgeschlagen');
|
||||||
|
}
|
||||||
|
|
||||||
|
$row++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spaltenbreite anpassen
|
||||||
|
$sheet->getColumnDimension('A')->setAutoSize(true);
|
||||||
|
$sheet->getColumnDimension('B')->setWidth(20); // Platz fürs Bild
|
||||||
|
|
||||||
|
// Datei speichern
|
||||||
|
$writer = new Xlsx($spreadsheet);
|
||||||
|
$writer->save('../temp.xlsx');
|
||||||
|
|
||||||
|
shell_exec("rm ../tmp/*");
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="content-header">Export - Fertig</div>
|
||||||
|
<hr />
|
||||||
|
<p>
|
||||||
|
Ihr Datenexport ist fertig vorbereitet.
|
||||||
|
</p>
|
||||||
|
<div class="save-button" onclick="window.location.href='../temp.xlsx'"); "><img src="/vendor/icons/play.svg" \>Herunterladen</div>
|
||||||
|
|
||||||
|
|
||||||
15
pagecontent/index.php
Executable file
15
pagecontent/index.php
Executable file
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// Hauptseite
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
?>
|
||||||
|
<div class="content-header">Federleiste prüfen</div>
|
||||||
|
<hr />
|
||||||
|
<p>Automatische Erkennung</p>
|
||||||
|
<i>Verbinden Sie den zu messenden Stecker mit dem Gerät. Vermeiden Sie Bewegungen während der Messung.</i>
|
||||||
|
|
||||||
|
<div class="save-button" onclick="window.location.href='#start';$('.save-button').html('<img src=\'/vendor/icons/load.gif\' \>Prüfung läuft...'); "><img src="/vendor/icons/play.svg" \>Jetzt prüfen</div>
|
||||||
|
|
||||||
|
|
||||||
18
pagecontent/inventory.php
Executable file
18
pagecontent/inventory.php
Executable file
@@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
|
||||||
|
<div class="content-header">Bestand</div>
|
||||||
|
<div class="action-menu">
|
||||||
|
<img src="/vendor/icons/download.svg" onclick="window.location.href='#export'; $(this).attr('src','/vendor/icons/load.gif'); message('Der Export wird vorbereitet. Das kann etwas dauern...');" />
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<div class="search-container">
|
||||||
|
<input type="text" id="database-search-term" onkeyup="search('program')" placeholder="Programm durchsuchen..." />
|
||||||
|
<div class="results">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<div class="inventory-table" id="database-program-search" onload="search('program')">
|
||||||
|
<div class="save-button" onclick="search('program')"><img src="/vendor/icons/restart.svg" \>Alle Datensätze holen</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
1
pagecontent/plug-select.php
Executable file
1
pagecontent/plug-select.php
Executable file
@@ -0,0 +1 @@
|
|||||||
|
Aktuell werden keine verschiedenen Steckerarten unterstützt.
|
||||||
230
pagecontent/program-editor.php
Executable file
230
pagecontent/program-editor.php
Executable file
@@ -0,0 +1,230 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// Diese Seite lädt alle (Unter)Seiten des Programmeditors
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
$db = new SQLite3('../db-test/test.db');
|
||||||
|
|
||||||
|
$view = $_GET["view"];
|
||||||
|
$meta = $_GET["meta"];
|
||||||
|
|
||||||
|
$_SESSION["meta"]=$meta;
|
||||||
|
|
||||||
|
$plug = json_decode(file_get_contents("../settings.json"), true)["plug"];
|
||||||
|
|
||||||
|
|
||||||
|
switch($view) {
|
||||||
|
default: // Standardseite (Übersicht)
|
||||||
|
?>
|
||||||
|
<div class="content-header">Programm-Editor - Übersicht</div>
|
||||||
|
<div class="action-menu">
|
||||||
|
<img src="/vendor/icons/plus.svg" onclick="window.location.href='#program-editor'; pageload('add');" />
|
||||||
|
</div>
|
||||||
|
<div class="plug-table">
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// Hole die Programme aus der Datenbank
|
||||||
|
$result = $db->query("SELECT * FROM programs WHERE plug_id = '" . $plug . "';");
|
||||||
|
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
$results = true;
|
||||||
|
?>
|
||||||
|
<div class="row">
|
||||||
|
<?php
|
||||||
|
print('
|
||||||
|
<div class="label" style="width: 30%">
|
||||||
|
<span>');
|
||||||
|
// Stelle die einzelnen Programmziffern dar
|
||||||
|
$program_identifiers = $db->query("SELECT * FROM program_id_bits WHERE program_id = '" . $row['id'] . "';");
|
||||||
|
|
||||||
|
while ($program_identifier = $program_identifiers->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
echo '<span class="label-char">' . $program_identifier["value"] . '</span>';
|
||||||
|
}
|
||||||
|
print('
|
||||||
|
</span>
|
||||||
|
</div>');
|
||||||
|
|
||||||
|
// Die erforderlichen Brücken werden aus der Datenbank geholt (via program_bridge_relation)
|
||||||
|
$bridges_url = [];
|
||||||
|
$bridges = $db->query("SELECT * FROM program_bridge_relation WHERE program_id = '" . $row['id'] . "';");
|
||||||
|
|
||||||
|
while ($bridge = $bridges->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
$bridges_url[] = $bridge["bridge_id"];
|
||||||
|
}
|
||||||
|
|
||||||
|
$url = '../stecker.php?translate=true&data=' . urlencode(json_encode($bridges_url)); // URL parsen; Modus: Programmanzeige
|
||||||
|
|
||||||
|
print('<img id="bridge-editor-img" style="width: 55%" src="' . $url . '" />');
|
||||||
|
// Aktionsmenü (mit hässlichem Inline-Code)
|
||||||
|
print('
|
||||||
|
<div class="options">
|
||||||
|
<img src="/vendor/icons/edit-pencil.svg" onclick="window.location.href=\'#program-editor\'; pageload(\'edit\',\'' . $row['id'] . '\');"/>
|
||||||
|
<img src="/vendor/icons/trash.svg"onclick="
|
||||||
|
if(confirm(\'Sicher? Diese Änderung kann nicht rückgängig gemacht werden! (Die darin enthaltenen Brücken bleiben erhalten und werden nicht gelöscht )\') == true){
|
||||||
|
save(\'program-editor\',\'remove\',\'' . $row['id'] . '\')
|
||||||
|
}" />
|
||||||
|
</div>
|
||||||
|
');
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
// Wenn Ergebnisliste leer
|
||||||
|
if($results != true) {
|
||||||
|
print("<p align='center'>Es sind keine Programme für diesen Stecker gespeichert.<br>Eventuell muss ein anderer Stecker gewählt werden.</p>");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Neues Hinzufügen eines Programms
|
||||||
|
case "add":
|
||||||
|
|
||||||
|
$meta = json_decode(urldecode($meta), true);
|
||||||
|
?>
|
||||||
|
<div class="content-header">Programm-Editor - Neu anlegen</div>
|
||||||
|
<img id="program-editor-img" src="../stecker.php" />
|
||||||
|
<hr />
|
||||||
|
<p>Zugehörige Brücken</p>
|
||||||
|
<i>Wählen Sie die Brücken, welche von diesem Programm gefordert werden</i>
|
||||||
|
|
||||||
|
<div class="program-field">
|
||||||
|
<?php
|
||||||
|
|
||||||
|
//zählen der Ergebnisse
|
||||||
|
$result = $db->query("SELECT COUNT(*) as anzahl FROM bridges WHERE plug_id = '" . $plug . "';");
|
||||||
|
$row = $result->fetchArray(SQLITE3_ASSOC);
|
||||||
|
$results_full = $row['anzahl'];
|
||||||
|
|
||||||
|
$count = 0;
|
||||||
|
|
||||||
|
// Holen der Ergebnisse
|
||||||
|
$result = $db->query("SELECT * FROM bridges WHERE plug_id = '" . $plug . "';");
|
||||||
|
|
||||||
|
// Zeigt ein horizonales Auswhl-Menü an, das alle Brücken als auswahl bietet
|
||||||
|
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
?>
|
||||||
|
<label class="checkbox-container">
|
||||||
|
<input onchange="programBridge(<?php echo $results_full; ?>)" type="checkbox" id="programSelect_<?php echo $count; ?>" value="<?php echo $row['id']; ?>">
|
||||||
|
<span class="checkbox-text">
|
||||||
|
<?php echo $row['id']; ?>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<?php
|
||||||
|
$count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<p>Name für dieses Programm</p>
|
||||||
|
<i>
|
||||||
|
Hinweis: Der Name kann aus Sicherheitsgründen im Nachhinein nicht mehr geändert werden. Bei dieser Stellwerksart ist die ID fünfstellig<br>Ein '-' kennzeichnet ein "Don't-Care". Darüber hinaus sind nur Großbuchstaben und Zahlen zugelassen
|
||||||
|
</i>
|
||||||
|
<div class="distinctly-input">
|
||||||
|
<input oninput="distinctlyInput(1)" type="text" maxlength="1" class="code-input" id="distinctlyInput1">
|
||||||
|
<input oninput="distinctlyInput(2)" type="text" maxlength="1" class="code-input" id="distinctlyInput2">
|
||||||
|
<input oninput="distinctlyInput(3)" type="text" maxlength="1" class="code-input" id="distinctlyInput3">
|
||||||
|
<input oninput="distinctlyInput(4)" type="text" maxlength="1" class="code-input" id="distinctlyInput4">
|
||||||
|
<input oninput="distinctlyInput(5)" type="text" maxlength="1" class="code-input" id="distinctlyInput5">
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<p>Beschreibung für dieses Programm</p>
|
||||||
|
<textarea id="program-description" placeholder="Wählen Sie eine möglichst präzise Beschreibung. Zum Beispiel: 'Relaisgruppe für eine nicht isolierte Weiche, die eine einfache Kreuzungsweiche mit Bogenfahrt über den Plusstrang ist'"></textarea>
|
||||||
|
<hr />
|
||||||
|
<div class="save-button" onclick="save('program-editor','add',<?php echo $results_full; ?>)"><img src="/vendor/icons/floppy-disk.svg" \>Speichern</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "edit":
|
||||||
|
$meta = json_decode(urldecode($meta), true);
|
||||||
|
?>
|
||||||
|
<div class="content-header">Programm-Editor - Bearbeiten</div>
|
||||||
|
<?php
|
||||||
|
$bridges_url = [];
|
||||||
|
|
||||||
|
$bridges = $db->query("SELECT * FROM program_bridge_relation WHERE program_id = '" . $meta . "';");
|
||||||
|
|
||||||
|
while ($bridge = $bridges->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
|
||||||
|
$bridges_url[] = $bridge["bridge_id"];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$url = '../stecker.php?translate=true&data=' . urlencode(json_encode($bridges_url)); // URL parsen
|
||||||
|
|
||||||
|
print('<img id="program-editor-img" src="../stecker.php?translate=true&data=' . $url . '" />');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<p>Zugehörige Brücken</p>
|
||||||
|
<i>Wählen Sie die Brücken, welche von diesem Programm gefordert werden</i>
|
||||||
|
|
||||||
|
<div class="program-field">
|
||||||
|
|
||||||
|
<?php
|
||||||
|
// Hole Anzahl der Brücken aus der DB
|
||||||
|
$number_bridges = $db->query("SELECT COUNT(*) as anzahl FROM bridges WHERE plug_id = '" . $plug . "';");
|
||||||
|
|
||||||
|
$number_bridges = $number_bridges->fetchArray(SQLITE3_ASSOC);
|
||||||
|
$number_bridges = $number_bridges['anzahl'];
|
||||||
|
$number_joined = 0;
|
||||||
|
|
||||||
|
// Hole zunächst ALLE Brücken aus der DB
|
||||||
|
$bridges = $db->query("SELECT * FROM bridges WHERE plug_id = '" . $plug . "';");
|
||||||
|
|
||||||
|
while ($bridge = $bridges->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
|
||||||
|
// schaue nun, ob diese Brücke Teil des Programms ist
|
||||||
|
$bridges_contained = $db->query("SELECT COUNT(*) as anzahl FROM program_bridge_relation WHERE plug_id = '" . $plug . "' and bridge_id = '" . $bridge["id"] . "' and program_id = '" . $meta . "';");
|
||||||
|
|
||||||
|
$row = $bridges_contained->fetchArray(SQLITE3_ASSOC);
|
||||||
|
$number = $row['anzahl'];
|
||||||
|
|
||||||
|
// Die Anzahl gibt Aufschlus darüber, ob Brücke von Programm gefordert ist -> wenn schon vorhanden, markiere diese Brücke schon vor ("checked"-Attribut)
|
||||||
|
?>
|
||||||
|
<label class="checkbox-container">
|
||||||
|
<input onchange="programBridge(<?php echo $number_bridges; ?>)" type="checkbox" <?php if($number > 0) { echo "checked"; } ?> id="programSelect_<?php echo $number_joined; ?>" value="<?php echo $bridge["id"]; ?>">
|
||||||
|
<span class="checkbox-text">
|
||||||
|
<?php echo $bridge["id"]; ?>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$number_joined++;
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<p>Name für dieses Programm</p>
|
||||||
|
<i>Darf auf Sicherheitsgründen nicht mehr geändert werden</i>
|
||||||
|
|
||||||
|
<div class="distinctly-input">
|
||||||
|
<?php
|
||||||
|
// Hole die ganzen Programmbezeichner raus aus der DB
|
||||||
|
$program_identifiers = $db->query("SELECT * FROM program_id_bits WHERE program_id = '" . $meta . "' ORDER BY position;");
|
||||||
|
while ($program_identifier = $program_identifiers->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
echo '<input type="text" maxlength="1" value="' . $program_identifier["value"] . '" disabled class="code-input">';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vorausgefüllte Programmbezeichnung
|
||||||
|
$description = ($row = $db->querySingle("SELECT program_description FROM programs WHERE id = '$meta' and plug_id = '$plug'", true)) ? $row['program_description'] : null;
|
||||||
|
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<p>Beschreibung für dieses Programm</p>
|
||||||
|
<textarea id="program-description" value="Value" placeholder="Wählen Sie eine möglichst präzise Beschreibung. Zum Beispiel: 'Relaisgruppe für eine nicht isolierte Weiche, die eine einfache Kreuzungsweiche mit Bogenfahrt über den Plusstrang ist'"><?php echo $description; ?></textarea>
|
||||||
|
<hr />
|
||||||
|
<div class="save-button" onclick="save('program-editor','edit',<?php echo $number_bridges; ?>)"><img src="/vendor/icons/floppy-disk.svg" \>Speichern</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
break;
|
||||||
|
}
|
||||||
131
pagecontent/selfcheck.php
Executable file
131
pagecontent/selfcheck.php
Executable file
@@ -0,0 +1,131 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
|
||||||
|
require("../functions.php");
|
||||||
|
|
||||||
|
$view = $_GET["view"];
|
||||||
|
$meta = $_GET["meta"];
|
||||||
|
$_SESSION["meta"] = $meta;
|
||||||
|
|
||||||
|
if ($view == "results") {
|
||||||
|
|
||||||
|
//Befehl zum Starten des Skripts
|
||||||
|
$command = escapeshellcmd('python3 /var/www/html/python/selfcheck.py');
|
||||||
|
|
||||||
|
//output und bridges sind die Ergebnisse des Durchlaufs
|
||||||
|
$output = json_decode(shell_exec($command), true);
|
||||||
|
$bridges = $output["data"];
|
||||||
|
|
||||||
|
//Zeigt schon der Erste durchlauf Fehler auf, kann abgebrochen werden (1. Fehlerfall)
|
||||||
|
if($output["logs"]["errorcode"] != 10) {
|
||||||
|
?>
|
||||||
|
<h3>
|
||||||
|
Die Prüfung konnte nicht abgeschlossen werden. <i>Fehler <?php echo $output["logs"]["errorcode"]; ?></i>
|
||||||
|
</h3>
|
||||||
|
<?php
|
||||||
|
include("../errorcodes.php");
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Isoliere die Brücken und speichere sie als $bridges (hiermit wird später alles weitere verarbeitet)
|
||||||
|
$bridges = array_map(function($entry) {
|
||||||
|
return $entry[0];
|
||||||
|
}, $output["data"]);
|
||||||
|
|
||||||
|
//Isoliere die Fehlercodes der ersten Messung; da Messungen identisch reicht erste Messung
|
||||||
|
$errors = array_filter($output["data"], function($entry) {
|
||||||
|
return $entry[1] !== 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
//Wenn Fehlerspeicher gefüllt: Ausgabe und Abbruch
|
||||||
|
if (!empty($errors)) {
|
||||||
|
|
||||||
|
measurementsContainErrors($output["data"]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="content-header">Selbstdiagnose - Ergebnisse</div>
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<style>
|
||||||
|
table {
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 10px;
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
width: 2.5%;
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<h2>Detailansicht</h2>
|
||||||
|
<p>Der Pin der jeweiligen Spalte wird eingeschaltet; Pins, welche einen Eingang registrieren, werden in der entsprechenden Zeile grün dargestellt.</p>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<?php
|
||||||
|
// Kopfzeile
|
||||||
|
echo "<tr>";
|
||||||
|
for ($j = 0; $j <= 32; $j++) {
|
||||||
|
$index = $j - 1;
|
||||||
|
if ($index == -1) {
|
||||||
|
echo "<td></td>";
|
||||||
|
} else {
|
||||||
|
echo "<td>$index</td>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo "</tr>";
|
||||||
|
|
||||||
|
// Matrix
|
||||||
|
for ($i = 0; $i <= 31; $i++) {
|
||||||
|
echo "<tr>";
|
||||||
|
echo "<td>$i</td>";
|
||||||
|
|
||||||
|
for ($j = 0; $j <= 31; $j++) {
|
||||||
|
$search = [$j, $i];
|
||||||
|
if (in_array($search, $bridges)) {
|
||||||
|
echo "<td style='color: green;'>✔</td>";
|
||||||
|
} else {
|
||||||
|
echo "<td style='color: gray;'>-</td>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo "</tr>";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</table>
|
||||||
|
<hr />
|
||||||
|
<?php
|
||||||
|
print("<p>Erklärung:<br>
|
||||||
|
Jede Verbindung darf nur einmal aufgeführt sein. Gibt es Doppelungen, so besteht eine unzulässige Verbindung zu einem anderen Pin.
|
||||||
|
Kann sich ein Pin nicht selbst auslesen, so weist dies auf einen internen Kabelbruch oder ein defektes Bauteil hin.
|
||||||
|
Ist der Fehler spiegelsymmetrisch (z.B. 10-20 und 20-10), deutet dies auf einen Kurzschluss im System hin.
|
||||||
|
Tritt der Fehler nur einseitig auf, ist ein Bauteil defekt.</p>");
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="save-button" onclick="window.location.href='#selfcheck'; pageload();$('.save-button').html('<img src=\'/vendor/icons/load.gif\' \>Bitte warten...');">
|
||||||
|
<img src="/vendor/icons/nav-arrow-left.svg">Zurück
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
} else {
|
||||||
|
?>
|
||||||
|
<div class="content-header">Selbstdiagnose</div>
|
||||||
|
|
||||||
|
<p>Sollten während Messungen Fehler aufgetreten sein, kann hier eine interne Diagnose durchgeführt werden. Dabei wird jeder "Pin" einmalig als Ausgang gesetzt und gleichzeitig der Wert ausgelesen. Nur, wenn der Pin selbst gelesen werden kann und keine unzulässigen Verbindungen zu anderen Pins bestehen, wird die Prüfung erfolgreich abgeschlossen.</p>
|
||||||
|
<hr />
|
||||||
|
<p><i>Bitte trennen Sie zuvor alle Verbindungen, sodass sich das Gerät im Leerlauf befindet. <b>Angeschlossene Kabel und Stecker verfälschen das Ergebnis!</b></i></p>
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<div class="save-button" onclick="window.location.href='#selfcheck'; pageload('results');$('.save-button').html('<img src=\'/vendor/icons/load.gif\' \>Bitte warten...');">
|
||||||
|
<img src="/vendor/icons/ecg-monitoring-icon.svg">Selbstdiagnose ausführen
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
122
pagecontent/start-cable.php
Executable file
122
pagecontent/start-cable.php
Executable file
@@ -0,0 +1,122 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
require("../functions.php");
|
||||||
|
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
|
||||||
|
$db = new SQLite3('../db-test/test.db');
|
||||||
|
|
||||||
|
//Befehl zum Starten des Skripts
|
||||||
|
$command = escapeshellcmd('python3 /var/www/html/python/cable-check.py');
|
||||||
|
|
||||||
|
//output1 und bridges1 sind die Ergebnisse des ersten Durchlaufs
|
||||||
|
$output1 = json_decode(shell_exec($command), true);
|
||||||
|
$bridges1 = $output1["data"];
|
||||||
|
|
||||||
|
//Zeigt schon der Erste durchlauf Fehler auf, kann abgebrochen werden (1. Fehlerfall)
|
||||||
|
if($output1["logs"]["errorcode"] != 10) {
|
||||||
|
?>
|
||||||
|
<h3>
|
||||||
|
Die Prüfung konnte nicht abgeschlossen werden. <i>Fehler <?php echo $output1["logs"]["errorcode"]; ?></i>
|
||||||
|
</h3>
|
||||||
|
<?php
|
||||||
|
include("../errorcodes.php");
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
//wenn bis hierhin ok: weitere Prüfung
|
||||||
|
$output2 = json_decode(shell_exec($command), true);
|
||||||
|
$bridges2 = $output2["data"];
|
||||||
|
|
||||||
|
//Die Messungen sind nicht identisch (egal ob wg Fehlercodes oder Daten, ungleiche Messungen sind immer schlecht) -> 2. Fehlerfall
|
||||||
|
//es wäre schon sehr eigenartig, wenn verschiedene Fehlercodes nacheinander ausgespuckt würden (Wackelkontakt?)
|
||||||
|
if($bridges1 !== $bridges2) {
|
||||||
|
|
||||||
|
measurementsDiffer($bridges1, $bridges2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Isoliere die Brücken und speichere sie als $bridges (hiermit wird später alles weitere verarbeitet)
|
||||||
|
$bridges = array_map(function($entry) {
|
||||||
|
return $entry[0];
|
||||||
|
}, $bridges1);
|
||||||
|
|
||||||
|
//Isoliere die Fehlercodes der ersten Messung; da Messungen identisch reicht erste Messung
|
||||||
|
$errors = array_filter($bridges1, function($entry) {
|
||||||
|
return $entry[1] !== 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
//Wenn Fehlerspeicher gefüllt: Ausgabe und Abbruch
|
||||||
|
if (!empty($errors)) {
|
||||||
|
|
||||||
|
measurementsContainErrors($bridges1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
//Ab hier wird die Logik geprüft, die Messung ist bis hierhin äußerlich in Ordnung
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
|
||||||
|
$bridges = translateArray($bridges, $translationMap, $translationMap2);
|
||||||
|
|
||||||
|
$cleaned_output = [];
|
||||||
|
$errors = [];
|
||||||
|
|
||||||
|
$ok = true;
|
||||||
|
|
||||||
|
// iteriere durch die Messung und prüfe, ob stets gilt [[20,20],[22,22]]
|
||||||
|
//wenn nein: Kurzschluss ($errors)
|
||||||
|
foreach($bridges as $bridge) {
|
||||||
|
if($bridge[0] == $bridge[1]) {
|
||||||
|
$cleaned_output[] = $bridge[0];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$ok = false;
|
||||||
|
$errors[] = $bridge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Haupt-Steckergrafik
|
||||||
|
$url = 'stecker.php?mode=fill&data=' . urlencode(json_encode($cleaned_output));
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="content-header">Ergebnis</div>
|
||||||
|
<hr />
|
||||||
|
<h2>Vollständigkeit</h2>
|
||||||
|
<p><i>Die folgende Grafik zeigt Ihnen, auf welchen Adern eine durchgängige Verbindung erkannt wurde. Nur, wenn alle Pins grün gefüllt sind, ist das Spurkabel in Ordnung!</i></p>
|
||||||
|
<img src="<?php echo $url; ?>" />
|
||||||
|
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
$url = 'stecker.php?data=' . urlencode(json_encode($errors)); // Kodiert es für die URL
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Unzulässigkeiten</h2>
|
||||||
|
<p><i>Die folgende Grafik zeigt Ihnen, auf welchen Adern eine Verbindung zu einer anderen Ader erkannt wurde. Ist die Grafik leer, sind alle Adern korrekt isoliert.</i></p>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
if($ok != true) {
|
||||||
|
?>
|
||||||
|
<p style='color: red !important'>
|
||||||
|
Es wurde mindestens ein Kurzschluss gefunden!
|
||||||
|
</p>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<img src="<?php echo $url; ?>" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="save-button" onclick="window.location.href='#cable-check';"><img src="/vendor/icons/nav-arrow-left.svg" \>Zurück</div>
|
||||||
|
|
||||||
625
pagecontent/start.php
Executable file
625
pagecontent/start.php
Executable file
@@ -0,0 +1,625 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
require("../functions.php");
|
||||||
|
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
|
||||||
|
$db = new SQLite3('../db-test/test.db');
|
||||||
|
|
||||||
|
//Befehl zum Starten des Skripts
|
||||||
|
$command = escapeshellcmd('python3 /var/www/html/python/observer-full.py');
|
||||||
|
|
||||||
|
//output1 und bridges1 sind die Ergebnisse des ersten Durchlaufs
|
||||||
|
$output1 = json_decode(shell_exec($command), true);
|
||||||
|
$bridges1 = $output1["data"];
|
||||||
|
|
||||||
|
//Zeigt schon der Erste durchlauf Fehler auf, kann abgebrochen werden (1. Fehlerfall)
|
||||||
|
if($output1["logs"]["errorcode"] != 10) {
|
||||||
|
?>
|
||||||
|
<h3>
|
||||||
|
Die Prüfung konnte nicht abgeschlossen werden. <i>Fehler <?php echo $output1["logs"]["errorcode"]; ?></i>
|
||||||
|
</h3>
|
||||||
|
<?php
|
||||||
|
include("../errorcodes.php");
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
//wenn bis hierhin ok: weitere Prüfung
|
||||||
|
$output2 = json_decode(shell_exec($command), true);
|
||||||
|
$bridges2 = $output2["data"];
|
||||||
|
|
||||||
|
//Die Messungen sind nicht identisch (egal ob wg Fehlercodes oder Daten, ungleiche Messungen sind immer schlecht) -> 2. Fehlerfall
|
||||||
|
//es wäre schon sehr eigenartig, wenn verschiedene Fehlercodes nacheinander ausgespuckt würden (Wackelkontakt?)
|
||||||
|
if($bridges1 !== $bridges2) {
|
||||||
|
|
||||||
|
measurementsDiffer($bridges1, $bridges2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Isoliere die Brücken und speichere sie als $bridges (hiermit wird später alles weitere verarbeitet)
|
||||||
|
$bridges = array_map(function($entry) {
|
||||||
|
return $entry[0];
|
||||||
|
}, $bridges1);
|
||||||
|
|
||||||
|
//Isoliere die Fehlercodes der ersten Messung; da Messungen identisch reicht erste Messung
|
||||||
|
$errors = array_filter($bridges1, function($entry) {
|
||||||
|
return $entry[1] !== 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
//Wenn Fehlerspeicher gefüllt: Ausgabe und Abbruch
|
||||||
|
if (!empty($errors)) {
|
||||||
|
|
||||||
|
measurementsContainErrors($bridges1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
//Ab hier wird die Logik geprüft, die Messung ist bis hierhin äußerlich in Ordnung
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
|
||||||
|
//Hier wird jetzt geprüft, dass jede Messung bidirektional aufgenommen wurde, also 10<>20 UND 20<>10
|
||||||
|
$doubles = []; // Array zur Verfolgung von Doppelungen
|
||||||
|
$errors = []; // Array für fehlende Doppelungen
|
||||||
|
|
||||||
|
// Untersuche die einzelnen aufgenommenen Messpaare
|
||||||
|
foreach ($bridges as $pair) {
|
||||||
|
// Jedes Paar MUSS aus zwei Elementen bestehen
|
||||||
|
if (count($pair) !== 2) {
|
||||||
|
$errors[] = $pair; // speichere diesen fehlerhaften Eintrag
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Sortiere die Paare, um [23,14] und [14,23] gleich zu behandeln
|
||||||
|
sort($pair);
|
||||||
|
// Setze dieses Paar als "Index", um es gleich wieder zu finden
|
||||||
|
$key = implode("-", $pair);
|
||||||
|
// Prüfe, ob dieser Eintrag schon einmal da war
|
||||||
|
if (isset($doubles[$key])) {
|
||||||
|
$doubles[$key]++; // Verbindung erneut gefunden
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$doubles[$key] = 1; // Erstmaliges Auftreten
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Überprüfe, ob jede Verbindung genau zweimal vorhanden ist
|
||||||
|
foreach ($doubles as $key => $count) {
|
||||||
|
if ($count !== 2) {
|
||||||
|
$errors[] = $key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Abbruch bei fehlenden Doppelungen
|
||||||
|
if (!empty($errors)) {
|
||||||
|
echo "Die Messung wurde zwar erfolgreich abgeschlossen, die Messergebnisse überzeugten jedoch nicht.<br>Es ist notwendig, dass Kabelbrücken aus beiden Richtungen erkannt werden.<br>Erwägen Sie, eine erneute Messung durchzuführen. Sollte der Fehler erneut auftreten, ist ein interner Defekt des Prüfgeräts wahrscheinlich.<br><br>Die folgende(n) Kabelbrücke(n) konnte(n) nur one-way gemessen werden: <br>";
|
||||||
|
print_r($errors);
|
||||||
|
|
||||||
|
?>
|
||||||
|
<div class="save-button" onclick="window.location.href='#index'; pageload();$('.save-button').html('<img src=\'load.gif\' \>Bitte warten...');"><img src="/vendor/icons/nav-arrow-left.svg" \>Zurück</div>
|
||||||
|
<?php
|
||||||
|
die(); // Skript abbrechen
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
//Die Messung ist valide. Es kann ausgegeben werden
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
// Bereinigung der doppelten Einträge
|
||||||
|
$unique = []; // Array für eindeutige Verbindungen
|
||||||
|
$seen = []; // Array zur Verfolgung bereits bearbeiteter Verbindungen
|
||||||
|
|
||||||
|
foreach ($bridges as $pair) {
|
||||||
|
// Sortiere das Paar
|
||||||
|
sort($pair);
|
||||||
|
$key = implode("-", $pair);
|
||||||
|
|
||||||
|
// Füge nur ein Exemplar hinzu
|
||||||
|
if (!isset($seen[$key])) {
|
||||||
|
$unique[] = $pair;
|
||||||
|
$seen[$key] = true; // Markiere als verarbeitet
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Wichtigste Variable - sieht z.b. so aus: [[20,30],[10,15]] - redundanzfrei und aufsteigend sortiert
|
||||||
|
$measurement_result = translateArray($unique, $translationMap);
|
||||||
|
$measurement_result_number = count($measurement_result); // Anzahl gemessener Brücken
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Haupt-Steckergrafik
|
||||||
|
$url = 'stecker.php?data=' . urlencode(json_encode($measurement_result));
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="content-header">Ergebnis</div>
|
||||||
|
<hr />
|
||||||
|
<div class="toggle-switch">
|
||||||
|
<div align="right"><p>Gesamtergebnis</p></div>
|
||||||
|
<div>
|
||||||
|
<label class="switch">
|
||||||
|
<input type="checkbox" onchange='$("#op-1").toggle(this.unchecked);$("#op-2").toggle(this.checked);'>
|
||||||
|
<span class="slider"></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div align="left">
|
||||||
|
<p>Einzelbrücken</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="op-1">
|
||||||
|
<img src="<?php echo $url; ?>" />
|
||||||
|
</div>
|
||||||
|
<div id="op-2" style="display: none;">
|
||||||
|
<?php
|
||||||
|
|
||||||
|
foreach($measurement_result as $bridge) {
|
||||||
|
// Hier muss der übertragene Wert unschön manuell in [] gesetzt werden, da ein äußeres, indexiertes Array erwartet wird...
|
||||||
|
?>
|
||||||
|
<img style="margin-bottom: 5px;" src="<?php echo 'stecker.php?data=' . urlencode("[" . json_encode($bridge) . "]"); ?>" />
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<h2>Identifizierte Brücken</h2>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
//Hole aktuellen Stecker aus der JSON-Datei
|
||||||
|
$settings = json_decode(file_get_contents("../settings.json"), true);
|
||||||
|
$plug = $settings["plug"];
|
||||||
|
|
||||||
|
$identified_bridges = [];
|
||||||
|
|
||||||
|
//Hole alle Nodes via JOIN aus der Dankebak
|
||||||
|
$nodes = $db->query("
|
||||||
|
SELECT
|
||||||
|
b.id AS bridge_id,
|
||||||
|
n.node_from,
|
||||||
|
n.node_to
|
||||||
|
FROM
|
||||||
|
bridges b
|
||||||
|
JOIN
|
||||||
|
nodes n ON b.id = n.required_by
|
||||||
|
ORDER BY
|
||||||
|
b.id
|
||||||
|
");
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ausgabe sieht z.B. so aus:
|
||||||
|
|
||||||
|
| bridge_id | node_from | node_to |
|
||||||
|
| --------- | --------- | ------- |
|
||||||
|
| 1 | 20 | 30 |
|
||||||
|
| 1 | 13 | 17 |
|
||||||
|
| 2 | 10 | 15 |
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
//die DB-ausgbe wird als indexiertes Array gespeichert, um einfacher durchsucht werden zu können
|
||||||
|
$bridges_db = [];
|
||||||
|
while ($row = $nodes->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
//Die Bridge-ID ist der Index, die geforderten Brücken werden im Standardformat eingefügt, z.B.: 1 => [[20,30],[13,17]]
|
||||||
|
$bridge_id = $row['bridge_id'];
|
||||||
|
$bridges_db[$bridge_id][] = [$row['node_from'], $row['node_to']];
|
||||||
|
}
|
||||||
|
|
||||||
|
//Vergleiche Datenbank mit gemessenen Werten
|
||||||
|
//iteriere durch alle Datenabnk-Brücken
|
||||||
|
foreach($bridges_db as $bridge_db => $required_nodes) {
|
||||||
|
$satisfied = true;
|
||||||
|
//iteriere durch alle von einer Brücke geforderten Node-Paare
|
||||||
|
foreach($required_nodes as $required_nodes_pairs) {
|
||||||
|
$innerMatch = 0;
|
||||||
|
// vergleiche die aktuelle Datenbank-Node mit allen gemessenen Nodes (+überkreuz)
|
||||||
|
for($i=0;$i<$measurement_result_number;$i++) {
|
||||||
|
if(($required_nodes_pairs[0] == $measurement_result[$i][0] && $required_nodes_pairs[1] == $measurement_result[$i][1] )||($required_nodes_pairs[1] == $measurement_result[$i][0] && $required_nodes_pairs[0] == $measurement_result[$i][1])){
|
||||||
|
// innerhalb der Node-zu-Node-Verbidnung wurde die Bedingung erfüllt
|
||||||
|
$innerMatch = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($innerMatch != 1) {
|
||||||
|
// An dieser Stelle wird satisfied direkt negiert, da mind. eine Abhängigkeit, die in der Datenbank gefordert ist, nicht gefunden wurde
|
||||||
|
$satisfied = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Kommen alle Nodes vor, wird die Brücke mit ihrem entsprechenden Namen dargestellt
|
||||||
|
if($satisfied == true) {
|
||||||
|
//Brücke vollständig enthalten -> speichern für später (Programm-Erkennung)
|
||||||
|
$identified_bridges[] = $bridge_db;
|
||||||
|
|
||||||
|
//Erinnerung: es gilt bridge_db=>bridges_db
|
||||||
|
$url = '../stecker.php?data=' . urlencode(json_encode($bridges_db[$bridge_db])); // URL parsen
|
||||||
|
?>
|
||||||
|
<div class="row">
|
||||||
|
<?php
|
||||||
|
print('<div class="label"><span>' . $bridge_db . '</span></div>');
|
||||||
|
print('<img id="bridge-editor-img" src="' . $url . '" />');
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Speicher für identifizierte Programme
|
||||||
|
$identified_programs = [];
|
||||||
|
|
||||||
|
//Hole Programme aus der Datenbank (via program_bridge_relation)
|
||||||
|
$programs = $db->query("
|
||||||
|
SELECT
|
||||||
|
p.id AS program_id,
|
||||||
|
p.program_description,
|
||||||
|
b.id AS bridge_id,
|
||||||
|
r.plug_id
|
||||||
|
FROM
|
||||||
|
program_bridge_relation r
|
||||||
|
JOIN programs p ON p.id = r.program_id
|
||||||
|
JOIN bridges b ON b.id = r.bridge_id
|
||||||
|
WHERE r.plug_id = '" . $plug . "'
|
||||||
|
");
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ausgabe sieht z.B. so aus:
|
||||||
|
|
||||||
|
| program_id | program_description | bridge_id |
|
||||||
|
| ---------- | ------------------- | --------- |
|
||||||
|
| 1 | Weiche, die... | 1 |
|
||||||
|
| 2 | Gs, die... | 1 |
|
||||||
|
| 2 | Gs, die... | 10 |
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
$bridges_db = [];
|
||||||
|
while ($row = $programs->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
// Gleiches vorgehen wie bei den Brücken: Programm-ID ist Index, Brücken sind Inhalt (2 => [1,10])
|
||||||
|
$program_id = $row['program_id'];
|
||||||
|
$programs_db[$program_id][] = $row['bridge_id'];
|
||||||
|
$program_descriptions[$program_id] = $row['program_description'];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Ist eine Stelle der Kennung des Programmsteckers zwischendrin doppelt beschrieben woren, wird idse Variable wahr
|
||||||
|
$double_program_identifier = false;
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
|
<hr />
|
||||||
|
<h2>Identifizierte Programme</h2>
|
||||||
|
<div class="plug-table">
|
||||||
|
<?php
|
||||||
|
$program_cache = ["?","?","?","?","?"]; // Die Steckerbezeichnung ist zu Beginn noch unbestimmt
|
||||||
|
|
||||||
|
//iteriere durch alle DB-Programme
|
||||||
|
foreach($programs_db as $program_db => $required_bridges) {
|
||||||
|
|
||||||
|
if(!empty($identified_bridges)) { //Abscicherung, sonst würde ein leeres Programm immer als vollständig enthalten markiert werden
|
||||||
|
$ok = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$ok = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iteriere durch alle geforderten Brücken
|
||||||
|
foreach ($required_bridges as $bridge_id) {
|
||||||
|
// sollte sich eine Programmbrücke nicht unter den identifizierten Messwerte befinden -> ok=0
|
||||||
|
if (!in_array($bridge_id, $identified_bridges)) {
|
||||||
|
$ok = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Programm ist mit allen Brücken vollständig vertreten
|
||||||
|
if($ok == 1) {
|
||||||
|
|
||||||
|
?>
|
||||||
|
<div class="row">
|
||||||
|
<div class="label" style="width: 30%">
|
||||||
|
<span>
|
||||||
|
<?php
|
||||||
|
// Stelle die einzelnen Programmziffern dar, indemdiese aus der DB geladen werden
|
||||||
|
$program_identifiers = $db->query("SELECT * FROM program_id_bits WHERE program_id = '" . $program_db . "' ORDER BY position;");
|
||||||
|
|
||||||
|
while ($program_identifier = $program_identifiers->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
echo '<span class="label-char">' . $program_identifier["value"] . '</span>';
|
||||||
|
if($program_identifier["value"] != "" && $program_identifier["value"] != "-") { // wenn noch nicht anders beschrieben oder leer -> Einfügen in großen "Gesamtspeicher" für später
|
||||||
|
if($program_cache[$program_identifier["position"]] == "?") {
|
||||||
|
$program_cache[$program_identifier["position"]] = $program_identifier["value"];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Wenn Stelle schon gesetzt war -> Warnung speichern
|
||||||
|
$double_program_identifier = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$url = '../stecker.php?translate=true&data=' . urlencode(json_encode($required_bridges)); // URL parsen
|
||||||
|
print('<img id="bridge-editor-img" style="width: 55%" src="' . $url . '" />');
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="row" style="position: relative;box-sizing: border-box;padding-left: 45px;">
|
||||||
|
<img style="max-height: 100%;width: auto;display: inline-block;filter: opacity(.5);position: absolute;left:10px" src="/vendor/icons/info-circle.svg" style=" top: 2.5px;left: 10px;">
|
||||||
|
<?php echo $program_descriptions[$program_db]; ?>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<h2>Kennungs-Nummer</h2>
|
||||||
|
<div class="plug-table" style="margin-bottom: 0;">
|
||||||
|
<div class="row">
|
||||||
|
<div class="label" style="width: 180px;float: none">
|
||||||
|
<span>
|
||||||
|
<?php
|
||||||
|
// Die Gesamt-Kennung-Nummer wurde zuvor von den identifizierten Programmen bestimmt und wird hier ausgegeben
|
||||||
|
$ok = 1;
|
||||||
|
foreach($program_cache as $cacheChar) {
|
||||||
|
echo '<span class="label-char">' . $cacheChar . '</span>';
|
||||||
|
if($cacheChar == "?") {
|
||||||
|
$ok = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
if($ok != 1) {
|
||||||
|
?>
|
||||||
|
<p style='color: red !important'>
|
||||||
|
Wichtiger Hinweis: Es sind nicht alle Stellen der Kennungsnummer definiert. Dies deutet darauf hin, dass möglicherweise nicht alle Programme des Steckers korrekt erkannt wurden. Andererseits kann auch die Programm-Datenbank unvollständig sein, sodass eine Erkennung nicht möglich ist.<br>Betrachten Sie daher das Ergebnis mit Vorsicht!
|
||||||
|
</p>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
if ($double_program_identifier == true) {
|
||||||
|
?>
|
||||||
|
<p style='color: red !important'>
|
||||||
|
Wichtiger Hinweis: Im Laufe der Programmabgleiche wurde versucht, eine Stelle der Gesamtkennungsnummer zu übeschreiben, da diese bereits durch ein vorheriges Programm festgelegt wurde. Details dazu finden Sie unter "Indentifizierte Programme". Bitte gleichen Sie die Spalten ab, ob eine doppelte Stellendefinition vorliegt!<br>Betrachten Sie daher das Ergebnis mit Vorsicht!
|
||||||
|
</p>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<hr />
|
||||||
|
<h2>Identische Messungen</h2>
|
||||||
|
<div class="inventory-table">
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
//Hole vorherige Messungen aus der DB
|
||||||
|
$measurement_nodes_db = $db->query("
|
||||||
|
SELECT
|
||||||
|
m.id AS measurement_id,
|
||||||
|
m.comment AS comment,
|
||||||
|
m.timestamp AS timestamp,
|
||||||
|
m.place_name AS place_name,
|
||||||
|
n.node_from AS node_from,
|
||||||
|
n.node_to AS node_to
|
||||||
|
FROM
|
||||||
|
measurements m
|
||||||
|
JOIN places p ON p.name = m.place_name
|
||||||
|
JOIN measurement_nodes n ON m.id = n.required_by
|
||||||
|
ORDER BY m.id
|
||||||
|
");
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ausgabe sieht z.B. so aus:
|
||||||
|
|
||||||
|
| measurement_id | comment | timestamp | place_name | node_from | node_to |
|
||||||
|
| -------------- | ------- | ---------- | -------------------- | --------- | ------- |
|
||||||
|
| 1 | abc | 1753357680 | Mannheim-Waldhof Wf | 20 | 26 |
|
||||||
|
| 1 | abc | 1753357680 | Mannheim-Waldhof Wf | 13 | 16 |
|
||||||
|
| 1 | abc | 1753357680 | Mannheim-Waldhof Wf | 30 | 35 |
|
||||||
|
| 2 | def | 1753357548 | Dudweiler Df | 30 | 35 |
|
||||||
|
| 2 | def | 1753357548 | Dudweiler Df | 10 | 12 |
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Auch hier werden alle Messungen erstmal komplex indexiert (also zwei ineinander indexierte Arrays): measurement_id=>(nodes=>[[30,35],[10,12]], place_name, timestamp, comment)
|
||||||
|
$measurements_db = [];
|
||||||
|
while ($row = $measurement_nodes_db->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
$measurement_id = $row['measurement_id'];
|
||||||
|
$measurements_db[$measurement_id]['nodes'][] = [$row['node_from'],$row['node_to']];
|
||||||
|
$measurements_db[$measurement_id]['place_name'] = $row['place_name'];
|
||||||
|
$measurements_db[$measurement_id]['timestamp'] = $row['timestamp'];
|
||||||
|
$measurements_db[$measurement_id]['comment'] = $row['comment'];
|
||||||
|
}
|
||||||
|
|
||||||
|
//Indikator, dass alle Brücken gefunden wurden
|
||||||
|
$ok = 0;
|
||||||
|
|
||||||
|
foreach ($measurements_db as $measurement_db) {
|
||||||
|
$satisfied = true;
|
||||||
|
|
||||||
|
foreach ($measurement_result as $bridge_measure) {
|
||||||
|
$found = false;
|
||||||
|
|
||||||
|
foreach ($measurement_db["nodes"] as $measurement_db_node) {
|
||||||
|
// Prüfe, ob Brücke identisch (+ überkreuz)
|
||||||
|
if (
|
||||||
|
($bridge_measure[0] == $measurement_db_node[0] && $bridge_measure[1] == $measurement_db_node[1]) ||
|
||||||
|
($bridge_measure[0] == $measurement_db_node[1] && $bridge_measure[1] == $measurement_db_node[0])
|
||||||
|
) {
|
||||||
|
$found = true; // Brücke gefunden
|
||||||
|
break; // Nächste Brücke prüfen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$found) {
|
||||||
|
// Diese Brücke nicht in DB gefunden -> Messung nicht erfüllt
|
||||||
|
$satisfied = false;
|
||||||
|
break; // weitere Brücken prüfen sinnlos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($satisfied) {
|
||||||
|
$ok = 1;
|
||||||
|
|
||||||
|
?>
|
||||||
|
<div class="row">
|
||||||
|
<img src="/vendor/icons/map-pin.svg" class="map">
|
||||||
|
<span>
|
||||||
|
<?php
|
||||||
|
echo $measurement_db["place_name"];
|
||||||
|
?>
|
||||||
|
</span>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
if(!empty($measurement_db["comment"])) {
|
||||||
|
?>
|
||||||
|
<img src="/vendor/icons/info-circle.svg" style="top: 30px;" class="map">
|
||||||
|
<span>
|
||||||
|
<?php
|
||||||
|
echo $measurement_db["comment"];
|
||||||
|
?>
|
||||||
|
</span>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="plug-table" style="display: block;">
|
||||||
|
<div class="row" style="margin-bottom:0; height: 57px;">
|
||||||
|
<div>
|
||||||
|
<div class="label" style="width: 100%;height:auto;">
|
||||||
|
<span>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
echo "Messung vom/um <b>" . date('d.m.Y H:i:s',$measurement_db["timestamp"]) . "</b>";
|
||||||
|
?>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
//Wenn keine Messungen gefunden:
|
||||||
|
if($ok == 0) {
|
||||||
|
?>
|
||||||
|
<p>Keine bekannt.</p>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<h2>Anpassen der Ergebnisse</h2>
|
||||||
|
|
||||||
|
<table class="simple-devider">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<h3>Kennungs-Nr.</h3>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="distinctly-input" style="width: 100%;">
|
||||||
|
<input oninput="distinctlyInput(1)" type="text" maxlength="1" value="<?php echo $program_cache[0]; ?>" class="code-input" id="distinctlyInput1">
|
||||||
|
<input oninput="distinctlyInput(2)" type="text" maxlength="1" value="<?php echo $program_cache[1]; ?>" class="code-input" id="distinctlyInput2">
|
||||||
|
<input oninput="distinctlyInput(3)" type="text" maxlength="1" value="<?php echo $program_cache[2]; ?>" class="code-input" id="distinctlyInput3">
|
||||||
|
<input oninput="distinctlyInput(4)" type="text" maxlength="1" value="<?php echo $program_cache[3]; ?>" class="code-input" id="distinctlyInput4">
|
||||||
|
<input oninput="distinctlyInput(5)" type="text" maxlength="1" value="<?php echo $program_cache[4]; ?>" class="code-input" id="distinctlyInput5">
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<h3>Sekundärbrücken abwählen</h3>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="program-field">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
|
||||||
|
$count = count($measurement_result);
|
||||||
|
|
||||||
|
foreach ( $measurement_result as $bridge) {
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<label class="checkbox-container">
|
||||||
|
<input checked onchange="excludeBridge(<?php echo $count; ?>)" type="checkbox" id="programSelect_<?php echo $i; ?>" value='[<?php echo $bridge[0] . "," . $bridge[1]; ?>]'>
|
||||||
|
|
||||||
|
|
||||||
|
<span class="checkbox-text">
|
||||||
|
<?php echo $bridge[0] . "-" . $bridge[1]; ?>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$i++;
|
||||||
|
|
||||||
|
} ?>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<img id="result-editor-result" src="../stecker.php" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<h3>Besonderheiten</h3>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<textarea id="database-special" style="height: 80px;" placeholder="z.B. + Brücke 45, - Brücke 13"></textarea>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<h2>Speichern unter...?</h2>
|
||||||
|
|
||||||
|
<div class="search-container">
|
||||||
|
<input type="text" id="database-search-term" onkeyup="search('results')" placeholder="Beginnen Sie zu tippen..." />
|
||||||
|
<div class="save-button" onclick="save('inventory','add');"><img src="/vendor/icons/floppy-disk.svg" \></div>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// Speichern für "action/inventory.php"
|
||||||
|
$_SESSION["bridges"] = $measurement_result;
|
||||||
|
|
||||||
|
?>
|
||||||
|
<input type="hidden" id="database-bridges" value="<?php echo urlencode(json_encode($measurement_result)); ?>" />
|
||||||
|
<input type="hidden" id="database-bridges-hidden" value="" />
|
||||||
|
<div class="results"></div>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
<i>Die dargestellten Vorschläge befinden sich bereits in der Datenbank. Geben Sie einen Ort sein, der noch nicht in der Datenbank vorhanden ist, so wird dieser automatisch erstellt</i>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<div class="save-button" onclick="if (window.confirm('Das Messergebnis wird verworfen, sollte es nicht gespeichert worden sein. Fortfahren?')) { window.location.href='#index'; pageload();$('.save-button').html('<img src=\'load.gif\' \>Bitte warten...');}"><img src="/vendor/icons/nav-arrow-left.svg" \>Zurück</div>
|
||||||
|
|
||||||
|
|
||||||
124
pagecontent/stecker.php
Executable file
124
pagecontent/stecker.php
Executable file
@@ -0,0 +1,124 @@
|
|||||||
|
<?php
|
||||||
|
// Setze den Content-Type-Header für SVG
|
||||||
|
header('Content-Type: image/svg+xml');
|
||||||
|
echo '<?xml version="1.0" encoding="UTF-8"?>';
|
||||||
|
?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
width="500" height="100">
|
||||||
|
|
||||||
|
<defs>
|
||||||
|
<style>
|
||||||
|
@font-face {
|
||||||
|
font-family: LexendDecaBold;
|
||||||
|
src: url(http://192.168.37.103/vendor/fonts/LexendDeca-Bold.ttf);
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
font-family: LexendDecaBold;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<text x="30" y="5" fill="black" text-anchor="middle" transform="translate(50,50) rotate(-90)">30</text>
|
||||||
|
<text x="-30" y="5" fill="black" text-anchor="middle" transform="translate(50,50) rotate(-90)">10</text>
|
||||||
|
<text x="30" y="405" fill="black" text-anchor="middle" transform="translate(50,50) rotate(-90)">31</text>
|
||||||
|
<text x="-30" y="405" fill="black" text-anchor="middle" transform="translate(50,50) rotate(-90)">11</text>
|
||||||
|
|
||||||
|
|
||||||
|
<path d="M500 0 L50 0" style="stroke:black;stroke-width:5; fill:none;" />
|
||||||
|
<path d="M50 0 L0 25" style="stroke:black;stroke-width:3; fill:none;" />
|
||||||
|
<path d="M0 25 L0 75" style="stroke:black;stroke-width:5; fill:none;" />
|
||||||
|
<path d="M0 75 L50 100" style="stroke:black;stroke-width:3; fill:none;" />
|
||||||
|
<path d="M50 100 L500 100" style="stroke:black;stroke-width:5; fill:none;" />
|
||||||
|
<path d="M500 100 L500 0" style="stroke:black;stroke-width:5; fill:none;" />
|
||||||
|
|
||||||
|
|
||||||
|
<rect width="35" height="35" x="452" y="32" rx="5" ry="5" style="stroke:black;stroke-width:3;fill:none" />
|
||||||
|
<circle r="8" cx="470" cy="50" fill="none" style="stroke:black;stroke-width:3;" />
|
||||||
|
<rect width="35" height="35" x="13" y="32" rx="5" ry="5" style="stroke:black;stroke-width:3;fill:none" />
|
||||||
|
<circle r="8" cx="30" cy="50" fill="none" style="stroke:black;stroke-width:3;" />
|
||||||
|
|
||||||
|
|
||||||
|
<rect width="380" height="80" x="60" y="10" rx="5" ry="5" style="stroke:black;stroke-width:3;fill:none" />
|
||||||
|
|
||||||
|
<?php
|
||||||
|
$pin_coordinates = [
|
||||||
|
10 => [70, 68], 20 => [70, 44], 30 => [70, 20],
|
||||||
|
11 => [405, 68], 12 => [370, 68], 13 => [335, 68], 14 => [300, 68],
|
||||||
|
15 => [265, 68], 16 => [230, 68], 17 => [195, 68], 18 => [160, 68], 19 => [125, 68],
|
||||||
|
21 => [405, 44], 22 => [370, 44], 23 => [335, 44], 24 => [300, 44],
|
||||||
|
25 => [265, 44], 26 => [220, 44], 27 => [185, 44], 28 => [150, 44], 29 => [115, 44],
|
||||||
|
31 => [405, 20], 32 => [370, 20], 33 => [335, 20], 34 => [300, 20],
|
||||||
|
35 => [265, 20], 36 => [230, 20], 37 => [195, 20], 38 => [160, 20], 39 => [125, 20],
|
||||||
|
];
|
||||||
|
|
||||||
|
// Rechtecke einfärben, wenn "fill"-Modus aktiv ist
|
||||||
|
if ($_GET["mode"] == "fill") {
|
||||||
|
$data = $_GET["data"];
|
||||||
|
$data = json_decode(urldecode($data), true);
|
||||||
|
|
||||||
|
foreach ($pin_coordinates as $key => $coordinates) {
|
||||||
|
$fill = in_array($key, $data) ? "green" : "red";
|
||||||
|
echo '<rect width="25" height="10" x="' . $coordinates[0] . '" y="' . $coordinates[1] . '" rx="1" ry="1" style="stroke:black;stroke-width:3;fill:' . $fill . '" />';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Nur Umrisse
|
||||||
|
foreach ($pin_coordinates as $coordinates) {
|
||||||
|
echo '<rect width="25" height="10" x="' . $coordinates[0] . '" y="' . $coordinates[1] . '" rx="1" ry="1" style="stroke:black;stroke-width:3;fill:none" />';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SVG frühzeitig beenden, wenn kein Data vorhanden oder im fill-Modus
|
||||||
|
if (empty($_GET['data']) || $_GET["mode"] == "fill") {
|
||||||
|
print "</svg>";
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Brückenverbindungen übersetzen, falls aktiviert
|
||||||
|
if ($_GET["translate"] == "true") {
|
||||||
|
$db = new SQLite3('db-test/test.db');
|
||||||
|
$data = json_decode($_GET["data"], true);
|
||||||
|
$plug = json_decode(file_get_contents("settings.json"), true)["plug"];
|
||||||
|
$nodes_raw = [];
|
||||||
|
|
||||||
|
foreach ($data as $bridge) {
|
||||||
|
$nodes = $db->query("SELECT node_from, node_to FROM nodes WHERE required_by = " . $bridge);
|
||||||
|
while ($node = $nodes->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
$nodes_raw[] = [$node['node_from'], $node['node_to']];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$inputArray = $nodes_raw;
|
||||||
|
} else {
|
||||||
|
$inputArray = json_decode($_GET['data'], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Koordinaten übersetzen
|
||||||
|
$translatedArray = array_map(function ($pair) use ($pin_coordinates) {
|
||||||
|
return [
|
||||||
|
$pin_coordinates[$pair[0]],
|
||||||
|
$pin_coordinates[$pair[1]],
|
||||||
|
];
|
||||||
|
}, $inputArray);
|
||||||
|
|
||||||
|
$colors = ["#1a5fb4", "#26a269", "#e5a50a", "#c64600", "#a51d2d", "#613583", "#63452c", "#3d3846"];
|
||||||
|
|
||||||
|
// Linien ausgeben
|
||||||
|
$colorNumber = 0;
|
||||||
|
foreach ($translatedArray as $line) {
|
||||||
|
$point1 = $line[0];
|
||||||
|
$point2 = $line[1];
|
||||||
|
|
||||||
|
$point1x = $point1[0] + 10;
|
||||||
|
$point1y = $point1[1] + 5;
|
||||||
|
$point2x = $point2[0] + 10;
|
||||||
|
$point2y = $point2[1] + 5;
|
||||||
|
|
||||||
|
echo '<path d="M' . $point1x . ' ' . $point1y . ' L' . $point2x . ' ' . $point2y .
|
||||||
|
'" style="stroke:' . $colors[$colorNumber] . ';stroke-width:3; fill:none;" />';
|
||||||
|
|
||||||
|
$colorNumber = ($colorNumber + 1) % count($colors);
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</svg>
|
||||||
139
pagecontent/system.php
Executable file
139
pagecontent/system.php
Executable file
@@ -0,0 +1,139 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$view = $_GET["view"];
|
||||||
|
|
||||||
|
switch($view) {
|
||||||
|
default: // Standardseite (Übersicht)
|
||||||
|
?>
|
||||||
|
<div class="content-header">System-Aktionen</div>
|
||||||
|
<hr />
|
||||||
|
<div class="save-button" style="background-color: #ffadad" onclick="if(confirm('Das System wird heruntergefahren. Fortfahren?') == true){pageload('shutdown')}"><img src="/vendor/icons/system-shut.svg" \>Herunterfahren</div>
|
||||||
|
<div class="save-button" style="background-color: #adcfff" onclick="if(confirm('Das System wird neu gestartet. Fortfahren?') == true){pageload('reboot')}"><img src="/vendor/icons/restart.svg" \>Neu starten</div>
|
||||||
|
<div class="save-button" onclick="pageload('info'); $(this).html('<img src=\'/vendor/icons/load.gif\' \>Sammle Systeminfos...');"><img src="/vendor/icons/info-circle.svg" \>Systeminfo</div>
|
||||||
|
<div class="save-button" onclick="pageload('wifi')"><img src="/vendor/icons/wifi.svg" \>WLAN-/DHCP-Konfig anzeigen</div>
|
||||||
|
<div class="save-button" onclick="window.location.href='#selfcheck';"><img src="/vendor/icons/ecg-monitoring-icon.svg" \>Selbstdiagnose</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "info":
|
||||||
|
?>
|
||||||
|
<div class="content-header">System-Aktionen: Sys-Info</div>
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<p>Kernel-Version:</p>
|
||||||
|
<?php
|
||||||
|
$output = shell_exec('uname -r');
|
||||||
|
echo "<pre align='left'>$output</pre>";
|
||||||
|
?>
|
||||||
|
|
||||||
|
<p>Betriebssystem:</p>
|
||||||
|
<?php
|
||||||
|
$output = shell_exec('cat /etc/os-release');
|
||||||
|
echo "<pre align='left'>$output</pre>";
|
||||||
|
?>
|
||||||
|
|
||||||
|
<p>System-Uptime:</p>
|
||||||
|
<?php
|
||||||
|
$output = shell_exec('uptime -p');
|
||||||
|
echo "<pre align='left'>$output</pre>";
|
||||||
|
?>
|
||||||
|
|
||||||
|
<p>Letzter Boot:</p>
|
||||||
|
<?php
|
||||||
|
$output = shell_exec('who -b');
|
||||||
|
echo "<pre align='left'>$output</pre>";
|
||||||
|
?>
|
||||||
|
|
||||||
|
<p>CPU-Infos:</p>
|
||||||
|
<?php
|
||||||
|
$output = shell_exec('cat /proc/cpuinfo');
|
||||||
|
echo "<pre align='left'>$output</pre>";
|
||||||
|
?>
|
||||||
|
|
||||||
|
<p>Arbeitsspeicher:</p>
|
||||||
|
<?php
|
||||||
|
$output = shell_exec('free -h');
|
||||||
|
echo "<pre align='left'>$output</pre>";
|
||||||
|
?>
|
||||||
|
|
||||||
|
<p>Speicherplatz:</p>
|
||||||
|
<?php
|
||||||
|
$output = shell_exec('df -h');
|
||||||
|
echo "<pre align='left'>$output</pre>";
|
||||||
|
?>
|
||||||
|
|
||||||
|
<p>Python-Version:</p>
|
||||||
|
<?php
|
||||||
|
$output = shell_exec('python3 --version');
|
||||||
|
echo "<pre align='left'>$output</pre>";
|
||||||
|
?>
|
||||||
|
|
||||||
|
<p>Top 5 Prozesse nach CPU-Auslastung:</p>
|
||||||
|
<?php
|
||||||
|
$output = shell_exec('ps -eo pid,comm,%cpu,%mem --sort=-%cpu | head -n 6');
|
||||||
|
echo "<pre align='left'>$output</pre>";
|
||||||
|
?>
|
||||||
|
|
||||||
|
<p>CPU-Temperatur:</p>
|
||||||
|
<?php
|
||||||
|
$output = shell_exec('vcgencmd measure_temp');
|
||||||
|
echo "<pre align='left'>$output</pre>";
|
||||||
|
?>
|
||||||
|
<p>System-Uhrzeit (PHP):</p>
|
||||||
|
<?php
|
||||||
|
setlocale(LC_TIME, 'de_DE.UTF-8'); // optional für deutsche Darstellung
|
||||||
|
date_default_timezone_set("Europe/Berlin"); // falls nötig
|
||||||
|
echo "<pre align='left'>" . strftime("%A, %e. %B %Y %H:%M:%S") . "</pre>";
|
||||||
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "wifi":
|
||||||
|
?>
|
||||||
|
<div class="content-header">System-Aktionen: WLAN/DHCP</div>
|
||||||
|
<hr />
|
||||||
|
<p>Netzwerkverbindungen:</p>
|
||||||
|
<?php
|
||||||
|
$output = shell_exec('nmcli connection show');
|
||||||
|
echo "<pre align='left'>$output</pre>";
|
||||||
|
?>
|
||||||
|
<p>Verbundene Geräte:</p>
|
||||||
|
<?php
|
||||||
|
$output = shell_exec('ip neigh');
|
||||||
|
echo "<pre align='left'>$output</pre>";
|
||||||
|
?>
|
||||||
|
<p>Netzwerkschnittstellen:</p>
|
||||||
|
<?php
|
||||||
|
$output = shell_exec('nmcli device show');
|
||||||
|
echo "<pre align='left'>$output</pre>";
|
||||||
|
?>
|
||||||
|
<p>Ifconfig:</p>
|
||||||
|
<?php
|
||||||
|
$output = shell_exec('ifconfig');
|
||||||
|
echo "<pre align='left'>$output</pre>";
|
||||||
|
break;
|
||||||
|
case "reboot":
|
||||||
|
?>
|
||||||
|
<div class="content-header">System-Aktionen: Neustart</div>
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<p>Das Prüfgerät wird nun neu gestartet. Die Verbindung wird in Kürze getrennt.</p>
|
||||||
|
<p>Stellen Sie sicher, dass Sie sich im Anschluss wieder mit dem Geräte-WLAN verbinden.</p>
|
||||||
|
<?php
|
||||||
|
$output = shell_exec('sudo /sbin/reboot 2>&1');
|
||||||
|
echo "------- Fehlerprotokoll nach dieser Zeile -------<br> $output";
|
||||||
|
break;
|
||||||
|
case "shutdown":
|
||||||
|
?>
|
||||||
|
<div class="content-header">System-Aktionen: Herunterfahren</div>
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<p>Das Prüfgerät wird nun heruntergefahren. Die Verbindung wird in Kürze getrennt.</p>
|
||||||
|
<p>Auf Wiedersehen!</p>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$output = shell_exec('sudo /sbin/shutdown -h now 2>&1');
|
||||||
|
echo "------- Fehlerprotokoll nach dieser Zeile -------<br> $output";
|
||||||
|
break;
|
||||||
|
}
|
||||||
0
pagecontent/temp.json
Executable file
0
pagecontent/temp.json
Executable file
BIN
python/.plug-check.py.swp
Normal file
BIN
python/.plug-check.py.swp
Normal file
Binary file not shown.
BIN
python/.selfcheck.py.swp
Normal file
BIN
python/.selfcheck.py.swp
Normal file
Binary file not shown.
230
python/cable-check.py
Normal file
230
python/cable-check.py
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
import smbus
|
||||||
|
import time
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
|
pruefer1 = 0x20
|
||||||
|
pruefer2 = 0x21
|
||||||
|
observer1 = 0x22
|
||||||
|
observer2 = 0x23
|
||||||
|
spurkabel1 = 0x24
|
||||||
|
spurkabel2 = 0x25
|
||||||
|
|
||||||
|
adressen = [pruefer1, pruefer2, observer1, observer2, spurkabel1, spurkabel2]
|
||||||
|
|
||||||
|
IODIRA = 0x00 # Eingang / Ausgang A
|
||||||
|
IODIRB = 0x01 # Eingang / Ausgang B
|
||||||
|
GPPUA = 0x0C # Eingang / Ausgang A
|
||||||
|
GPPUB = 0x0D # Eingang / Ausgang B
|
||||||
|
GPIOA = 0x12 # GPIO A
|
||||||
|
GPIOB = 0x13 # GPIO B
|
||||||
|
|
||||||
|
array = {}
|
||||||
|
logs = {}
|
||||||
|
data = []
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Initialisiere den I2C Bus
|
||||||
|
bus = smbus.SMBus(1)
|
||||||
|
except:
|
||||||
|
logs["errorcode"] = 12
|
||||||
|
array["logs"] = logs
|
||||||
|
json_output = json.dumps(array)
|
||||||
|
print(json_output)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
def default():
|
||||||
|
|
||||||
|
#Schleife für alle Registeradressen (0x00 bis 0x15)
|
||||||
|
for register in range(0x00, 0x16):
|
||||||
|
for adresse in adressen:
|
||||||
|
#print("Setze " + str(adresse) + " in Register " + str(register) + " auf Wert 0x00")
|
||||||
|
bus.write_byte_data(adresse, register, 0x00)
|
||||||
|
|
||||||
|
|
||||||
|
#print("Hallo! Es wird damit begonnen, alle Register zurpckzusetzen...")
|
||||||
|
#Aktiviere alle Pullups und setze alle als Eingang
|
||||||
|
time.sleep(0.05)
|
||||||
|
for adresse in adressen:
|
||||||
|
bus.write_byte_data(adresse, IODIRA, 0xFF)
|
||||||
|
bus.write_byte_data(adresse, GPPUA, 0xFF)
|
||||||
|
bus.write_byte_data(adresse, IODIRB, 0xFF)
|
||||||
|
bus.write_byte_data(adresse, GPPUB, 0xFF)
|
||||||
|
|
||||||
|
#print("============= Reset erfolgreich! =============")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
try:
|
||||||
|
default()
|
||||||
|
except:
|
||||||
|
logs["errorcode"] = 11
|
||||||
|
return
|
||||||
|
for pin in range(32): # 0 bis 31
|
||||||
|
aktuellAn = pin
|
||||||
|
|
||||||
|
for adresse in adressen:
|
||||||
|
bus.write_byte_data(adresse, IODIRA, 0xFF)
|
||||||
|
bus.write_byte_data(adresse, GPPUA, 0xFF)
|
||||||
|
bus.write_byte_data(adresse, IODIRB, 0xFF)
|
||||||
|
bus.write_byte_data(adresse, GPPUB, 0xFF)
|
||||||
|
|
||||||
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
if pin < 16:
|
||||||
|
# Setze den gewählten Pin auf HIGH
|
||||||
|
if pin < 8: # Pins A0-A7
|
||||||
|
|
||||||
|
wert = 0xFF & ~(1 << pin) # Alle Bits auf 1, außer das eine gewünschte auf 0
|
||||||
|
|
||||||
|
bus.write_byte_data(pruefer1, GPPUA, wert)
|
||||||
|
bus.write_byte_data(pruefer1, IODIRA, wert)
|
||||||
|
bus.write_byte_data(pruefer1, GPIOA, 0x00)
|
||||||
|
|
||||||
|
else: # Pins B0-B7
|
||||||
|
wert = 0xFF & ~(1 << pin - 8) # Alle Bits auf 1, außer das eine gewünschte auf 0
|
||||||
|
|
||||||
|
bus.write_byte_data(pruefer1, GPPUB, wert)
|
||||||
|
bus.write_byte_data(pruefer1, IODIRB, wert)
|
||||||
|
bus.write_byte_data(pruefer1, GPIOB, 0x00)
|
||||||
|
else:
|
||||||
|
# Setze den gewählten Pin auf HIGH
|
||||||
|
if pin < 24: # Pins A0-A7
|
||||||
|
wert = 0xFF & ~(1 << pin - 16) # Alle Bits auf 1, außer das eine gewünschte auf 0
|
||||||
|
|
||||||
|
bus.write_byte_data(pruefer2, GPPUA, wert)
|
||||||
|
bus.write_byte_data(pruefer2, IODIRA, wert)
|
||||||
|
bus.write_byte_data(pruefer2, GPIOA, 0x00)
|
||||||
|
else: # Pins B0-B7
|
||||||
|
wert = 0xFF & ~(1 << pin - 24) # Alle Bits auf 1, außer das eine gewünschte auf 0
|
||||||
|
|
||||||
|
bus.write_byte_data(pruefer2, GPPUB, wert)
|
||||||
|
bus.write_byte_data(pruefer2, IODIRB, wert)
|
||||||
|
bus.write_byte_data(pruefer2, GPIOB, 0x00)
|
||||||
|
|
||||||
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
##print(f"i2cget -y 1 0x20 0x12")
|
||||||
|
pruefer1_A_value = bus.read_byte_data(pruefer1, GPIOA)
|
||||||
|
pruefer1_B_value = bus.read_byte_data(pruefer1, GPIOB)
|
||||||
|
pruefer2_A_value = bus.read_byte_data(pruefer2, GPIOA)
|
||||||
|
pruefer2_B_value = bus.read_byte_data(pruefer2, GPIOB)
|
||||||
|
|
||||||
|
observer1_A_value = bus.read_byte_data(observer1, GPIOA)
|
||||||
|
observer1_B_value = bus.read_byte_data(observer1, GPIOB)
|
||||||
|
observer2_A_value = bus.read_byte_data(observer2, GPIOA)
|
||||||
|
observer2_B_value = bus.read_byte_data(observer2, GPIOB)
|
||||||
|
|
||||||
|
spurkabel1_A_value = bus.read_byte_data(spurkabel1, GPIOA)
|
||||||
|
spurkabel1_B_value = bus.read_byte_data(spurkabel1, GPIOB)
|
||||||
|
spurkabel2_A_value = bus.read_byte_data(spurkabel2, GPIOA)
|
||||||
|
spurkabel2_B_value = bus.read_byte_data(spurkabel2, GPIOB)
|
||||||
|
|
||||||
|
#print(f"------>>>>Es konnte vom pruefer1_A_value der Wert {format(pruefer1_A_value, '08b')} festgetsellt werden")
|
||||||
|
#print(f"------>>>>Es konnte vom pruefer1_B_value der Wert {format(pruefer1_B_value, '08b')} festgetsellt werden")
|
||||||
|
#print(f"------>>>>Es konnte vom pruefer2_A_value der Wert {format(pruefer2_A_value, '08b')} festgetsellt werden")
|
||||||
|
#print(f"------>>>>Es konnte vom pruefer2_B_value der Wert {format(pruefer2_B_value, '08b')} festgetsellt werden")
|
||||||
|
|
||||||
|
#print(f"------>>>>Es konnte vom observer1_A_value der Wert {format(observer1_A_value, '08b')} festgetsellt werden")
|
||||||
|
#print(f"------>>>>Es konnte vom observer1_B_value der Wert {format(observer1_B_value, '08b')} festgetsellt werden")
|
||||||
|
#print(f"------>>>>Es konnte vom observer2_A_value der Wert {format(observer2_A_value, '08b')} festgetsellt werden")
|
||||||
|
#print(f"------>>>>Es konnte vom observer2_B_value der Wert {format(observer2_B_value, '08b')} festgetsellt werden")
|
||||||
|
|
||||||
|
#print(f"------>>>>Es konnte vom spurkabel1_A_value der Wert {format(spurkabel1_A_value, '08b')} festgetsellt werden")
|
||||||
|
#print(f"------>>>>Es konnte vom spurkabel1_B_value der Wert {format(spurkabel1_B_value, '08b')} festgetsellt werden")
|
||||||
|
#print(f"------>>>>Es konnte vom spurkabel2_A_value der Wert {format(spurkabel2_A_value, '08b')} festgetsellt werden")
|
||||||
|
#print(f"------>>>>Es konnte vom spurkabel2_B_value der Wert {format(spurkabel2_B_value, '08b')} festgetsellt werden")
|
||||||
|
|
||||||
|
#print("===========================================================================")
|
||||||
|
|
||||||
|
|
||||||
|
for j in range(8): # Verarbeite 4*8=32 Pins + Jeweils 32 Observer- und Spurkabel-Daten
|
||||||
|
bitmaske = 1 << j # Erstelle eine Maske: 1, 2, 4, 8, 16, ...
|
||||||
|
|
||||||
|
pruefer1_A_value_bit = bool(pruefer1_A_value & bitmaske)
|
||||||
|
pruefer1_B_value_bit = bool(pruefer1_B_value & bitmaske)
|
||||||
|
pruefer2_A_value_bit = bool(pruefer2_A_value & bitmaske)
|
||||||
|
pruefer2_B_value_bit = bool(pruefer2_B_value & bitmaske)
|
||||||
|
|
||||||
|
observer1_A_value_bit = bool(observer1_A_value & bitmaske)
|
||||||
|
observer1_B_value_bit = bool(observer1_B_value & bitmaske)
|
||||||
|
observer2_A_value_bit = bool(observer2_A_value & bitmaske)
|
||||||
|
observer2_B_value_bit = bool(observer2_B_value & bitmaske)
|
||||||
|
|
||||||
|
spurkabel1_A_value_bit = bool(spurkabel1_A_value & bitmaske)
|
||||||
|
spurkabel1_B_value_bit = bool(spurkabel1_B_value & bitmaske)
|
||||||
|
spurkabel2_A_value_bit = bool(spurkabel2_A_value & bitmaske)
|
||||||
|
spurkabel2_B_value_bit = bool(spurkabel2_B_value & bitmaske)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
i = j
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if spurkabel1_A_value_bit == False:
|
||||||
|
data.append([[pin ,i],0])
|
||||||
|
|
||||||
|
if pruefer1_A_value_bit == False and observer1_A_value_bit == True:
|
||||||
|
data.append([[pin ,i],2])
|
||||||
|
#print("Prüfer sagt NEIN, Observer sagt JA");
|
||||||
|
if pruefer1_A_value_bit == True and observer1_A_value_bit == False:
|
||||||
|
data.append([[pin ,i],3])
|
||||||
|
#print("Prüfer sagt JA, Observer sagt NEIN");
|
||||||
|
|
||||||
|
|
||||||
|
i = j + 8
|
||||||
|
|
||||||
|
|
||||||
|
if spurkabel1_B_value_bit == False:
|
||||||
|
data.append([[pin ,i],0])
|
||||||
|
|
||||||
|
if pruefer1_B_value_bit == False and observer1_B_value_bit == True:
|
||||||
|
data.append([[pin ,i],2])
|
||||||
|
#print("Prüfer sagt NEIN, Observer sagt JA");
|
||||||
|
if pruefer1_B_value_bit == True and observer1_B_value_bit == False:
|
||||||
|
data.append([[pin ,i],3])
|
||||||
|
#print("Prüfer sagt JA, Observer sagt NEIN");
|
||||||
|
|
||||||
|
|
||||||
|
i = j + 16
|
||||||
|
|
||||||
|
|
||||||
|
if spurkabel2_A_value_bit == False:
|
||||||
|
data.append([[pin ,i],0])
|
||||||
|
|
||||||
|
if pruefer2_A_value_bit == False and observer2_A_value_bit == True:
|
||||||
|
data.append([[pin ,i],2])
|
||||||
|
#print("Prüfer sagt NEIN, Observer sagt JA");
|
||||||
|
if pruefer2_A_value_bit == True and observer2_A_value_bit == False:
|
||||||
|
data.append([[pin ,i],3])
|
||||||
|
#print("Prüfer sagt JA, Observer sagt NEIN");
|
||||||
|
|
||||||
|
|
||||||
|
i = j + 24
|
||||||
|
|
||||||
|
if spurkabel2_B_value_bit == False:
|
||||||
|
data.append([[pin ,i],0])
|
||||||
|
|
||||||
|
if pruefer2_B_value_bit == False and observer2_B_value_bit == True:
|
||||||
|
data.append([[pin ,i],2])
|
||||||
|
#print("Prüfer sagt NEIN, Observer sagt JA");
|
||||||
|
if pruefer2_B_value_bit == True and observer2_B_value_bit == False:
|
||||||
|
data.append([[pin ,i],3])
|
||||||
|
#print("Prüfer sagt JA, Observer sagt NEIN");
|
||||||
|
|
||||||
|
logs["errorcode"] = 10
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except:
|
||||||
|
logs["errorcode"] = 13
|
||||||
|
array["logs"] = logs
|
||||||
|
array["data"] = data
|
||||||
|
json_output = json.dumps(array)
|
||||||
|
print(json_output)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
219
python/observer-full.py
Normal file
219
python/observer-full.py
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
import smbus
|
||||||
|
import time
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
|
pruefer1 = 0x20
|
||||||
|
pruefer2 = 0x21
|
||||||
|
observer1 = 0x22
|
||||||
|
observer2 = 0x23
|
||||||
|
|
||||||
|
adressen = [pruefer1, pruefer2, observer1, observer2]
|
||||||
|
|
||||||
|
IODIRA = 0x00 # Eingang / Ausgang A
|
||||||
|
IODIRB = 0x01 # Eingang / Ausgang B
|
||||||
|
GPPUA = 0x0C # Eingang / Ausgang A
|
||||||
|
GPPUB = 0x0D # Eingang / Ausgang B
|
||||||
|
GPIOA = 0x12 # GPIO A
|
||||||
|
GPIOB = 0x13 # GPIO B
|
||||||
|
|
||||||
|
array = {}
|
||||||
|
logs = {}
|
||||||
|
data = []
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Initialisiere den I2C Bus
|
||||||
|
bus = smbus.SMBus(1)
|
||||||
|
except:
|
||||||
|
logs["errorcode"] = 12
|
||||||
|
array["logs"] = logs
|
||||||
|
json_output = json.dumps(array)
|
||||||
|
print(json_output)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
def default():
|
||||||
|
|
||||||
|
#Schleife für alle Registeradressen (0x00 bis 0x15)
|
||||||
|
for register in range(0x00, 0x16):
|
||||||
|
for adresse in adressen:
|
||||||
|
#print("Setze " + str(adresse) + " in Register " + str(register) + " auf Wert 0x00")
|
||||||
|
bus.write_byte_data(adresse, register, 0x00)
|
||||||
|
|
||||||
|
|
||||||
|
#print("Hallo! Es wird damit begonnen, alle Register zurpckzusetzen...")
|
||||||
|
#Aktiviere alle Pullups und setze alle als Eingang
|
||||||
|
time.sleep(0.05)
|
||||||
|
for adresse in adressen:
|
||||||
|
bus.write_byte_data(adresse, IODIRA, 0xFF)
|
||||||
|
bus.write_byte_data(adresse, GPPUA, 0xFF)
|
||||||
|
bus.write_byte_data(adresse, IODIRB, 0xFF)
|
||||||
|
bus.write_byte_data(adresse, GPPUB, 0xFF)
|
||||||
|
|
||||||
|
#print("============= Reset erfolgreich! =============")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
try:
|
||||||
|
default()
|
||||||
|
except:
|
||||||
|
logs["errorcode"] = 11
|
||||||
|
return
|
||||||
|
time.sleep(0.05)
|
||||||
|
for pin in range(32): # 0 bis 31
|
||||||
|
aktuellAn = pin
|
||||||
|
|
||||||
|
for adresse in adressen:
|
||||||
|
bus.write_byte_data(adresse, IODIRA, 0xFF)
|
||||||
|
bus.write_byte_data(adresse, GPPUA, 0xFF)
|
||||||
|
bus.write_byte_data(adresse, IODIRB, 0xFF)
|
||||||
|
bus.write_byte_data(adresse, GPPUB, 0xFF)
|
||||||
|
|
||||||
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
if pin < 16:
|
||||||
|
# Setze den gewählten Pin auf HIGH
|
||||||
|
if pin < 8: # Pins A0-A7
|
||||||
|
|
||||||
|
wert = 0xFF & ~(1 << pin) # Alle Bits auf 1, außer das eine gewünschte auf 0
|
||||||
|
|
||||||
|
bus.write_byte_data(pruefer1, GPPUA, wert)
|
||||||
|
bus.write_byte_data(pruefer1, IODIRA, wert)
|
||||||
|
bus.write_byte_data(pruefer1, GPIOA, 0x00)
|
||||||
|
|
||||||
|
else: # Pins B0-B7
|
||||||
|
wert = 0xFF & ~(1 << pin - 8) # Alle Bits auf 1, außer das eine gewünschte auf 0
|
||||||
|
|
||||||
|
bus.write_byte_data(pruefer1, GPPUB, wert)
|
||||||
|
bus.write_byte_data(pruefer1, IODIRB, wert)
|
||||||
|
bus.write_byte_data(pruefer1, GPIOB, 0x00)
|
||||||
|
else:
|
||||||
|
# Setze den gewählten Pin auf HIGH
|
||||||
|
if pin < 24: # Pins A0-A7
|
||||||
|
wert = 0xFF & ~(1 << pin - 16) # Alle Bits auf 1, außer das eine gewünschte auf 0
|
||||||
|
|
||||||
|
bus.write_byte_data(pruefer2, GPPUA, wert)
|
||||||
|
bus.write_byte_data(pruefer2, IODIRA, wert)
|
||||||
|
bus.write_byte_data(pruefer2, GPIOA, 0x00)
|
||||||
|
else: # Pins B0-B7
|
||||||
|
wert = 0xFF & ~(1 << pin - 24) # Alle Bits auf 1, außer das eine gewünschte auf 0
|
||||||
|
|
||||||
|
bus.write_byte_data(pruefer2, GPPUB, wert)
|
||||||
|
bus.write_byte_data(pruefer2, IODIRB, wert)
|
||||||
|
bus.write_byte_data(pruefer2, GPIOB, 0x00)
|
||||||
|
|
||||||
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
##print(f"i2cget -y 1 0x20 0x12")
|
||||||
|
pruefer1_A_value = bus.read_byte_data(pruefer1, GPIOA)
|
||||||
|
pruefer1_B_value = bus.read_byte_data(pruefer1, GPIOB)
|
||||||
|
pruefer2_A_value = bus.read_byte_data(pruefer2, GPIOA)
|
||||||
|
pruefer2_B_value = bus.read_byte_data(pruefer2, GPIOB)
|
||||||
|
|
||||||
|
observer1_A_value = bus.read_byte_data(observer1, GPIOA)
|
||||||
|
observer1_B_value = bus.read_byte_data(observer1, GPIOB)
|
||||||
|
observer2_A_value = bus.read_byte_data(observer2, GPIOA)
|
||||||
|
observer2_B_value = bus.read_byte_data(observer2, GPIOB)
|
||||||
|
|
||||||
|
#print(f"------>>>>Es konnte vom Pruefer der Wert {format(Wert_pruefer, '08b')} festgetsellt werden")
|
||||||
|
#print(f"------>>>>Es konnte vom Observer der Wert {format(Wert_observer, '08b')} festgetsellt werden")
|
||||||
|
|
||||||
|
|
||||||
|
for j in range(8): # Verarbeite 4*8=32 Pins + Jeweils 32 Observer-Daten
|
||||||
|
bitmaske = 1 << j # Erstelle eine Maske: 1, 2, 4, 8, 16, ...
|
||||||
|
|
||||||
|
pruefer1_A_value_bit = bool(pruefer1_A_value & bitmaske)
|
||||||
|
pruefer1_B_value_bit = bool(pruefer1_B_value & bitmaske)
|
||||||
|
pruefer2_A_value_bit = bool(pruefer2_A_value & bitmaske)
|
||||||
|
pruefer2_B_value_bit = bool(pruefer2_B_value & bitmaske)
|
||||||
|
|
||||||
|
observer1_A_value_bit = bool(observer1_A_value & bitmaske)
|
||||||
|
observer1_B_value_bit = bool(observer1_B_value & bitmaske)
|
||||||
|
observer2_A_value_bit = bool(observer2_A_value & bitmaske)
|
||||||
|
observer2_B_value_bit = bool(observer2_B_value & bitmaske)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
i = j
|
||||||
|
|
||||||
|
if pruefer1_A_value_bit == False and i != pin:
|
||||||
|
#print("Gefunden: " + str(pin) + " <> " + str(j));
|
||||||
|
if observer1_A_value_bit == False:
|
||||||
|
#print("Dies wurde vom Observer bestätigt!");
|
||||||
|
data.append([[pin ,i],0])
|
||||||
|
else:
|
||||||
|
#print("Konnte NICHT bestätigen!");
|
||||||
|
data.append([[pin ,i],1])
|
||||||
|
if pruefer1_A_value_bit == False and observer1_A_value_bit == True:
|
||||||
|
data.append([[pin ,i],2])
|
||||||
|
#print("Prüfer sagt NEIN, Observer sagt JA");
|
||||||
|
if pruefer1_A_value_bit == True and observer1_A_value_bit == False:
|
||||||
|
data.append([[pin ,i],3])
|
||||||
|
#print("Prüfer sagt JA, Observer sagt NEIN");
|
||||||
|
|
||||||
|
|
||||||
|
i = j + 8
|
||||||
|
|
||||||
|
if pruefer1_B_value_bit == False and i != pin:
|
||||||
|
#print("Gefunden: " + str(pin) + " <> " + str(j));
|
||||||
|
if observer1_B_value_bit == False:
|
||||||
|
#print("Dies wurde vom Observer bestätigt!");
|
||||||
|
data.append([[pin ,i],0])
|
||||||
|
else:
|
||||||
|
#print("Konnte NICHT bestätigen!");
|
||||||
|
data.append([[pin ,i],1])
|
||||||
|
if pruefer1_B_value_bit == False and observer1_B_value_bit == True:
|
||||||
|
data.append([[pin ,i],2])
|
||||||
|
#print("Prüfer sagt NEIN, Observer sagt JA");
|
||||||
|
if pruefer1_B_value_bit == True and observer1_B_value_bit == False:
|
||||||
|
data.append([[pin ,i],3])
|
||||||
|
#print("Prüfer sagt JA, Observer sagt NEIN");
|
||||||
|
|
||||||
|
i = j + 16
|
||||||
|
|
||||||
|
if pruefer2_A_value_bit == False and i != pin:
|
||||||
|
#print("Gefunden: " + str(pin) + " <> " + str(j));
|
||||||
|
if observer2_A_value_bit == False:
|
||||||
|
#print("Dies wurde vom Observer bestätigt!");
|
||||||
|
data.append([[pin ,i],0])
|
||||||
|
else:
|
||||||
|
#print("Konnte NICHT bestätigen!");
|
||||||
|
data.append([[pin ,i],1])
|
||||||
|
if pruefer2_A_value_bit == False and observer2_A_value_bit == True:
|
||||||
|
data.append([[pin ,i],2])
|
||||||
|
#print("Prüfer sagt NEIN, Observer sagt JA");
|
||||||
|
if pruefer2_A_value_bit == True and observer2_A_value_bit == False:
|
||||||
|
data.append([[pin ,i],3])
|
||||||
|
#print("Prüfer sagt JA, Observer sagt NEIN");
|
||||||
|
|
||||||
|
i = j + 24
|
||||||
|
|
||||||
|
if pruefer2_B_value_bit == False and i != pin:
|
||||||
|
#print("Gefunden: " + str(pin) + " <> " + str(j));
|
||||||
|
if observer2_B_value_bit == False:
|
||||||
|
#print("Dies wurde vom Observer bestätigt!");
|
||||||
|
data.append([[pin ,i],0])
|
||||||
|
else:
|
||||||
|
#print("Konnte NICHT bestätigen!");
|
||||||
|
data.append([[pin ,i],1])
|
||||||
|
if pruefer2_B_value_bit == False and observer2_B_value_bit == True:
|
||||||
|
data.append([[pin ,i],2])
|
||||||
|
#print("Prüfer sagt NEIN, Observer sagt JA");
|
||||||
|
if pruefer2_B_value_bit == True and observer2_B_value_bit == False:
|
||||||
|
data.append([[pin ,i],3])
|
||||||
|
#print("Prüfer sagt JA, Observer sagt NEIN");
|
||||||
|
|
||||||
|
logs["errorcode"] = 10
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except:
|
||||||
|
logs["errorcode"] = 13
|
||||||
|
array["logs"] = logs
|
||||||
|
array["data"] = data
|
||||||
|
json_output = json.dumps(array)
|
||||||
|
print(json_output)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
127
python/observer.py
Normal file
127
python/observer.py
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
import smbus
|
||||||
|
import time
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
|
pruefer = 0x20
|
||||||
|
observer = 0x22
|
||||||
|
|
||||||
|
|
||||||
|
IODIRA = 0x00 # Eingang / Ausgang A
|
||||||
|
IODIRB = 0x01 # Eingang / Ausgang B
|
||||||
|
GPPUA = 0x0C # Eingang / Ausgang A
|
||||||
|
GPPUB = 0x0D # Eingang / Ausgang B
|
||||||
|
GPIOA = 0x12 # GPIO A
|
||||||
|
GPIOB = 0x13 # GPIO B
|
||||||
|
|
||||||
|
array = {}
|
||||||
|
logs = {}
|
||||||
|
data = []
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Initialisiere den I2C Bus
|
||||||
|
bus = smbus.SMBus(1)
|
||||||
|
except:
|
||||||
|
logs["errorcode"] = 12
|
||||||
|
array["logs"] = logs
|
||||||
|
json_output = json.dumps(array)
|
||||||
|
print(json_output)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def default():
|
||||||
|
#adressen = [pruefer]
|
||||||
|
|
||||||
|
# Schleife für alle Registeradressen (0x00 bis 0x15)
|
||||||
|
#for register in range(0x00, 0x16):
|
||||||
|
# for adresse in adressen:
|
||||||
|
# time.sleep(0.05)
|
||||||
|
# #print("Setze " + str(adresse) + " in Register " + str(register) + " auf Wert 0x00")
|
||||||
|
# bus.write_byte_data(adresse, register, 0x00)
|
||||||
|
|
||||||
|
|
||||||
|
#print("Hallo! Es wird damit begonnen, alle Register zurpckzusetzen...")
|
||||||
|
time.sleep(0.05)
|
||||||
|
bus.write_byte_data(pruefer, IODIRA, 0xFF)
|
||||||
|
bus.write_byte_data(observer, IODIRA, 0xFF)
|
||||||
|
|
||||||
|
bus.write_byte_data(pruefer, GPPUA, 0xFF)
|
||||||
|
bus.write_byte_data(observer, GPPUA, 0xFF)
|
||||||
|
#print("============= Reset erfolgreich! =============")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
try:
|
||||||
|
default()
|
||||||
|
except:
|
||||||
|
logs["errorcode"] = 11
|
||||||
|
return
|
||||||
|
time.sleep(0.05)
|
||||||
|
for pin in range(8): # 0 bis 7
|
||||||
|
wert = 0xFF & ~(1 << pin) # Alle Bits auf 1, außer das eine gewünschte auf 0
|
||||||
|
#print("======== Setze Pin " + str(pin) + " auf den Wert " + format(wert, '08b'));
|
||||||
|
|
||||||
|
|
||||||
|
bus.write_byte_data(pruefer, GPPUA, wert)
|
||||||
|
bus.write_byte_data(pruefer, IODIRA, wert) # Setze einzeln als Ausgang 111011111 usw...
|
||||||
|
bus.write_byte_data(pruefer, GPIOA, 0x00) # Deaktiviere alle pins (es reagiert sowieso nur der Ausgang, dh keine Bitmaske erforderlich) 00000000 usw..
|
||||||
|
|
||||||
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
##print(f"i2cget -y 1 0x20 0x12")
|
||||||
|
Wert_pruefer = bus.read_byte_data(pruefer, GPIOA)
|
||||||
|
Wert_observer = bus.read_byte_data(observer, GPIOA)
|
||||||
|
|
||||||
|
#print(f"------>>>>Es konnte vom Pruefer der Wert {format(Wert_pruefer, '08b')} festgetsellt werden")
|
||||||
|
#print(f"------>>>>Es konnte vom Observer der Wert {format(Wert_observer, '08b')} festgetsellt werden")
|
||||||
|
|
||||||
|
ok = 0
|
||||||
|
|
||||||
|
for j in range(8): # Lese 4*8=32 Pins
|
||||||
|
bitmaske = 1 << j # Erstelle eine Maske: 1, 2, 4, 8, 16, ...
|
||||||
|
|
||||||
|
Bit_pruefer = bool(Wert_pruefer & bitmaske)
|
||||||
|
Bit_observer = bool(Wert_observer & bitmaske)
|
||||||
|
|
||||||
|
if Bit_observer == False: # Prüfe, ob aktueller Pin wirklich 0 sein darf
|
||||||
|
if j == pin:
|
||||||
|
ok = 1
|
||||||
|
if Bit_pruefer == False and j != pin:
|
||||||
|
#print("Gefunden: " + str(pin) + " <> " + str(j));
|
||||||
|
if Bit_observer == False:
|
||||||
|
#print("Dies wurde vom Observer bestätigt!");
|
||||||
|
data.append([[pin ,j],0])
|
||||||
|
else:
|
||||||
|
#print("Konnte NICHT bestätigen!");
|
||||||
|
data.append([[pin ,j],1])
|
||||||
|
if Bit_pruefer == False and Bit_observer == True:
|
||||||
|
data.append([[pin ,j],2])
|
||||||
|
#print("Prüfer sagt NEIN, Observer sagt JA");
|
||||||
|
if Bit_pruefer == True and Bit_observer == False:
|
||||||
|
data.append([[pin ,j],3])
|
||||||
|
#print("Prüfer sagt JA, Observer sagt NEIN");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if ok != 1:
|
||||||
|
#print("Fehler beim Aufruf von Pin " + str(pin) + "! Es konnte nicht bestätigt werden, dass dieser Pin tatsächlich LOW ist!");
|
||||||
|
data.append([[pin ,"???"],4])
|
||||||
|
|
||||||
|
logs["errorcode"] = 10
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except:
|
||||||
|
logs["errorcode"] = 13
|
||||||
|
array["logs"] = logs
|
||||||
|
array["data"] = data
|
||||||
|
json_output = json.dumps(array)
|
||||||
|
print(json_output)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
165
python/plug-check.py
Normal file
165
python/plug-check.py
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
import smbus
|
||||||
|
import time
|
||||||
|
import json
|
||||||
|
|
||||||
|
# Adressen der beiden MCP23017 Chips
|
||||||
|
AusgangRechts = 0x20 # Ausgang rechte Hälfte
|
||||||
|
AusgangLinks = 0x21 # Ausgang linke Hälfte
|
||||||
|
EingangRechts = 0x24 # Eingang rechte Hälfte
|
||||||
|
EingangLinks = 0x23 # Eingang linke Hälfte
|
||||||
|
|
||||||
|
# Register-Adressen für den MCP23017
|
||||||
|
IODIRA = 0x00 # Eingang / Ausgang A
|
||||||
|
IODIRB = 0x01 # Eingang / Ausgang B
|
||||||
|
GPIOA = 0x12 # GPIO A
|
||||||
|
GPIOB = 0x13 # GPIO B
|
||||||
|
|
||||||
|
# Initialisiere den I2C Bus
|
||||||
|
bus = smbus.SMBus(1)
|
||||||
|
|
||||||
|
RechtsA_ausgang = ["Z", "AA", "W", "AB", "AC", "AD", "AE", "AF"]
|
||||||
|
RechtsB_ausgang = ["Q", "U", "V", "T", "S", "R", "Y", "X"]
|
||||||
|
|
||||||
|
RechtsA_eingang = ["R", "T", "V", "X", "Z", "AB", "AD", "AE"]
|
||||||
|
RechtsB_eingang = ["Q", "S", "W", "U", "AA", "Y", "AC", "AF"]
|
||||||
|
|
||||||
|
LinksA_ausgang = ["C", "D", "E", "J", "F", "G", "H", "I"]
|
||||||
|
LinksB_ausgang = ["A", "B", "P", "O", "K", "L", "M", "N"]
|
||||||
|
|
||||||
|
LinksA_eingang = ["B", "D", "F", "H", "J", "K", "M", "I"]
|
||||||
|
LinksB_eingang = ["A", "C", "E", "G", "L", "N", "O", "P"]
|
||||||
|
|
||||||
|
|
||||||
|
array = []
|
||||||
|
|
||||||
|
def default():
|
||||||
|
adressen = [AusgangRechts, AusgangLinks, EingangRechts, EingangLinks]
|
||||||
|
|
||||||
|
# Schleife für alle Registeradressen (0x00 bis 0x15)
|
||||||
|
for register in range(0x00, 0x16):
|
||||||
|
for adresse in adressen:
|
||||||
|
time.sleep(0.05)
|
||||||
|
print("Setze " + str(adresse) + " in Register " + str(register) + " auf Wert 0x00")
|
||||||
|
bus.write_byte_data(adresse, register, 0x00)
|
||||||
|
|
||||||
|
# Konfiguriere alle Pins auf Chip 1 als Ausgang (A und B)
|
||||||
|
def configure_chip1_as_output():
|
||||||
|
bus.write_byte_data(AusgangRechts, IODIRA, 0x00) # Setze alle Pins von A als Ausgang
|
||||||
|
bus.write_byte_data(AusgangRechts, IODIRB, 0x00) # Setze alle Pins von B als Ausgang
|
||||||
|
|
||||||
|
bus.write_byte_data(AusgangLinks, IODIRA, 0x00) # Setze alle Pins von A als Ausgang
|
||||||
|
bus.write_byte_data(AusgangLinks, IODIRB, 0x00) # Setze alle Pins von B als Ausgang
|
||||||
|
|
||||||
|
# Konfiguriere alle Pins auf Chip 2 als Eingang (A und B)
|
||||||
|
def configure_chip2_as_input():
|
||||||
|
bus.write_byte_data(EingangRechts, IODIRA, 0xFF) # Setze alle Pins von A als Eingang
|
||||||
|
bus.write_byte_data(EingangRechts, IODIRB, 0xFF) # Setze alle Pins von B als Eingang
|
||||||
|
|
||||||
|
bus.write_byte_data(EingangLinks, IODIRA, 0xFF) # Setze alle Pins von A als Eingang
|
||||||
|
bus.write_byte_data(EingangLinks, IODIRB, 0xFF) # Setze alle Pins von B als Eingang
|
||||||
|
|
||||||
|
|
||||||
|
# Hauptprogramm
|
||||||
|
def main():
|
||||||
|
default()
|
||||||
|
time.sleep(0.05)
|
||||||
|
configure_chip1_as_output()
|
||||||
|
time.sleep(0.05)
|
||||||
|
configure_chip2_as_input()
|
||||||
|
|
||||||
|
# Teste alle Pins auf Chip 1 (A0-A7, B0-B7)
|
||||||
|
for pin in range(32): # 0 bis 31
|
||||||
|
#print(f"Setze Pin {pin} auf HIGH auf Chip 1")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print("setze AusgangRechts GPIOA")
|
||||||
|
bus.write_byte_data(AusgangRechts, GPIOA, 0x00)
|
||||||
|
print("setze AusgangRechts GPIOB")
|
||||||
|
bus.write_byte_data(AusgangRechts, GPIOB, 0x00)
|
||||||
|
|
||||||
|
print("setze AusgangLinks GPIOA")
|
||||||
|
bus.write_byte_data(AusgangLinks, GPIOA, 0x00)
|
||||||
|
print("setze AusgangLinks GPIOB")
|
||||||
|
bus.write_byte_data(AusgangLinks, GPIOB, 0x00)
|
||||||
|
|
||||||
|
|
||||||
|
if pin < 16:
|
||||||
|
# Setze den gewählten Pin auf HIGH
|
||||||
|
if pin < 8: # Pins A0-A7
|
||||||
|
print("setze RechtsA_ausgang" + RechtsA_ausgang[pin])
|
||||||
|
bus.write_byte_data(AusgangRechts, GPIOA, 1 << pin)
|
||||||
|
|
||||||
|
aktuellAn = RechtsA_ausgang[pin]
|
||||||
|
else: # Pins B0-B7
|
||||||
|
print("setze RechtsB_ausgang" + RechtsB_ausgang[pin-8])
|
||||||
|
bus.write_byte_data(AusgangRechts, GPIOB, 1 << (pin - 8))
|
||||||
|
aktuellAn = RechtsB_ausgang[pin - 8]
|
||||||
|
else:
|
||||||
|
# Setze den gewählten Pin auf HIGH
|
||||||
|
if pin < 24: # Pins A0-A7
|
||||||
|
print("setze LinksA_ausgang" + LinksA_ausgang[pin-16])
|
||||||
|
bus.write_byte_data(AusgangLinks, GPIOA, 1 << pin - 16)
|
||||||
|
aktuellAn = LinksA_ausgang[pin - 16]
|
||||||
|
else: # Pins B0-B7
|
||||||
|
print("setze LinksB_ausgang" + LinksB_ausgang[pin-24])
|
||||||
|
bus.write_byte_data(AusgangLinks, GPIOB, 1 << (pin - 24))
|
||||||
|
aktuellAn = LinksB_ausgang[pin - 24]
|
||||||
|
|
||||||
|
print("====================" + aktuellAn + "==========================")
|
||||||
|
|
||||||
|
time.sleep(0.2) # Kurze Pause, damit die Änderung sichtbar wird
|
||||||
|
|
||||||
|
print("Lese Wert_Rechts_A")
|
||||||
|
Wert_Rechts_A = bus.read_byte_data(EingangRechts, GPIOA)
|
||||||
|
print(Wert_Rechts_A)
|
||||||
|
print("Lese Wert_Links_A")
|
||||||
|
Wert_Links_A = bus.read_byte_data(EingangLinks, GPIOA)
|
||||||
|
print(Wert_Links_A)
|
||||||
|
|
||||||
|
print("Lese Wert_Rechts_B")
|
||||||
|
Wert_Rechts_B = bus.read_byte_data(EingangRechts, GPIOB)
|
||||||
|
print(Wert_Rechts_B)
|
||||||
|
print("Lese Wert_Links_B")
|
||||||
|
Wert_Links_B = bus.read_byte_data(EingangLinks, GPIOB)
|
||||||
|
print(Wert_Links_B)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for j in range(8): # Lese 4*8=32 Pins
|
||||||
|
bitmaske = 1 << j # Erstelle eine Maske: 1, 2, 4, 8, 16, ...
|
||||||
|
|
||||||
|
Bit_Rechts_A = bool(Wert_Rechts_A & bitmaske) # Isoliere das entsprechende Bit
|
||||||
|
Bit_Links_A = bool(Wert_Links_A & bitmaske) # Isoliere das entsprechende Bit
|
||||||
|
Bit_Rechts_B = bool(Wert_Rechts_B & bitmaske) # Isoliere das entsprechende Bit
|
||||||
|
Bit_Links_B = bool(Wert_Links_B & bitmaske) # Isoliere das entsprechende Bit
|
||||||
|
|
||||||
|
if Bit_Rechts_A == True:
|
||||||
|
if aktuellAn != RechtsA_eingang[j]:
|
||||||
|
array.append([aktuellAn ,RechtsA_eingang[j]])
|
||||||
|
print("Gefunden: " + RechtsA_eingang[j])
|
||||||
|
|
||||||
|
if Bit_Links_A == True:
|
||||||
|
if aktuellAn != LinksA_eingang[j]:
|
||||||
|
array.append([aktuellAn ,LinksA_eingang[j]])
|
||||||
|
print("Gefunden: " + LinksA_eingang[j])
|
||||||
|
|
||||||
|
if Bit_Rechts_B == True:
|
||||||
|
if aktuellAn != RechtsB_eingang[j]:
|
||||||
|
array.append([aktuellAn ,RechtsB_eingang[j]])
|
||||||
|
print("Gefunden: " + RechtsB_eingang[j])
|
||||||
|
|
||||||
|
if Bit_Links_B == True:
|
||||||
|
if aktuellAn != LinksB_eingang[j]:
|
||||||
|
array.append([aktuellAn ,LinksB_eingang[j]])
|
||||||
|
print("Gefunden: " + LinksB_eingang[j])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
json_output = json.dumps(array)
|
||||||
|
print(json_output)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
||||||
75
python/plug-check_external-pulldown.py
Normal file
75
python/plug-check_external-pulldown.py
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
import smbus
|
||||||
|
import time
|
||||||
|
import json
|
||||||
|
|
||||||
|
# Adressen der beiden MCP23017 Chips
|
||||||
|
MP = 0x20 # Ausgang rechte Hälfte
|
||||||
|
|
||||||
|
|
||||||
|
# Register-Adressen für den MCP23017
|
||||||
|
IODIRA = 0x00 # Eingang / Ausgang A
|
||||||
|
IODIRB = 0x01 # Eingang / Ausgang B
|
||||||
|
GPIOA = 0x12 # GPIO A
|
||||||
|
GPIOB = 0x13 # GPIO B
|
||||||
|
|
||||||
|
# Initialisiere den I2C Bus
|
||||||
|
bus = smbus.SMBus(1)
|
||||||
|
|
||||||
|
|
||||||
|
def default():
|
||||||
|
# Schleife für alle Registeradressen (0x00 bis 0x15)
|
||||||
|
for register in range(0x00, 0x16):
|
||||||
|
bus.write_byte_data(MP, register, 0x00)
|
||||||
|
|
||||||
|
# Konfiguriere alle Pins auf Chip 1 als Ausgang (A und B)
|
||||||
|
def configure_chip1_as_output():
|
||||||
|
bus.write_byte_data(MP, IODIRA, 0x00) # Setze alle Pins von A als Ausgang
|
||||||
|
bus.write_byte_data(MP, IODIRB, 0x00) # Setze alle Pins von B als Ausgang
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Hauptprogramm
|
||||||
|
def main():
|
||||||
|
default()
|
||||||
|
time.sleep(0.5)
|
||||||
|
configure_chip1_as_output()
|
||||||
|
|
||||||
|
# Teste alle Pins auf Chip 1 (A0-A7, B0-B7)
|
||||||
|
for pin in range(32): # 0 bis 31
|
||||||
|
#print(f"Setze Pin {pin} auf HIGH auf Chip 1")
|
||||||
|
|
||||||
|
|
||||||
|
bus.write_byte_data(MP, GPIOA, 0x00)
|
||||||
|
|
||||||
|
|
||||||
|
if pin < 16:
|
||||||
|
# Setze den gewählten Pin auf HIGH
|
||||||
|
if pin < 8: # Pins A0-
|
||||||
|
|
||||||
|
bus.write_byte_data(MP, IODIRA, ~(1 << pin))
|
||||||
|
|
||||||
|
bus.write_byte_data(MP, GPIOA, 1 << pin)
|
||||||
|
|
||||||
|
|
||||||
|
print("====================" + str(pin) + "==========================")
|
||||||
|
|
||||||
|
time.sleep(0.2) # Kurze Pause, damit die Änderung sichtbar wird
|
||||||
|
|
||||||
|
wert = bus.read_byte_data(MP, GPIOA)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for j in range(8): # Lese 4*8=32 Pins
|
||||||
|
bitmaske = 1 << j # Erstelle eine Maske: 1, 2, 4, 8, 16, ...
|
||||||
|
|
||||||
|
wert_bitweise = bool(wert & bitmaske) # Isoliere das entsprechende Bit
|
||||||
|
|
||||||
|
|
||||||
|
if wert_bitweise == True:
|
||||||
|
print("Gefunden: " + str(j))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
||||||
53
python/plug-check_internal-pullup.py
Normal file
53
python/plug-check_internal-pullup.py
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import smbus
|
||||||
|
import time
|
||||||
|
import json
|
||||||
|
|
||||||
|
# Adressen der beiden MCP23017 Chips
|
||||||
|
MP = 0x20 # Ausgang rechte Hälfte
|
||||||
|
|
||||||
|
|
||||||
|
# Register-Adressen für den MCP23017
|
||||||
|
IODIRA = 0x00 # Eingang / Ausgang A
|
||||||
|
IODIRB = 0x01 # Eingang / Ausgang B
|
||||||
|
GPIOA = 0x12 # GPIO A
|
||||||
|
GPIOB = 0x13 # GPIO B
|
||||||
|
|
||||||
|
PULLUPA = 0x0C
|
||||||
|
PULLUPB = 0x0D
|
||||||
|
|
||||||
|
# Initialisiere den I2C Bus
|
||||||
|
bus = smbus.SMBus(1)
|
||||||
|
|
||||||
|
# Hauptprogramm
|
||||||
|
def main():
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
for pin in range(8):
|
||||||
|
|
||||||
|
|
||||||
|
bus.write_byte_data(MP, IODIRA, ~(1 << pin))
|
||||||
|
time.sleep(0.02)
|
||||||
|
bus.write_byte_data(MP, PULLUPA, ~(1 << pin))
|
||||||
|
time.sleep(0.02)
|
||||||
|
|
||||||
|
bus.write_byte_data(MP, GPIOA, ~(1 << pin))
|
||||||
|
time.sleep(0.02)
|
||||||
|
|
||||||
|
|
||||||
|
print("====================" + str(pin) + "==========================")
|
||||||
|
|
||||||
|
wert = bus.read_byte_data(MP, GPIOA)
|
||||||
|
|
||||||
|
for j in range(8): # Lese 4*8=32 Pins
|
||||||
|
bitmaske = 1 << j
|
||||||
|
|
||||||
|
wert_bitweise = bool(wert & bitmaske)
|
||||||
|
|
||||||
|
if wert_bitweise == False and j != pin:
|
||||||
|
print(str(j))
|
||||||
|
|
||||||
|
time.sleep(0.02) # Kurze Pause, damit die Änderung sichtbar wird
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
219
python/selfcheck.py
Normal file
219
python/selfcheck.py
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
import smbus
|
||||||
|
import time
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
|
pruefer1 = 0x20
|
||||||
|
pruefer2 = 0x21
|
||||||
|
observer1 = 0x22
|
||||||
|
observer2 = 0x23
|
||||||
|
|
||||||
|
adressen = [pruefer1, pruefer2, observer1, observer2]
|
||||||
|
|
||||||
|
IODIRA = 0x00 # Eingang / Ausgang A
|
||||||
|
IODIRB = 0x01 # Eingang / Ausgang B
|
||||||
|
GPPUA = 0x0C # Eingang / Ausgang A
|
||||||
|
GPPUB = 0x0D # Eingang / Ausgang B
|
||||||
|
GPIOA = 0x12 # GPIO A
|
||||||
|
GPIOB = 0x13 # GPIO B
|
||||||
|
|
||||||
|
array = {}
|
||||||
|
logs = {}
|
||||||
|
data = []
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Initialisiere den I2C Bus
|
||||||
|
bus = smbus.SMBus(1)
|
||||||
|
except:
|
||||||
|
logs["errorcode"] = 12
|
||||||
|
array["logs"] = logs
|
||||||
|
json_output = json.dumps(array)
|
||||||
|
print(json_output)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
def default():
|
||||||
|
|
||||||
|
#Schleife für alle Registeradressen (0x00 bis 0x15)
|
||||||
|
for register in range(0x00, 0x16):
|
||||||
|
for adresse in adressen:
|
||||||
|
#print("Setze " + str(adresse) + " in Register " + str(register) + " auf Wert 0x00")
|
||||||
|
bus.write_byte_data(adresse, register, 0x00)
|
||||||
|
|
||||||
|
|
||||||
|
#print("Hallo! Es wird damit begonnen, alle Register zurpckzusetzen...")
|
||||||
|
#Aktiviere alle Pullups und setze alle als Eingang
|
||||||
|
time.sleep(0.05)
|
||||||
|
for adresse in adressen:
|
||||||
|
bus.write_byte_data(adresse, IODIRA, 0xFF)
|
||||||
|
bus.write_byte_data(adresse, GPPUA, 0xFF)
|
||||||
|
bus.write_byte_data(adresse, IODIRB, 0xFF)
|
||||||
|
bus.write_byte_data(adresse, GPPUB, 0xFF)
|
||||||
|
|
||||||
|
#print("============= Reset erfolgreich! =============")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
try:
|
||||||
|
default()
|
||||||
|
except:
|
||||||
|
logs["errorcode"] = 11
|
||||||
|
return
|
||||||
|
time.sleep(0.05)
|
||||||
|
for pin in range(32): # 0 bis 31
|
||||||
|
aktuellAn = pin
|
||||||
|
|
||||||
|
for adresse in adressen:
|
||||||
|
bus.write_byte_data(adresse, IODIRA, 0xFF)
|
||||||
|
bus.write_byte_data(adresse, GPPUA, 0xFF)
|
||||||
|
bus.write_byte_data(adresse, IODIRB, 0xFF)
|
||||||
|
bus.write_byte_data(adresse, GPPUB, 0xFF)
|
||||||
|
|
||||||
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
if pin < 16:
|
||||||
|
# Setze den gewählten Pin auf HIGH
|
||||||
|
if pin < 8: # Pins A0-A7
|
||||||
|
|
||||||
|
wert = 0xFF & ~(1 << pin) # Alle Bits auf 1, außer das eine gewünschte auf 0
|
||||||
|
|
||||||
|
bus.write_byte_data(pruefer1, GPPUA, wert)
|
||||||
|
bus.write_byte_data(pruefer1, IODIRA, wert)
|
||||||
|
bus.write_byte_data(pruefer1, GPIOA, 0x00)
|
||||||
|
|
||||||
|
else: # Pins B0-B7
|
||||||
|
wert = 0xFF & ~(1 << pin - 8) # Alle Bits auf 1, außer das eine gewünschte auf 0
|
||||||
|
|
||||||
|
bus.write_byte_data(pruefer1, GPPUB, wert)
|
||||||
|
bus.write_byte_data(pruefer1, IODIRB, wert)
|
||||||
|
bus.write_byte_data(pruefer1, GPIOB, 0x00)
|
||||||
|
else:
|
||||||
|
# Setze den gewählten Pin auf HIGH
|
||||||
|
if pin < 24: # Pins A0-A7
|
||||||
|
wert = 0xFF & ~(1 << pin - 16) # Alle Bits auf 1, außer das eine gewünschte auf 0
|
||||||
|
|
||||||
|
bus.write_byte_data(pruefer2, GPPUA, wert)
|
||||||
|
bus.write_byte_data(pruefer2, IODIRA, wert)
|
||||||
|
bus.write_byte_data(pruefer2, GPIOA, 0x00)
|
||||||
|
else: # Pins B0-B7
|
||||||
|
wert = 0xFF & ~(1 << pin - 24) # Alle Bits auf 1, außer das eine gewünschte auf 0
|
||||||
|
|
||||||
|
bus.write_byte_data(pruefer2, GPPUB, wert)
|
||||||
|
bus.write_byte_data(pruefer2, IODIRB, wert)
|
||||||
|
bus.write_byte_data(pruefer2, GPIOB, 0x00)
|
||||||
|
|
||||||
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
##print(f"i2cget -y 1 0x20 0x12")
|
||||||
|
pruefer1_A_value = bus.read_byte_data(pruefer1, GPIOA)
|
||||||
|
pruefer1_B_value = bus.read_byte_data(pruefer1, GPIOB)
|
||||||
|
pruefer2_A_value = bus.read_byte_data(pruefer2, GPIOA)
|
||||||
|
pruefer2_B_value = bus.read_byte_data(pruefer2, GPIOB)
|
||||||
|
|
||||||
|
observer1_A_value = bus.read_byte_data(observer1, GPIOA)
|
||||||
|
observer1_B_value = bus.read_byte_data(observer1, GPIOB)
|
||||||
|
observer2_A_value = bus.read_byte_data(observer2, GPIOA)
|
||||||
|
observer2_B_value = bus.read_byte_data(observer2, GPIOB)
|
||||||
|
|
||||||
|
#print(f"------>>>>Es konnte vom Pruefer der Wert {format(Wert_pruefer, '08b')} festgetsellt werden")
|
||||||
|
#print(f"------>>>>Es konnte vom Observer der Wert {format(Wert_observer, '08b')} festgetsellt werden")
|
||||||
|
|
||||||
|
|
||||||
|
for j in range(8): # Verarbeite 4*8=32 Pins + Jeweils 32 Observer-Daten
|
||||||
|
bitmaske = 1 << j # Erstelle eine Maske: 1, 2, 4, 8, 16, ...
|
||||||
|
|
||||||
|
pruefer1_A_value_bit = bool(pruefer1_A_value & bitmaske)
|
||||||
|
pruefer1_B_value_bit = bool(pruefer1_B_value & bitmaske)
|
||||||
|
pruefer2_A_value_bit = bool(pruefer2_A_value & bitmaske)
|
||||||
|
pruefer2_B_value_bit = bool(pruefer2_B_value & bitmaske)
|
||||||
|
|
||||||
|
observer1_A_value_bit = bool(observer1_A_value & bitmaske)
|
||||||
|
observer1_B_value_bit = bool(observer1_B_value & bitmaske)
|
||||||
|
observer2_A_value_bit = bool(observer2_A_value & bitmaske)
|
||||||
|
observer2_B_value_bit = bool(observer2_B_value & bitmaske)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
i = j
|
||||||
|
|
||||||
|
if pruefer1_A_value_bit == False:
|
||||||
|
#print("Gefunden: " + str(pin) + " <> " + str(j));
|
||||||
|
if observer1_A_value_bit == False:
|
||||||
|
#print("Dies wurde vom Observer bestätigt!");
|
||||||
|
data.append([[pin ,i],0])
|
||||||
|
else:
|
||||||
|
#print("Konnte NICHT bestätigen!");
|
||||||
|
data.append([[pin ,i],1])
|
||||||
|
if pruefer1_A_value_bit == False and observer1_A_value_bit == True:
|
||||||
|
data.append([[pin ,i],2])
|
||||||
|
#print("Prüfer sagt NEIN, Observer sagt JA");
|
||||||
|
if pruefer1_A_value_bit == True and observer1_A_value_bit == False:
|
||||||
|
data.append([[pin ,i],3])
|
||||||
|
#print("Prüfer sagt JA, Observer sagt NEIN");
|
||||||
|
|
||||||
|
|
||||||
|
i = j + 8
|
||||||
|
|
||||||
|
if pruefer1_B_value_bit == False:
|
||||||
|
#print("Gefunden: " + str(pin) + " <> " + str(j));
|
||||||
|
if observer1_B_value_bit == False:
|
||||||
|
#print("Dies wurde vom Observer bestätigt!");
|
||||||
|
data.append([[pin ,i],0])
|
||||||
|
else:
|
||||||
|
#print("Konnte NICHT bestätigen!");
|
||||||
|
data.append([[pin ,i],1])
|
||||||
|
if pruefer1_B_value_bit == False and observer1_B_value_bit == True:
|
||||||
|
data.append([[pin ,i],2])
|
||||||
|
#print("Prüfer sagt NEIN, Observer sagt JA");
|
||||||
|
if pruefer1_B_value_bit == True and observer1_B_value_bit == False:
|
||||||
|
data.append([[pin ,i],3])
|
||||||
|
#print("Prüfer sagt JA, Observer sagt NEIN");
|
||||||
|
|
||||||
|
i = j + 16
|
||||||
|
|
||||||
|
if pruefer2_A_value_bit == False:
|
||||||
|
#print("Gefunden: " + str(pin) + " <> " + str(j));
|
||||||
|
if observer2_A_value_bit == False:
|
||||||
|
#print("Dies wurde vom Observer bestätigt!");
|
||||||
|
data.append([[pin ,i],0])
|
||||||
|
else:
|
||||||
|
#print("Konnte NICHT bestätigen!");
|
||||||
|
data.append([[pin ,i],1])
|
||||||
|
if pruefer2_A_value_bit == False and observer2_A_value_bit == True:
|
||||||
|
data.append([[pin ,i],2])
|
||||||
|
#print("Prüfer sagt NEIN, Observer sagt JA");
|
||||||
|
if pruefer2_A_value_bit == True and observer2_A_value_bit == False:
|
||||||
|
data.append([[pin ,i],3])
|
||||||
|
#print("Prüfer sagt JA, Observer sagt NEIN");
|
||||||
|
|
||||||
|
i = j + 24
|
||||||
|
|
||||||
|
if pruefer2_B_value_bit == False:
|
||||||
|
#print("Gefunden: " + str(pin) + " <> " + str(j));
|
||||||
|
if observer2_B_value_bit == False:
|
||||||
|
#print("Dies wurde vom Observer bestätigt!");
|
||||||
|
data.append([[pin ,i],0])
|
||||||
|
else:
|
||||||
|
#print("Konnte NICHT bestätigen!");
|
||||||
|
data.append([[pin ,i],1])
|
||||||
|
if pruefer2_B_value_bit == False and observer2_B_value_bit == True:
|
||||||
|
data.append([[pin ,i],2])
|
||||||
|
#print("Prüfer sagt NEIN, Observer sagt JA");
|
||||||
|
if pruefer2_B_value_bit == True and observer2_B_value_bit == False:
|
||||||
|
data.append([[pin ,i],3])
|
||||||
|
#print("Prüfer sagt JA, Observer sagt NEIN");
|
||||||
|
|
||||||
|
logs["errorcode"] = 10
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except:
|
||||||
|
logs["errorcode"] = 13
|
||||||
|
array["logs"] = logs
|
||||||
|
array["data"] = data
|
||||||
|
json_output = json.dumps(array)
|
||||||
|
print(json_output)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
53
python/test.py
Normal file
53
python/test.py
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import smbus
|
||||||
|
import time
|
||||||
|
import json
|
||||||
|
|
||||||
|
# Adressen der beiden MCP23017 Chips
|
||||||
|
MP = 0x20 # Ausgang rechte Hälfte
|
||||||
|
|
||||||
|
|
||||||
|
# Register-Adressen für den MCP23017
|
||||||
|
IODIRA = 0x00 # Eingang / Ausgang A
|
||||||
|
IODIRB = 0x01 # Eingang / Ausgang B
|
||||||
|
GPIOA = 0x12 # GPIO A
|
||||||
|
GPIOB = 0x13 # GPIO B
|
||||||
|
|
||||||
|
PULLUPA = 0x0C
|
||||||
|
PULLUPB = 0x0D
|
||||||
|
|
||||||
|
# Initialisiere den I2C Bus
|
||||||
|
bus = smbus.SMBus(1)
|
||||||
|
|
||||||
|
# Hauptprogramm
|
||||||
|
def main():
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
for pin in range(8):
|
||||||
|
|
||||||
|
|
||||||
|
bus.write_byte_data(MP, IODIRA, ~(1 << pin))
|
||||||
|
time.sleep(0.02)
|
||||||
|
bus.write_byte_data(MP, PULLUPA, ~(1 << pin))
|
||||||
|
time.sleep(0.02)
|
||||||
|
|
||||||
|
bus.write_byte_data(MP, GPIOA, ~(1 << pin))
|
||||||
|
time.sleep(0.02)
|
||||||
|
|
||||||
|
|
||||||
|
print("====================" + str(pin) + "==========================")
|
||||||
|
|
||||||
|
wert = bus.read_byte_data(MP, GPIOA)
|
||||||
|
|
||||||
|
for j in range(8): # Lese 4*8=32 Pins
|
||||||
|
bitmaske = 1 << j
|
||||||
|
|
||||||
|
wert_bitweise = bool(wert & bitmaske)
|
||||||
|
|
||||||
|
if wert_bitweise == False and j != pin:
|
||||||
|
print(str(j))
|
||||||
|
|
||||||
|
time.sleep(0.02) # Kurze Pause, damit die Änderung sichtbar wird
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
364
reset.php
Normal file
364
reset.php
Normal file
@@ -0,0 +1,364 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$data = '{
|
||||||
|
"plugs": [
|
||||||
|
{
|
||||||
|
"name": "SpDr L30",
|
||||||
|
"id": "0",
|
||||||
|
"programCharNumber": "5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SpDr S60",
|
||||||
|
"id": "1",
|
||||||
|
"programCharNumber": "6"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bridges": [
|
||||||
|
{
|
||||||
|
"plugID": null,
|
||||||
|
"bridgeName": "3",
|
||||||
|
"nodes": [
|
||||||
|
[
|
||||||
|
"14",
|
||||||
|
"27"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"plugID": null,
|
||||||
|
"bridgeName": "4",
|
||||||
|
"nodes": [
|
||||||
|
[
|
||||||
|
"16",
|
||||||
|
"15"
|
||||||
|
],
|
||||||
|
null,
|
||||||
|
[
|
||||||
|
"15",
|
||||||
|
"23"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"plugID": null,
|
||||||
|
"bridgeName": "40",
|
||||||
|
"nodes": [
|
||||||
|
[
|
||||||
|
"15",
|
||||||
|
"13"
|
||||||
|
],
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
[
|
||||||
|
"30",
|
||||||
|
"33"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"plugID": "0",
|
||||||
|
"bridgeName": "68",
|
||||||
|
"nodes": [
|
||||||
|
[
|
||||||
|
"20",
|
||||||
|
"30"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"35",
|
||||||
|
"36"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"plugID": "0",
|
||||||
|
"bridgeName": "70",
|
||||||
|
"nodes": [
|
||||||
|
[
|
||||||
|
"34",
|
||||||
|
"24"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"plugID": "0",
|
||||||
|
"bridgeName": "72",
|
||||||
|
"nodes": [
|
||||||
|
[
|
||||||
|
"24",
|
||||||
|
"14"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"plugID": "0",
|
||||||
|
"bridgeName": "62",
|
||||||
|
"nodes": [
|
||||||
|
[
|
||||||
|
"33",
|
||||||
|
"23"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"plugID": "0",
|
||||||
|
"bridgeName": "65",
|
||||||
|
"nodes": [
|
||||||
|
[
|
||||||
|
"12",
|
||||||
|
"13"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"plugID": "0",
|
||||||
|
"bridgeName": "78",
|
||||||
|
"nodes": [
|
||||||
|
[
|
||||||
|
"31",
|
||||||
|
"21"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"plugID": "0",
|
||||||
|
"bridgeName": "80",
|
||||||
|
"nodes": [
|
||||||
|
[
|
||||||
|
"31",
|
||||||
|
"22"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"programs": [
|
||||||
|
{
|
||||||
|
"plugID": "0",
|
||||||
|
"programID": [
|
||||||
|
"V",
|
||||||
|
"-",
|
||||||
|
"-",
|
||||||
|
"-",
|
||||||
|
"-"
|
||||||
|
],
|
||||||
|
"bridges": [
|
||||||
|
"68"
|
||||||
|
],
|
||||||
|
"programDescription": "verschlossen werden"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"plugID": "0",
|
||||||
|
"programID": [
|
||||||
|
"-",
|
||||||
|
"1",
|
||||||
|
"-",
|
||||||
|
"-",
|
||||||
|
"0"
|
||||||
|
],
|
||||||
|
"bridges": [
|
||||||
|
"70",
|
||||||
|
"72"
|
||||||
|
],
|
||||||
|
"programDescription": "weder Kreuzungs- noch Zwieschutzweiche"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"plugID": "0",
|
||||||
|
"programID": [
|
||||||
|
"-",
|
||||||
|
"-",
|
||||||
|
"3",
|
||||||
|
"-",
|
||||||
|
"-"
|
||||||
|
],
|
||||||
|
"bridges": [
|
||||||
|
"62",
|
||||||
|
"65"
|
||||||
|
],
|
||||||
|
"programDescription": "Zugfahrt auf Hp1 nur \u00fcber Minusstrang stellbar"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"plugID": "0",
|
||||||
|
"programID": [
|
||||||
|
"-",
|
||||||
|
"-",
|
||||||
|
"-",
|
||||||
|
"5",
|
||||||
|
"-"
|
||||||
|
],
|
||||||
|
"bridges": [
|
||||||
|
"78",
|
||||||
|
"80"
|
||||||
|
],
|
||||||
|
"programDescription": "Zugfahrten auf Sh1 \u00fcber Weiche stellbar"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"places": [
|
||||||
|
{
|
||||||
|
"name": "Osterburken Of",
|
||||||
|
"placeID": "g7FhxA"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "M\u00fchlacker Mf",
|
||||||
|
"placeID": "tFu7hD"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Mannheim-Waldhof Wf (Mwf)",
|
||||||
|
"placeID": "cqGe8D"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "V\u00f6lklingen Vf",
|
||||||
|
"placeID": "2d9jzL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "G\u00f6ppingen Gf",
|
||||||
|
"placeID": "Hpg65B"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Geislingen (Steige) Gf",
|
||||||
|
"placeID": "sUfr3C"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "B\u00f6blingen Bf",
|
||||||
|
"placeID": "mxgPY2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Amstetten (W\u00fcrtt) Af",
|
||||||
|
"placeID": "SwZK2B"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Bierbach Bf",
|
||||||
|
"placeID": "u8FTYx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Bondorf (b Herrenberg) Bf",
|
||||||
|
"placeID": "FKR5A9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Gingen (Fils)",
|
||||||
|
"placeID": "5J6Zge"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Illingen (W\u00fcrtt) If",
|
||||||
|
"placeID": "rWCN6b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Laupheim West Lf",
|
||||||
|
"placeID": "JUwSbY"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Orschweier Of (Orf)",
|
||||||
|
"placeID": "ha88hL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "T\u00fcrkism\u00fchle Tf",
|
||||||
|
"placeID": "63sKQa"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "V\u00f6lklingen Saarstahl Walzwerk Ngf",
|
||||||
|
"placeID": "a9tSAR"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Dudweiler Df",
|
||||||
|
"placeID": "Fmk3fT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Beckingen (Saar) Bf",
|
||||||
|
"placeID": "eQ7CAB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "G\u00e4rtringen Gf",
|
||||||
|
"placeID": "G9FBxL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": null,
|
||||||
|
"placeID": "sxQjTF"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "geislingen",
|
||||||
|
"placeID": "Xkp3Ak"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Meine Tasche",
|
||||||
|
"placeID": "PUEtdp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Mein B\u00fcro",
|
||||||
|
"placeID": "vcY225"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Karlsruhe B\u00fcro",
|
||||||
|
"placeID": "Qf4lI8"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"measurements": [
|
||||||
|
{
|
||||||
|
"plugID": [
|
||||||
|
"0",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"place": "cqGe8D",
|
||||||
|
"programID": [
|
||||||
|
"V",
|
||||||
|
"1",
|
||||||
|
"3",
|
||||||
|
"5",
|
||||||
|
"0"
|
||||||
|
],
|
||||||
|
"bridges": [
|
||||||
|
[
|
||||||
|
"22",
|
||||||
|
"31"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"21",
|
||||||
|
"22"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"12",
|
||||||
|
"13"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"23",
|
||||||
|
"33"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"21",
|
||||||
|
"31"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"14",
|
||||||
|
"24"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"14",
|
||||||
|
"34"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"24",
|
||||||
|
"34"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"20",
|
||||||
|
"30"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"35",
|
||||||
|
"36"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"17",
|
||||||
|
"36"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"special": "+ Br\u00fccke 56",
|
||||||
|
"timestamp": 1740400487
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
file_put_contents("database.json", $data)
|
||||||
|
|
||||||
|
?>
|
||||||
502
script.js
Normal file
502
script.js
Normal file
@@ -0,0 +1,502 @@
|
|||||||
|
function distinctlyInput(input) {
|
||||||
|
// Wenn das aktuell gewählte Feld gefüllt wird
|
||||||
|
if ($('#distinctlyInput' + input).val().length >= 1) {
|
||||||
|
input++; // Fahre fort mit dem nächsten Feld
|
||||||
|
if ($('#distinctlyInput' + input).length) {
|
||||||
|
$('#distinctlyInput' + input).focus().select(); // Fokus auf das nächste Feld setzen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Wenn das aktuell gewählte Feld geleert wird
|
||||||
|
else if ($('#distinctlyInput' + input).val().length === 0 && input > 1) {
|
||||||
|
input--; // Gehe zum vorherigen Feld
|
||||||
|
$('#distinctlyInput' + input).focus().select(); // Fokus auf das vorherige Feld setzen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function pageload(view, meta) { // Funktion zum Laden des Inhalts
|
||||||
|
|
||||||
|
secondaryNavigation("close"); // Schließe das Stecker-Menü
|
||||||
|
page = window.location.hash.substr(1); // Hole die aufzurufende Seite über den URL-Hash (#xy)
|
||||||
|
|
||||||
|
if(page.length === 0) {
|
||||||
|
|
||||||
|
page = "index";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var loadingTimer = setTimeout(function() {
|
||||||
|
$("#content").addClass("loading");
|
||||||
|
message("Die Seite befindet sich im Aufbau...");
|
||||||
|
}, 2000); // 2 Sekunden warten
|
||||||
|
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: "/pagecontent/" + page + ".php?view=" + view + "&meta=" + meta, // Pfad der zu ladenden Seite aufbauen
|
||||||
|
error: function(jqXHR, textStatus, errorThrown) { // Wenn ein Fehler bei der Anfrage auftritt (z.B. Netzwerkprobleme)
|
||||||
|
|
||||||
|
message("Es ist ein unerwarteter Fehler aufgetreten. Der Seiteninhalt konnte nicht geladen werden!");
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
success: function(result){ // Abfrage erfolgreich
|
||||||
|
clearTimeout(loadingTimer);
|
||||||
|
$("#content").removeClass("loading");
|
||||||
|
$("#content").html(result);
|
||||||
|
$("div.navigation>div").removeClass("active"); // Alle Buttons inaktiv
|
||||||
|
$("#" + page).addClass("active"); // Button mit Klasse "page" wird aktiv geschaltet (im Menü)
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkForReload(page) {
|
||||||
|
|
||||||
|
page_hash = window.location.hash.substr(1);
|
||||||
|
|
||||||
|
if(page_hash == page) {
|
||||||
|
pageload();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function checkConnection(last) { // Verbindunsstatus überwachen // Last ist der letzte gemessene Netzwerkzustand
|
||||||
|
$.ajax({
|
||||||
|
url: "/actions/connection-test.php?a=" + Date.now(), // verändere idr URL leicht, damit der Server nicht cached
|
||||||
|
timeout: 5000, // maximale Wartezeit sind 5 Sekunden; alles darüber wird als zu unzuverlässig angesehen
|
||||||
|
error: function(jqXHR, textStatus, errorThrown) { // Wenn ein Fehler bei der Anfrage auftritt (z.B. Netzwerkprobleme)
|
||||||
|
|
||||||
|
$(".navigation-footer").html('<div class="connection-indicator false"></div>Keine Verbindung<img class="infrago-logo" src="/vendor/DB_InfraGo_logo_red_black_100px_rgb.svg" width="100%" />');
|
||||||
|
console.error("Fehler bei der Anfrage:", textStatus, errorThrown);
|
||||||
|
|
||||||
|
if (last != 1) { // letzter Zustand war "online" // Vermeiden von ständigen Nachrichten
|
||||||
|
message("Keine Verbindung"); // Werfe eine Nachricht
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(function() { // nächste Prüfung in 5 Sekunden
|
||||||
|
checkConnection(1); // der Status offline wird mit übertragen
|
||||||
|
}, 5000);
|
||||||
|
},
|
||||||
|
success: function(data) { // Verbindung iO
|
||||||
|
setTimeout(function() { // nächste Prüfung in 5 Sekunden
|
||||||
|
checkConnection();
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
|
if (data == 'true') { // der Rückgabewert ist true, alles IO
|
||||||
|
$(".navigation-footer").html('<div class="connection-indicator true"></div>Verbunden<img class="infrago-logo" src="/vendor/DB_InfraGo_logo_red_black_100px_rgb.svg" width="100%" />');
|
||||||
|
if (last == 1) { // war der letzte Status noch "offline", wird der Nutzer benachrichtigt
|
||||||
|
message("Verbindung wiederhergestellt!");
|
||||||
|
}
|
||||||
|
} else { // außergewöhnlicher Fehler, aber möglich
|
||||||
|
message("Keine Verbindung"); // Verbindung dennoch unbrauchbar, wenn keine Daten geladen werden
|
||||||
|
$(".navigation-footer").html('<div class="connection-indicator false"></div>Keine Verbindung<img class="infrago-logo" src="/vendor/DB_InfraGo_logo_red_black_100px_rgb.svg" width="100%" />');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var pinRowNumber = 0;
|
||||||
|
|
||||||
|
|
||||||
|
function connectPins(startPoint, endPoint, origin) {
|
||||||
|
|
||||||
|
|
||||||
|
const encoded = $('#bridge-editor-img').attr("meta");
|
||||||
|
const decoded = decodeURIComponent(encoded);
|
||||||
|
let myArray = JSON.parse(decoded);
|
||||||
|
|
||||||
|
|
||||||
|
console.log(myArray);
|
||||||
|
|
||||||
|
length = myArray.length;
|
||||||
|
lengthNext = length + 1;
|
||||||
|
lengthPrev = length -1 ;
|
||||||
|
|
||||||
|
|
||||||
|
myArray[length] = [];
|
||||||
|
myArray[length][0] = startPoint;
|
||||||
|
myArray[length][1] = endPoint;
|
||||||
|
$(".pin-table").append('<div class="row" id="pinRow_' + length + '"><span>' + startPoint + '</span><img src="/vendor/icons/data-transfer-both.svg" height="30px"/><span>' + endPoint + '</span><img style="transform: rotate(0deg); padding-top: 17.5px;" src="/vendor/icons/trash.svg" onclick="removePin(' + length + ')" height="30px"/></div>');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var myJsonStringURL = encodeURI(JSON.stringify(myArray));
|
||||||
|
|
||||||
|
|
||||||
|
$('#bridge-editor-img').attr("meta", myJsonStringURL);
|
||||||
|
|
||||||
|
|
||||||
|
$('#bridge-editor-img').attr("style", "background-image: url('../stecker.php?data=" + myJsonStringURL + "')");
|
||||||
|
|
||||||
|
|
||||||
|
$('#bridge-editor-edit').attr("value", pinRowNumber);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function removePin(row) {
|
||||||
|
const encoded = $('#bridge-editor-img').attr("meta");
|
||||||
|
const decoded = decodeURIComponent(encoded);
|
||||||
|
let myArray = JSON.parse(decoded);
|
||||||
|
|
||||||
|
myArray[row] = [];
|
||||||
|
myArray[row][0] = "";
|
||||||
|
myArray[row][1] = "";
|
||||||
|
|
||||||
|
$("#pinRow_" + row).hide();
|
||||||
|
|
||||||
|
var myJsonStringURL = encodeURI(JSON.stringify(myArray));
|
||||||
|
|
||||||
|
|
||||||
|
$('#bridge-editor-img').attr("meta", myJsonStringURL);
|
||||||
|
|
||||||
|
|
||||||
|
$('#bridge-editor-img').attr("style", "background-image: url('../stecker.php?data=" + myJsonStringURL + "')");
|
||||||
|
|
||||||
|
|
||||||
|
$('#bridge-editor-edit').attr("value", pinRowNumber);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function programBridge(number) { // Checkboxen für die Auswahl der Brücken im Programm-Editor
|
||||||
|
|
||||||
|
let myArray = []; // initialisiere Array
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
|
||||||
|
for (i = 0; i <= number; i++) { // iteriere durch alle Checkboxen
|
||||||
|
if ($('#programSelect_' + i).is(":checked")) { // wenn gesetzt
|
||||||
|
myArray[index] = $('#programSelect_' + i).val(); // Hänge die Brücken-ID dem Programm an
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var myJsonString = JSON.stringify(myArray); // kreiere URL
|
||||||
|
|
||||||
|
$('#program-editor-img').attr("src", "stecker.php?translate=true&data=" + myJsonString); // aktualisiere das Bild
|
||||||
|
console.log("OK");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function excludeBridge(number) { // Checkboxen für die Auswahl der Brücken im Programm-Editor
|
||||||
|
|
||||||
|
let myArray = []; // initialisiere Array
|
||||||
|
let myArraySubtrahend = []; // initialisiere Array
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
indexSubtrahend = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < number; i++) { // iteriere durch alle Checkboxen
|
||||||
|
if ($('#programSelect_' + i).is(":checked")) { // wenn gesetzt
|
||||||
|
myArray[index] = JSON.parse($('#programSelect_' + i).val());
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
myArraySubtrahend[indexSubtrahend] = JSON.parse($('#programSelect_' + i).val());
|
||||||
|
indexSubtrahend++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var myJsonString = JSON.stringify(myArray); // kreiere URL
|
||||||
|
var myJsonStringSubtrahend = JSON.stringify(myArraySubtrahend); // kreiere URL
|
||||||
|
|
||||||
|
|
||||||
|
$('#result-editor-result').attr("src", "stecker.php?data=" + myJsonString); // aktualisiere das Bild
|
||||||
|
|
||||||
|
|
||||||
|
$('#database-bridges-hidden').attr("value", encodeURI(myJsonStringSubtrahend));
|
||||||
|
|
||||||
|
|
||||||
|
console.log("OK");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function search(page,special) { // Datenbanksuche
|
||||||
|
|
||||||
|
value = $('#database-search-term').val(); // Suchbegriff, wenn die Datenbank durchsucht wird
|
||||||
|
|
||||||
|
if(page == 'results') {
|
||||||
|
if (special == "x") { // die Vorschläge werden ignoriert
|
||||||
|
value = ""; // Lösche Eingabe virtuell
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$.get("/pagecontent/database-search.php", {
|
||||||
|
meta: value, // Suchbegriff
|
||||||
|
view: page // je nachdem, von wo aus die Suche ausgelöst wurde
|
||||||
|
},
|
||||||
|
function(data, status) {
|
||||||
|
if (status == "success") {
|
||||||
|
if(page == 'results') { // je nachdem, von wo aus die Suche ausgelöst wurde, anderen Container verändern
|
||||||
|
$("div.search-container div.results").html(data);
|
||||||
|
}
|
||||||
|
if(page == 'program') {
|
||||||
|
$("div.inventory-table").html(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function save(page, action, meta) { // prinzipiell gleiche Funktion wie getcontent, jedoch mit Abfragen von JS-Werten
|
||||||
|
|
||||||
|
suppress_page_reload = 0;
|
||||||
|
|
||||||
|
if (page == "bridge-editor") {
|
||||||
|
|
||||||
|
if (action == "edit" || action == "add") {
|
||||||
|
|
||||||
|
number_entry = $('#bridge-editor-edit').val(); // von PHP fixierter Wert (Anzahl der zu Beginn vorhandenen Felder)
|
||||||
|
|
||||||
|
let myArray = {}; // Initialisiere myArray als Objekt
|
||||||
|
|
||||||
|
|
||||||
|
const encoded = $('#bridge-editor-img').attr("meta");
|
||||||
|
const decoded = decodeURIComponent(encoded);
|
||||||
|
myArray["pins"] = JSON.parse(decoded);
|
||||||
|
|
||||||
|
if (action == "add") { // wird die Brücke neu angelegt, muss ein Name gewählt werden
|
||||||
|
myArray["name"] = prompt("Bitte noch einen Namen festlegen (nur Zahlen):");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var myJsonString = JSON.stringify(myArray); // verpacke alle Pin-Brücken als JSON
|
||||||
|
|
||||||
|
|
||||||
|
meta = myJsonString;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (page == "program-editor") {
|
||||||
|
|
||||||
|
if (action == "edit" || action == "add") {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
let myArray = {}; // Initialisiere als leeres, multidimensionales, indexiertes Array
|
||||||
|
myArray["bridges"] = []; // Initialisiere als leeres Array
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
|
||||||
|
for (i = 0; i <= meta; i++) {
|
||||||
|
if ($('#programSelect_' + i).is(":checked")) {
|
||||||
|
myArray["bridges"][index] = $('#programSelect_' + i).val();
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (action == "add") {
|
||||||
|
myArray["programID"] = [];
|
||||||
|
for (i = 0; i <= 4; i++) {
|
||||||
|
j = i + 1;
|
||||||
|
myArray["programID"][i] = $('#distinctlyInput' + j).val().toUpperCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
myArray["programDescription"] = $('#program-description').val();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
console.log(myArray);
|
||||||
|
|
||||||
|
var myJsonString = JSON.stringify(myArray);
|
||||||
|
console.log(myJsonString); // Zeigt die JSON-Ausgabe in der Konsole an
|
||||||
|
|
||||||
|
meta = myJsonString;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (page == "inventory" && action == "add") {
|
||||||
|
|
||||||
|
|
||||||
|
let myArray = {};
|
||||||
|
myArray["name"] = $('#database-search-term').val();
|
||||||
|
|
||||||
|
myArray["bridges-hidden"] = $('#database-bridges-hidden').val();
|
||||||
|
myArray["special"] = $('#database-special').val();
|
||||||
|
|
||||||
|
|
||||||
|
myArray["programCache"] = [];
|
||||||
|
for (i = 0; i <= 4; i++) {
|
||||||
|
j = i + 1;
|
||||||
|
myArray["programCache"][i] = $('#distinctlyInput' + j).val().toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(myArray);
|
||||||
|
|
||||||
|
var myJsonString = JSON.stringify(myArray);
|
||||||
|
console.log(myJsonString); // Zeigt die JSON-Ausgabe in der Konsole an
|
||||||
|
|
||||||
|
meta = myJsonString;
|
||||||
|
|
||||||
|
suppress_page_reload = 1;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("/actions/" + page + ".php?action=" + action + "&meta=" + meta);
|
||||||
|
|
||||||
|
$.get("/actions/" + page + ".php", {
|
||||||
|
action: action,
|
||||||
|
meta: meta
|
||||||
|
|
||||||
|
},
|
||||||
|
function(data, status) {
|
||||||
|
if (status == "success") {
|
||||||
|
data = JSON.parse(data);
|
||||||
|
if (data[0] == true) {
|
||||||
|
if (suppress_page_reload != 1) {
|
||||||
|
window.location.href = "#" + page;
|
||||||
|
pageload();
|
||||||
|
}
|
||||||
|
|
||||||
|
message(data[1]);
|
||||||
|
} else {
|
||||||
|
message(data[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function secondaryNavigation(animation, content) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (animation == "open") {
|
||||||
|
|
||||||
|
|
||||||
|
$.get("/pagecontent/plug-select.php", {
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
function(data, status) {
|
||||||
|
if (status == "success") {
|
||||||
|
if (data != 'false') {
|
||||||
|
$("#navigation-secondary").css("left", "250px");
|
||||||
|
$(".navigation-header").attr("onclick", "secondaryNavigation('close','plug-select')");
|
||||||
|
setTimeout(function() {
|
||||||
|
$("#navigation-secondary").html(data);
|
||||||
|
console.log(data);
|
||||||
|
}, 200);
|
||||||
|
} else {
|
||||||
|
window.location.href = "#";
|
||||||
|
|
||||||
|
alert("Die Inhalte konnten nicht abgerufen werden. Vergewissern Sie sich, dass Sie mit dem WLAN-Netzwerk verbunden sind und laden Sie bei Bedarf die Seite neu.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$("#navigation-secondary").css("left", "-250px");
|
||||||
|
$(".navigation-header").attr("onclick", "secondaryNavigation('open','plug-select')");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeSettings(type, value, meta) {
|
||||||
|
|
||||||
|
$.get("/actions/save-settings.php", {
|
||||||
|
type: type,
|
||||||
|
value: value,
|
||||||
|
meta: meta
|
||||||
|
},
|
||||||
|
function(data, status) {
|
||||||
|
if (status == "success") {
|
||||||
|
if (data == 'true') {
|
||||||
|
applySettings(type);
|
||||||
|
pageload();
|
||||||
|
} else {
|
||||||
|
window.location.href = '#index';
|
||||||
|
pageload();
|
||||||
|
|
||||||
|
alert("Die Inhalte konnten nicht abgerufen werden. Vergewissern Sie sich, dass Sie mit dem WLAN-Netzwerk verbunden sind und laden Sie bei Bedarf die Seite neu.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function applySettings(type) {
|
||||||
|
|
||||||
|
secondaryNavigation('close');
|
||||||
|
|
||||||
|
$.get("/actions/apply-settings.php", {
|
||||||
|
type: type
|
||||||
|
},
|
||||||
|
function(data, status) {
|
||||||
|
if (status == "success") {
|
||||||
|
if (data != 'false') {
|
||||||
|
|
||||||
|
if (type == "plug") {
|
||||||
|
|
||||||
|
$(".navigation-header>div").html(data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
window.location.href = "#";
|
||||||
|
|
||||||
|
alert("Die Inhalte konnten nicht abgerufen werden. Vergewissern Sie sich, dass Sie mit dem WLAN-Netzwerk verbunden sind und laden Sie bei Bedarf die Seite neu.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function message(content) {
|
||||||
|
$("#message-box").html(content);
|
||||||
|
$("#message-box").css("display", "block");
|
||||||
|
setTimeout(function() {
|
||||||
|
$("#message-box").css("transform", "translateY(0)");
|
||||||
|
}, 50);
|
||||||
|
setTimeout(function() {
|
||||||
|
setTimeout(function() {
|
||||||
|
$("#message-box").css("display", "none");
|
||||||
|
}, 500);
|
||||||
|
$("#message-box").css("transform", "translateY(calc(100% + 5px))");
|
||||||
|
}, 3000);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$(window).bind('beforeunload', function() {
|
||||||
|
$("#warning").css("display", "block");
|
||||||
|
return 'Are you sure you want to leave?';
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1
settings.json
Normal file
1
settings.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"plug":"0"}
|
||||||
124
stecker.php
Normal file
124
stecker.php
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
<?php
|
||||||
|
// Setze den Content-Type-Header für SVG
|
||||||
|
header('Content-Type: image/svg+xml');
|
||||||
|
echo '<?xml version="1.0" encoding="UTF-8"?>';
|
||||||
|
?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
width="500" height="100">
|
||||||
|
|
||||||
|
<defs>
|
||||||
|
<style>
|
||||||
|
@font-face {
|
||||||
|
font-family: LexendDecaBold;
|
||||||
|
src: url(http://192.168.37.103/vendor/fonts/LexendDeca-Bold.ttf);
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
font-family: LexendDecaBold;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<text x="30" y="5" fill="black" text-anchor="middle" transform="translate(50,50) rotate(-90)">30</text>
|
||||||
|
<text x="-30" y="5" fill="black" text-anchor="middle" transform="translate(50,50) rotate(-90)">10</text>
|
||||||
|
<text x="30" y="405" fill="black" text-anchor="middle" transform="translate(50,50) rotate(-90)">31</text>
|
||||||
|
<text x="-30" y="405" fill="black" text-anchor="middle" transform="translate(50,50) rotate(-90)">11</text>
|
||||||
|
|
||||||
|
|
||||||
|
<path d="M500 0 L50 0" style="stroke:black;stroke-width:5; fill:none;" />
|
||||||
|
<path d="M50 0 L0 25" style="stroke:black;stroke-width:3; fill:none;" />
|
||||||
|
<path d="M0 25 L0 75" style="stroke:black;stroke-width:5; fill:none;" />
|
||||||
|
<path d="M0 75 L50 100" style="stroke:black;stroke-width:3; fill:none;" />
|
||||||
|
<path d="M50 100 L500 100" style="stroke:black;stroke-width:5; fill:none;" />
|
||||||
|
<path d="M500 100 L500 0" style="stroke:black;stroke-width:5; fill:none;" />
|
||||||
|
|
||||||
|
|
||||||
|
<rect width="35" height="35" x="452" y="32" rx="5" ry="5" style="stroke:black;stroke-width:3;fill:none" />
|
||||||
|
<circle r="8" cx="470" cy="50" fill="none" style="stroke:black;stroke-width:3;" />
|
||||||
|
<rect width="35" height="35" x="13" y="32" rx="5" ry="5" style="stroke:black;stroke-width:3;fill:none" />
|
||||||
|
<circle r="8" cx="30" cy="50" fill="none" style="stroke:black;stroke-width:3;" />
|
||||||
|
|
||||||
|
|
||||||
|
<rect width="380" height="80" x="60" y="10" rx="5" ry="5" style="stroke:black;stroke-width:3;fill:none" />
|
||||||
|
|
||||||
|
<?php
|
||||||
|
$pin_coordinates = [
|
||||||
|
10 => [70, 68], 20 => [70, 44], 30 => [70, 20],
|
||||||
|
11 => [405, 68], 12 => [370, 68], 13 => [335, 68], 14 => [300, 68],
|
||||||
|
15 => [265, 68], 16 => [230, 68], 17 => [195, 68], 18 => [160, 68], 19 => [125, 68],
|
||||||
|
21 => [405, 44], 22 => [370, 44], 23 => [335, 44], 24 => [300, 44],
|
||||||
|
25 => [265, 44], 26 => [220, 44], 27 => [185, 44], 28 => [150, 44], 29 => [115, 44],
|
||||||
|
31 => [405, 20], 32 => [370, 20], 33 => [335, 20], 34 => [300, 20],
|
||||||
|
35 => [265, 20], 36 => [230, 20], 37 => [195, 20], 38 => [160, 20], 39 => [125, 20],
|
||||||
|
];
|
||||||
|
|
||||||
|
// Rechtecke einfärben, wenn "fill"-Modus aktiv ist
|
||||||
|
if ($_GET["mode"] == "fill") {
|
||||||
|
$data = $_GET["data"];
|
||||||
|
$data = json_decode(urldecode($data), true);
|
||||||
|
|
||||||
|
foreach ($pin_coordinates as $key => $coordinates) {
|
||||||
|
$fill = in_array($key, $data) ? "green" : "red";
|
||||||
|
echo '<rect width="25" height="10" x="' . $coordinates[0] . '" y="' . $coordinates[1] . '" rx="1" ry="1" style="stroke:black;stroke-width:3;fill:' . $fill . '" />';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Nur Umrisse
|
||||||
|
foreach ($pin_coordinates as $coordinates) {
|
||||||
|
echo '<rect width="25" height="10" x="' . $coordinates[0] . '" y="' . $coordinates[1] . '" rx="1" ry="1" style="stroke:black;stroke-width:3;fill:none" />';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SVG frühzeitig beenden, wenn kein Data vorhanden oder im fill-Modus
|
||||||
|
if (empty($_GET['data']) || $_GET["mode"] == "fill") {
|
||||||
|
print "</svg>";
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Brückenverbindungen übersetzen, falls aktiviert
|
||||||
|
if ($_GET["translate"] == "true") {
|
||||||
|
$db = new SQLite3('db-test/test.db');
|
||||||
|
$data = json_decode($_GET["data"], true);
|
||||||
|
$plug = json_decode(file_get_contents("settings.json"), true)["plug"];
|
||||||
|
$nodes_raw = [];
|
||||||
|
|
||||||
|
foreach ($data as $bridge) {
|
||||||
|
$nodes = $db->query("SELECT node_from, node_to FROM nodes WHERE required_by = " . $bridge);
|
||||||
|
while ($node = $nodes->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
$nodes_raw[] = [$node['node_from'], $node['node_to']];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$inputArray = $nodes_raw;
|
||||||
|
} else {
|
||||||
|
$inputArray = json_decode($_GET['data'], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Koordinaten übersetzen
|
||||||
|
$translatedArray = array_map(function ($pair) use ($pin_coordinates) {
|
||||||
|
return [
|
||||||
|
$pin_coordinates[$pair[0]],
|
||||||
|
$pin_coordinates[$pair[1]],
|
||||||
|
];
|
||||||
|
}, $inputArray);
|
||||||
|
|
||||||
|
$colors = ["#1a5fb4", "#26a269", "#e5a50a", "#c64600", "#a51d2d", "#613583", "#63452c", "#3d3846"];
|
||||||
|
|
||||||
|
// Linien ausgeben
|
||||||
|
$colorNumber = 0;
|
||||||
|
foreach ($translatedArray as $line) {
|
||||||
|
$point1 = $line[0];
|
||||||
|
$point2 = $line[1];
|
||||||
|
|
||||||
|
$point1x = $point1[0] + 10;
|
||||||
|
$point1y = $point1[1] + 5;
|
||||||
|
$point2x = $point2[0] + 10;
|
||||||
|
$point2y = $point2[1] + 5;
|
||||||
|
|
||||||
|
echo '<path d="M' . $point1x . ' ' . $point1y . ' L' . $point2x . ' ' . $point2y .
|
||||||
|
'" style="stroke:' . $colors[$colorNumber] . ';stroke-width:3; fill:none;" />';
|
||||||
|
|
||||||
|
$colorNumber = ($colorNumber + 1) % count($colors);
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</svg>
|
||||||
553
style3.css
Normal file
553
style3.css
Normal file
@@ -0,0 +1,553 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: LexendDecaBold;
|
||||||
|
src: url(/vendor/fonts/LexendDeca-Bold.ttf);
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: LexendDecaMedium;
|
||||||
|
src: url(/vendor/fonts/LexendDeca-Medium.ttf);
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
padding: 20px;
|
||||||
|
margin: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-family: LexendDecaBold;
|
||||||
|
font-weight: light;
|
||||||
|
color: #2e3436;
|
||||||
|
}
|
||||||
|
div.main {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 900px;
|
||||||
|
height: auto;
|
||||||
|
border-radius: 15px;
|
||||||
|
overflow: hidden;
|
||||||
|
margin: 0 auto;
|
||||||
|
border: 5px solid #c3c3c3;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
div.navigation {
|
||||||
|
width: 250px;
|
||||||
|
height: 600px;
|
||||||
|
background-color: #ebebeb;
|
||||||
|
float: left;
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
z-index: 501;
|
||||||
|
}
|
||||||
|
div.navigation.secondary {
|
||||||
|
position: absolute;
|
||||||
|
left: -250px;
|
||||||
|
top: 0;
|
||||||
|
overflow-y: auto;
|
||||||
|
z-index: 500;
|
||||||
|
transition-duration: .6s;
|
||||||
|
width: 500px;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
background-color: #ebebeb8c;
|
||||||
|
}
|
||||||
|
div.navigation.secondary img {
|
||||||
|
width: 100px !important;
|
||||||
|
}
|
||||||
|
div.navigation>div, div.save-button {
|
||||||
|
padding: 5px;
|
||||||
|
margin: 10px;
|
||||||
|
line-height: 30px;
|
||||||
|
transition-duration: .4s;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
div.navigation>div:hover,div.navigation>div.active,div.navigation-footer,div.navigation-header,div.save-button:hover {
|
||||||
|
background-color: #d2d2d2;
|
||||||
|
}
|
||||||
|
div.navigation div.navigation-header {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
div.navigation div.navigation-header>div {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 0 0 7px 7px;
|
||||||
|
color: grey;
|
||||||
|
line-height: 20px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
div.navigation>div>img:not(.infrago-logo),div.content div.save-button>img {
|
||||||
|
width: 30px;
|
||||||
|
max-height: 30px;
|
||||||
|
margin-right:20px;
|
||||||
|
vertical-align:middle;
|
||||||
|
filter: contrast(0.3);
|
||||||
|
}
|
||||||
|
div.navigation>div>img.infrago-logo {
|
||||||
|
width: 100%;
|
||||||
|
display:block;
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
div.content {
|
||||||
|
width: calc(100% - 250px);
|
||||||
|
float: right;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 15px 20px;
|
||||||
|
height: 600px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow-y: auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
div.content>img.loader {
|
||||||
|
position: absolute;
|
||||||
|
height: 35%;
|
||||||
|
width: 35%;
|
||||||
|
left: 37.5%;
|
||||||
|
top: 37.5%;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
div#content {
|
||||||
|
transition-duration: .5s;
|
||||||
|
}
|
||||||
|
div#content.loading {
|
||||||
|
filter: blur(4px);
|
||||||
|
}
|
||||||
|
div#content.loading>img.loader {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
div.content div.content-header {
|
||||||
|
text-align: center;
|
||||||
|
line-height: 30px;
|
||||||
|
padding: 0;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
display: block;
|
||||||
|
font-size: 2em;
|
||||||
|
margin-block-start: 0.67em;
|
||||||
|
margin-block-end: 0.67em;
|
||||||
|
margin-inline-start: 0px;
|
||||||
|
margin-inline-end: 0px;
|
||||||
|
font-weight: bold;
|
||||||
|
unicode-bidi: isolate;
|
||||||
|
}
|
||||||
|
div.content img {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
div.navigation-footer {
|
||||||
|
position: absolute;
|
||||||
|
bottom:0;
|
||||||
|
width: calc(100% - 40px);
|
||||||
|
padding: 10px !important;
|
||||||
|
cursor: auto !important;
|
||||||
|
}
|
||||||
|
div.connection-indicator {
|
||||||
|
height: 15px;
|
||||||
|
width: 15px;
|
||||||
|
border-radius: 100%;
|
||||||
|
float: left;
|
||||||
|
vertical-align:middle;
|
||||||
|
margin: 7.5px;
|
||||||
|
}
|
||||||
|
div.connection-indicator.true {
|
||||||
|
background-color: #2ec27e;
|
||||||
|
}
|
||||||
|
div.connection-indicator.unknown {
|
||||||
|
background-color: #f6d32d;
|
||||||
|
}
|
||||||
|
div.connection-indicator.false {
|
||||||
|
background-color: #ed333b;
|
||||||
|
}
|
||||||
|
div.pin-table {
|
||||||
|
width: auto;
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
div.pin-table img {
|
||||||
|
width: 30px;
|
||||||
|
transform: rotate(90deg);
|
||||||
|
padding-left: 17.5px;
|
||||||
|
}
|
||||||
|
div.pin-table div.row {
|
||||||
|
width: auto;
|
||||||
|
display: block;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
div.pin-table div.row * {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
div.pin-table div.row input {
|
||||||
|
width: 100px;
|
||||||
|
border: 0;
|
||||||
|
background-color: #ebebeb;
|
||||||
|
padding: 15px;
|
||||||
|
font-family: inherit;
|
||||||
|
border-radius: 20px;
|
||||||
|
text-align: center;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
div.plug-table {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 50px;
|
||||||
|
}
|
||||||
|
div.row {
|
||||||
|
width: 100%;
|
||||||
|
height: 70px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
div.inventory-table>div.row {
|
||||||
|
height: 30px;
|
||||||
|
text-align: left;
|
||||||
|
display: block;
|
||||||
|
top: calc(50% - 27.5px);
|
||||||
|
position: relative;
|
||||||
|
width: auto;
|
||||||
|
background-color: #ebebeb;
|
||||||
|
margin: 10px;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 25px;
|
||||||
|
height: auto;
|
||||||
|
line-height: 25px;
|
||||||
|
}
|
||||||
|
div.inventory-table>div.row div.plug-table {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
div.inventory-table>div.row div.plug-table div.label>span {
|
||||||
|
background-color: #d2d2d2;
|
||||||
|
}
|
||||||
|
div.inventory-table>div.row img,div.inventory-table>div.row img {
|
||||||
|
max-height: 100%;
|
||||||
|
width: auto;
|
||||||
|
display: inline-block;
|
||||||
|
filter: opacity(.5);
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
div.inventory-table>div.row img.map,div.inventory-table>div.row img.down {
|
||||||
|
left: 10px;
|
||||||
|
top: 5px;
|
||||||
|
bottom: 5px;
|
||||||
|
}
|
||||||
|
div.inventory-table>div.row img.down {
|
||||||
|
left: unset;
|
||||||
|
cursor: pointer;
|
||||||
|
right: 10px;
|
||||||
|
}
|
||||||
|
div.inventory-table>div.row span {
|
||||||
|
margin-left: 4px;
|
||||||
|
line-height: 25px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
div.label {
|
||||||
|
display: inline-block;
|
||||||
|
width: 20%;
|
||||||
|
margin: 0 auto;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 100%;
|
||||||
|
float: left;
|
||||||
|
height: 70px;
|
||||||
|
}
|
||||||
|
div.label>span {
|
||||||
|
display: block;
|
||||||
|
top: calc(50% - 27.5px);
|
||||||
|
position:relative;
|
||||||
|
width: auto;
|
||||||
|
background-color: #ebebeb;
|
||||||
|
margin: 10px;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 25px;
|
||||||
|
height: 25px;
|
||||||
|
line-height:25px;
|
||||||
|
}
|
||||||
|
div.label>span span {
|
||||||
|
padding: 2px;
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 0px 3px;
|
||||||
|
border-radius: 100%;
|
||||||
|
display: block;
|
||||||
|
float: left;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
img#bridge-editor-img {
|
||||||
|
display: inline-block;
|
||||||
|
width: 65%;
|
||||||
|
max-height:70px;
|
||||||
|
}
|
||||||
|
div.row div.options {
|
||||||
|
display: inline-block;
|
||||||
|
width: 15%;
|
||||||
|
height: 70px;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
div.row div.options img {
|
||||||
|
width: 40%;
|
||||||
|
padding: 3px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: inline-block;
|
||||||
|
top: calc(50% - 25px);
|
||||||
|
position: relative;
|
||||||
|
filter: opacity(.5);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
div.action-menu {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 10px;
|
||||||
|
right: 10px;
|
||||||
|
width: auto;
|
||||||
|
height: 50px;
|
||||||
|
z-index: 501;
|
||||||
|
}
|
||||||
|
div.action-menu img {
|
||||||
|
float: left;
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
background-color: #ffffff7a;
|
||||||
|
border-radius: 100%;
|
||||||
|
cursor: pointer;
|
||||||
|
filter: contrast(0.3);
|
||||||
|
}
|
||||||
|
div.distinctly-input {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 10px;
|
||||||
|
width:70%;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.code-input, div.search-container input {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
font-size: 24px;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #ebebeb;
|
||||||
|
border-radius: 8px;
|
||||||
|
outline: none;
|
||||||
|
transition: border-color 0.3s ease;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
.code-input:focus {
|
||||||
|
border-color: #007bff;
|
||||||
|
}
|
||||||
|
textarea {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
height: 200px;
|
||||||
|
max-height: 200px;
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #ebebeb;
|
||||||
|
border-radius: 8px;
|
||||||
|
outline: none;
|
||||||
|
transition: border-color 0.3s ease;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
textarea:focus {
|
||||||
|
border-color: #007bff;
|
||||||
|
}
|
||||||
|
hr {
|
||||||
|
border: 3px solid #ebebeb;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
div.search-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
div.search-container input {
|
||||||
|
width: calc(100% - 60px);
|
||||||
|
border-radius: inherit 0px;
|
||||||
|
border-radius: 10px 0 0 10px;
|
||||||
|
}
|
||||||
|
div.search-container div.save-button {
|
||||||
|
width: 50px;
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0;
|
||||||
|
height: 40px;
|
||||||
|
float: right;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 0 10px 10px 0
|
||||||
|
}
|
||||||
|
div.search-container div.save-button img {
|
||||||
|
margin: 0;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
div.search-container div.results {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 50px;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: #d2d2d2;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
div.program-field {
|
||||||
|
padding: 20px;
|
||||||
|
margin-top: 20px;
|
||||||
|
border: 3px solid #ebebeb;
|
||||||
|
border-radius: 25px;
|
||||||
|
}
|
||||||
|
.checkbox-container {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.checkbox-container input[type="checkbox"] {
|
||||||
|
position: absolute;
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.checkbox-container .checkbox-text {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 25px;
|
||||||
|
background-color: #ebebeb;
|
||||||
|
padding: 5px 15px;
|
||||||
|
border: 3px solid #ebebeb;
|
||||||
|
}
|
||||||
|
.checkbox-container input[type="checkbox"]:checked + .checkbox-text {
|
||||||
|
background-color: #d2d2d2;
|
||||||
|
border: 3px solid #2e3436;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
div.save-button img {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
div.save-button {
|
||||||
|
background-color: #ebebeb
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 5px;
|
||||||
|
}
|
||||||
|
/* Track */
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: #ebebeb;
|
||||||
|
}
|
||||||
|
/* Handle */
|
||||||
|
::-webkit-scrollbar-thumb, ::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: #d2d2d2;
|
||||||
|
}
|
||||||
|
div.toggle-switch {
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
div.toggle-switch div {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
div.toggle-switch div:nth-child(1), div.toggle-switch div:nth-child(3) {
|
||||||
|
width: 39%;
|
||||||
|
}
|
||||||
|
div.toggle-switch div:nth-child(2) {
|
||||||
|
width: 20%;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
.switch {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
height: 34px;
|
||||||
|
}
|
||||||
|
.switch input {
|
||||||
|
opacity: 0;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
.slider {
|
||||||
|
position: absolute;
|
||||||
|
cursor: pointer;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: #ccc;
|
||||||
|
-webkit-transition: .4s;
|
||||||
|
transition: .4s;
|
||||||
|
border-radius: 25px;
|
||||||
|
}
|
||||||
|
.slider:before {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
height: 26px;
|
||||||
|
width: 26px;
|
||||||
|
left: 4px;
|
||||||
|
bottom: 4px;
|
||||||
|
background-color: white;
|
||||||
|
-webkit-transition: .4s;
|
||||||
|
transition: .4s;
|
||||||
|
border-radius: 100%;
|
||||||
|
}
|
||||||
|
input:checked + .slider:before {
|
||||||
|
-webkit-transform: translateX(86px);
|
||||||
|
-ms-transform: translateX(86px);
|
||||||
|
transform: translateX(86px);
|
||||||
|
}
|
||||||
|
/* Rounded sliders */
|
||||||
|
.slider.round {
|
||||||
|
border-radius: 34px;
|
||||||
|
}
|
||||||
|
.slider.round:before {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
table.simple-devider th,table.simple-devider td {
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
table.simple-devider * {
|
||||||
|
margin: 0;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
canvas {
|
||||||
|
cursor: crosshair;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 1200px) {
|
||||||
|
div.main {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
max-width: unset;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
padding: 0;
|
||||||
|
padding-right: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
div.content {
|
||||||
|
width: calc(100% - 250px);
|
||||||
|
height: 100%;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
div.navigation {
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
div.navigation-footer {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 800px) {
|
||||||
|
|
||||||
|
div.navigation {
|
||||||
|
width: 40px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
div.navigation > div > span {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
div.navigation>div {
|
||||||
|
padding: 5px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.navigation.secondary {
|
||||||
|
left: -500px !important;
|
||||||
|
}
|
||||||
|
div.navigation-footer {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
div.content {
|
||||||
|
width: calc(100% - 40px);
|
||||||
|
height: 100%;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
8
temp.csv
Normal file
8
temp.csv
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
"Gemessen am / um";"Stw-Name / Ort";"Erkannte Brücken (Pin-zu-Pin)";"(automatisch) ermittelte Programm-Nummer";Freitext-Besonderheiten
|
||||||
|
"24.07.2025 11:48:00";"Dudweiler Df";"20<->28, 30<->39, ";?????;
|
||||||
|
"24.07.2025 11:48:56";"Mannheim-Waldhof Wf (Mwf)";"20<->28, 30<->39, ";12345;
|
||||||
|
"24.07.2025 12:48:27";"Laupheim West Lf";"20<->28, 30<->39, ";S???1;
|
||||||
|
"24.07.2025 13:37:29";"Mannheim-Waldhof Wf (Mwf)";"20<->28, 30<->39, ";S???1;
|
||||||
|
"24.07.2025 14:28:33";"Dudweiler Df";"20<->28, 30<->39, ";S???1;
|
||||||
|
"28.07.2025 14:52:44";"Sinzig Sf";"19<->22, ";JAAAA;
|
||||||
|
"29.07.2025 05:57:38";"Mannheim-Waldhof Wf (Mwf)";"19<->22, ";JAAAA;
|
||||||
|
77
vendor/DB_InfraGo_logo_red_black_100px_rgb.svg
vendored
Normal file
77
vendor/DB_InfraGo_logo_red_black_100px_rgb.svg
vendored
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?><svg id="DB_InfraGO_logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 316.5 70"><desc>Das ist das Firmenlogo der gemeinwohlorientierten Infrastrukturgesellschaft DB InfraGO AG.</desc>
|
||||||
|
<metadata><?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
|
||||||
|
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 9.1-c001 79.a8d4753, 2023/03/23-08:56:37 ">
|
||||||
|
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||||
|
<rdf:Description rdf:about=""
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/"
|
||||||
|
xmlns:xmp="http://ns.adobe.com/xap/1.0/"
|
||||||
|
xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
|
||||||
|
xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
|
||||||
|
xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/">
|
||||||
|
<dc:creator>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li>Deutsche Bahn</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</dc:creator>
|
||||||
|
<dc:description>
|
||||||
|
<rdf:Alt>
|
||||||
|
<rdf:li xml:lang="x-default">Das ist das Firmenlogo der gemeinwohlorientierten Infrastrukturgesellschaft DB InfraGO AG.</rdf:li>
|
||||||
|
</rdf:Alt>
|
||||||
|
</dc:description>
|
||||||
|
<Iptc4xmpCore:AltTextAccessibility>
|
||||||
|
<rdf:Alt>
|
||||||
|
<rdf:li xml:lang="x-default">Das ist das Firmenlogo der gemeinwohlorientierten Infrastrukturgesellschaft DB InfraGO AG.</rdf:li>
|
||||||
|
</rdf:Alt>
|
||||||
|
</Iptc4xmpCore:AltTextAccessibility>
|
||||||
|
<Iptc4xmpCore:ExtDescrAccessibility>
|
||||||
|
<rdf:Alt>
|
||||||
|
<rdf:li xml:lang="x-default">Das ist das Firmenlogo der gemeinwohlorientierten Infrastrukturgesellschaft DB InfraGO AG.</rdf:li>
|
||||||
|
</rdf:Alt>
|
||||||
|
</Iptc4xmpCore:ExtDescrAccessibility>
|
||||||
|
<xmp:MetadataDate>2023-12-20T16:18:38+01:00</xmp:MetadataDate>
|
||||||
|
<xmpMM:InstanceID>xmp.iid:f4896118-a5fc-4ec6-884b-265e34b1ca9a</xmpMM:InstanceID>
|
||||||
|
<xmpMM:DocumentID>xmp.did:8feca862-1f36-49d9-a283-4022945ab9e2</xmpMM:DocumentID>
|
||||||
|
<xmpMM:OriginalDocumentID>xmp.did:8feca862-1f36-49d9-a283-4022945ab9e2</xmpMM:OriginalDocumentID>
|
||||||
|
<xmpMM:History>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li>
|
||||||
|
<rdf:Description>
|
||||||
|
<stEvt:action>saved</stEvt:action>
|
||||||
|
<stEvt:instanceID>xmp.iid:8feca862-1f36-49d9-a283-4022945ab9e2</stEvt:instanceID>
|
||||||
|
<stEvt:when>2023-12-20T16:13:32+01:00</stEvt:when>
|
||||||
|
<stEvt:softwareAgent>Adobe Bridge 2024</stEvt:softwareAgent>
|
||||||
|
<stEvt:changed>/metadata</stEvt:changed>
|
||||||
|
</rdf:Description>
|
||||||
|
</rdf:li>
|
||||||
|
<rdf:li>
|
||||||
|
<rdf:Description>
|
||||||
|
<stEvt:action>saved</stEvt:action>
|
||||||
|
<stEvt:instanceID>xmp.iid:f4896118-a5fc-4ec6-884b-265e34b1ca9a</stEvt:instanceID>
|
||||||
|
<stEvt:when>2023-12-20T16:18:38+01:00</stEvt:when>
|
||||||
|
<stEvt:softwareAgent>Adobe Bridge 2024</stEvt:softwareAgent>
|
||||||
|
<stEvt:changed>/metadata</stEvt:changed>
|
||||||
|
</rdf:Description>
|
||||||
|
</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</xmpMM:History>
|
||||||
|
<photoshop:CaptionWriter>Deutsche Bahn</photoshop:CaptionWriter>
|
||||||
|
</rdf:Description>
|
||||||
|
</rdf:RDF>
|
||||||
|
</x:xmpmeta>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<?xpacket end="w"?></metadata>
|
||||||
|
<g id="DB_Logo"><path d="M90,0H10C4.6,0,0,4.3,0,10v50c0,5.5,4.6,10,10,10h80c5.5,0,10-4.5,10-10.1V10c0-5.7-4.6-10-10-10ZM92.7,59.9c0,1.6-1.2,2.9-2.7,2.9H10c-1.6,0-2.7-1.3-2.7-2.9V10c0-1.6,1.2-2.9,2.7-2.9h80c1.6,0,2.7,1.3,2.7,2.9v49.9Z" style="fill:#ec0016; stroke-width:0px;"/><path d="M30.6,57.9H13.8V12.1h16.8c11.9,0,18.4,7.4,18.4,22.7,0,13.2-4.5,23-18.4,23.1ZM37.9,35.7c0-9.2-1-16.4-10.9-16.4h-2.2v31.2h3.9c5.8,0,9.2-4.7,9.2-14.8Z" style="fill:#ec0016; stroke-width:0px;"/><path d="M78,33.9c3.2-.9,8-4.6,8-10.7,0-1-.2-11.2-13.1-11.2h-19.1v45.8h16.2c4.3,0,17.7,0,17.7-12.9,0-3.1-1.4-9.1-9.7-11ZM64.7,19.2h3.5c4.9,0,6.9,1.7,6.9,5.5,0,3-2.2,5.5-6,5.5h-4.4v-11ZM69.2,50.5h-4.5v-11.8h4.8c5.7,0,7.1,3.3,7.1,5.9,0,5.9-5.6,5.9-7.4,5.9Z" style="fill:#ec0016; stroke-width:0px;"/></g><g id="InfraGo"><path d="M125,19.1h10v38.9h-10V19.1Z" style="stroke-width:0px;"/><path d="M148.3,28.5h2.2v5.2c3.1-3.5,6.2-5.1,9.9-5.1,4.9,0,7.7,3.3,7.7,9v20.3h-9.3v-18.2c0-2.4-1.1-3.5-3.4-3.5-1.6,0-2.8.4-4.9,1.5v20.2h-9.3v-27.6c3.7-.1,6-.7,7.1-1.8Z" style="stroke-width:0px;"/><path d="M175,37.2h-3.6v-6.6h3.6v-2c0-6.3,3.8-10.2,11.3-10.2,1.9,0,3.3.2,4.6.3v6.4c-.7-.1-1.3-.2-2-.2-3.2,0-4.5,1.2-4.5,4v1.7h4.8v6.6h-4.8v20.7h-9.4v-20.7Z" style="stroke-width:0px;"/><path d="M199.3,28.6h2.2v5.7c2.4-3.8,4.9-5.6,7.6-5.6.3,0,.5.1.7.1v8.3l-.6.1c-2.5.2-5.3.8-7.7,1.9v18.9h-9.3v-27.6c3.6-.1,5.9-.7,7.1-1.8Z" style="stroke-width:0px;"/><path d="M226.7,54.2c-2.1,3-4.9,4.5-8.4,4.5-5.3,0-8.4-3-8.4-8.6,0-8.1,7-8.6,16.3-9v-1.5c0-3-1.4-4.1-4.2-4.1s-5.9.5-9.8,1.2v-7.2c4.1-.9,7.2-1.3,10.8-1.3,8.9,0,12.5,3.3,12.5,11.2v11.7c0,3.2.3,4.3,1.2,5v1.6h-9l-1-3.5ZM222.1,52.6c1.5,0,2.9-.5,4.2-1.6v-5.7c-5.3.2-7.2.5-7.2,4-.1,2.3.8,3.3,3,3.3Z" style="stroke-width:0px;"/><path d="M240.1,39v-.2c0-13.6,7.2-20.3,20.4-20.3,4.3,0,7.6.5,11.6,1.7v7.9c-3.9-1.3-7.3-1.9-11.1-1.9-7.9,0-10,4-10,12.6v.3c0,8.8,2.4,12.2,9.4,12.2,1.6,0,2.7-.2,4.2-.6v-6.5h-6.2v-7.4h15.6v19c-4.8,1.8-9,2.8-13.9,2.8-13.6,0-20-5-20-19.6Z" style="stroke-width:0px;"/><path d="M278.7,38.6v-.2c0-12.5,7.1-20,18.9-20,11.9,0,18.9,7.6,18.9,20.1v.2c0,12.5-7,19.9-18.9,19.9-12,0-18.9-7.5-18.9-20ZM305.6,38.7v-.3c0-9-2.4-12.7-8-12.7-5.7,0-8,3.7-8,12.8v.3c0,8.8,2.4,12.4,8,12.4,5.7,0,8-3.6,8-12.5Z" style="stroke-width:0px;"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 6.9 KiB |
5
vendor/composer/composer.json
vendored
Normal file
5
vendor/composer/composer.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"require": {
|
||||||
|
"phpoffice/phpspreadsheet": "^4.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
600
vendor/composer/composer.lock
generated
vendored
Normal file
600
vendor/composer/composer.lock
generated
vendored
Normal file
@@ -0,0 +1,600 @@
|
|||||||
|
{
|
||||||
|
"_readme": [
|
||||||
|
"This file locks the dependencies of your project to a known state",
|
||||||
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
|
"This file is @generated automatically"
|
||||||
|
],
|
||||||
|
"content-hash": "218a60c9572277f09d6952f6a8761547",
|
||||||
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "composer/pcre",
|
||||||
|
"version": "3.3.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/composer/pcre.git",
|
||||||
|
"reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e",
|
||||||
|
"reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.4 || ^8.0"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"phpstan/phpstan": "<1.11.10"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpstan/phpstan": "^1.12 || ^2",
|
||||||
|
"phpstan/phpstan-strict-rules": "^1 || ^2",
|
||||||
|
"phpunit/phpunit": "^8 || ^9"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"phpstan": {
|
||||||
|
"includes": [
|
||||||
|
"extension.neon"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-main": "3.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Composer\\Pcre\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Jordi Boggiano",
|
||||||
|
"email": "j.boggiano@seld.be",
|
||||||
|
"homepage": "http://seld.be"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PCRE wrapping library that offers type-safe preg_* replacements.",
|
||||||
|
"keywords": [
|
||||||
|
"PCRE",
|
||||||
|
"preg",
|
||||||
|
"regex",
|
||||||
|
"regular expression"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/composer/pcre/issues",
|
||||||
|
"source": "https://github.com/composer/pcre/tree/3.3.2"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://packagist.com",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/composer",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-11-12T16:29:46+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "maennchen/zipstream-php",
|
||||||
|
"version": "3.1.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/maennchen/ZipStream-PHP.git",
|
||||||
|
"reference": "aeadcf5c412332eb426c0f9b4485f6accba2a99f"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/aeadcf5c412332eb426c0f9b4485f6accba2a99f",
|
||||||
|
"reference": "aeadcf5c412332eb426c0f9b4485f6accba2a99f",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"ext-zlib": "*",
|
||||||
|
"php-64bit": "^8.2"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"brianium/paratest": "^7.7",
|
||||||
|
"ext-zip": "*",
|
||||||
|
"friendsofphp/php-cs-fixer": "^3.16",
|
||||||
|
"guzzlehttp/guzzle": "^7.5",
|
||||||
|
"mikey179/vfsstream": "^1.6",
|
||||||
|
"php-coveralls/php-coveralls": "^2.5",
|
||||||
|
"phpunit/phpunit": "^11.0",
|
||||||
|
"vimeo/psalm": "^6.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"guzzlehttp/psr7": "^2.4",
|
||||||
|
"psr/http-message": "^2.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"ZipStream\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Paul Duncan",
|
||||||
|
"email": "pabs@pablotron.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jonatan Männchen",
|
||||||
|
"email": "jonatan@maennchen.ch"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jesse Donat",
|
||||||
|
"email": "donatj@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "András Kolesár",
|
||||||
|
"email": "kolesar@kolesar.hu"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.",
|
||||||
|
"keywords": [
|
||||||
|
"stream",
|
||||||
|
"zip"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/maennchen/ZipStream-PHP/issues",
|
||||||
|
"source": "https://github.com/maennchen/ZipStream-PHP/tree/3.1.2"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/maennchen",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-01-27T12:07:53+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "markbaker/complex",
|
||||||
|
"version": "3.0.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/MarkBaker/PHPComplex.git",
|
||||||
|
"reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
|
||||||
|
"reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.2 || ^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
|
||||||
|
"phpcompatibility/php-compatibility": "^9.3",
|
||||||
|
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
|
||||||
|
"squizlabs/php_codesniffer": "^3.7"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Complex\\": "classes/src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Mark Baker",
|
||||||
|
"email": "mark@lange.demon.co.uk"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PHP Class for working with complex numbers",
|
||||||
|
"homepage": "https://github.com/MarkBaker/PHPComplex",
|
||||||
|
"keywords": [
|
||||||
|
"complex",
|
||||||
|
"mathematics"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/MarkBaker/PHPComplex/issues",
|
||||||
|
"source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.2"
|
||||||
|
},
|
||||||
|
"time": "2022-12-06T16:21:08+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "markbaker/matrix",
|
||||||
|
"version": "3.0.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/MarkBaker/PHPMatrix.git",
|
||||||
|
"reference": "728434227fe21be27ff6d86621a1b13107a2562c"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/728434227fe21be27ff6d86621a1b13107a2562c",
|
||||||
|
"reference": "728434227fe21be27ff6d86621a1b13107a2562c",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.1 || ^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
|
||||||
|
"phpcompatibility/php-compatibility": "^9.3",
|
||||||
|
"phpdocumentor/phpdocumentor": "2.*",
|
||||||
|
"phploc/phploc": "^4.0",
|
||||||
|
"phpmd/phpmd": "2.*",
|
||||||
|
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
|
||||||
|
"sebastian/phpcpd": "^4.0",
|
||||||
|
"squizlabs/php_codesniffer": "^3.7"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Matrix\\": "classes/src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Mark Baker",
|
||||||
|
"email": "mark@demon-angel.eu"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PHP Class for working with matrices",
|
||||||
|
"homepage": "https://github.com/MarkBaker/PHPMatrix",
|
||||||
|
"keywords": [
|
||||||
|
"mathematics",
|
||||||
|
"matrix",
|
||||||
|
"vector"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/MarkBaker/PHPMatrix/issues",
|
||||||
|
"source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.1"
|
||||||
|
},
|
||||||
|
"time": "2022-12-02T22:17:43+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "phpoffice/phpspreadsheet",
|
||||||
|
"version": "4.5.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
|
||||||
|
"reference": "2ea9786632e6fac1aee601b6e426bcc723d8ce13"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/2ea9786632e6fac1aee601b6e426bcc723d8ce13",
|
||||||
|
"reference": "2ea9786632e6fac1aee601b6e426bcc723d8ce13",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"composer/pcre": "^1||^2||^3",
|
||||||
|
"ext-ctype": "*",
|
||||||
|
"ext-dom": "*",
|
||||||
|
"ext-fileinfo": "*",
|
||||||
|
"ext-gd": "*",
|
||||||
|
"ext-iconv": "*",
|
||||||
|
"ext-libxml": "*",
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"ext-simplexml": "*",
|
||||||
|
"ext-xml": "*",
|
||||||
|
"ext-xmlreader": "*",
|
||||||
|
"ext-xmlwriter": "*",
|
||||||
|
"ext-zip": "*",
|
||||||
|
"ext-zlib": "*",
|
||||||
|
"maennchen/zipstream-php": "^2.1 || ^3.0",
|
||||||
|
"markbaker/complex": "^3.0",
|
||||||
|
"markbaker/matrix": "^3.0",
|
||||||
|
"php": "^8.1",
|
||||||
|
"psr/http-client": "^1.0",
|
||||||
|
"psr/http-factory": "^1.0",
|
||||||
|
"psr/simple-cache": "^1.0 || ^2.0 || ^3.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"dealerdirect/phpcodesniffer-composer-installer": "dev-main",
|
||||||
|
"dompdf/dompdf": "^2.0 || ^3.0",
|
||||||
|
"friendsofphp/php-cs-fixer": "^3.2",
|
||||||
|
"mitoteam/jpgraph": "^10.3",
|
||||||
|
"mpdf/mpdf": "^8.1.1",
|
||||||
|
"phpcompatibility/php-compatibility": "^9.3",
|
||||||
|
"phpstan/phpstan": "^1.1 || ^2.0",
|
||||||
|
"phpstan/phpstan-deprecation-rules": "^1.0 || ^2.0",
|
||||||
|
"phpstan/phpstan-phpunit": "^1.0 || ^2.0",
|
||||||
|
"phpunit/phpunit": "^10.5",
|
||||||
|
"squizlabs/php_codesniffer": "^3.7",
|
||||||
|
"tecnickcom/tcpdf": "^6.5"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"dompdf/dompdf": "Option for rendering PDF with PDF Writer",
|
||||||
|
"ext-intl": "PHP Internationalization Functions",
|
||||||
|
"mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
|
||||||
|
"mpdf/mpdf": "Option for rendering PDF with PDF Writer",
|
||||||
|
"tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Maarten Balliauw",
|
||||||
|
"homepage": "https://blog.maartenballiauw.be"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Mark Baker",
|
||||||
|
"homepage": "https://markbakeruk.net"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Franck Lefevre",
|
||||||
|
"homepage": "https://rootslabs.net"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Erik Tilt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Adrien Crivelli"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
|
||||||
|
"homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
|
||||||
|
"keywords": [
|
||||||
|
"OpenXML",
|
||||||
|
"excel",
|
||||||
|
"gnumeric",
|
||||||
|
"ods",
|
||||||
|
"php",
|
||||||
|
"spreadsheet",
|
||||||
|
"xls",
|
||||||
|
"xlsx"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
|
||||||
|
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/4.5.0"
|
||||||
|
},
|
||||||
|
"time": "2025-07-24T05:15:59+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "psr/http-client",
|
||||||
|
"version": "1.0.3",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/php-fig/http-client.git",
|
||||||
|
"reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90",
|
||||||
|
"reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.0 || ^8.0",
|
||||||
|
"psr/http-message": "^1.0 || ^2.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Psr\\Http\\Client\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "PHP-FIG",
|
||||||
|
"homepage": "https://www.php-fig.org/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Common interface for HTTP clients",
|
||||||
|
"homepage": "https://github.com/php-fig/http-client",
|
||||||
|
"keywords": [
|
||||||
|
"http",
|
||||||
|
"http-client",
|
||||||
|
"psr",
|
||||||
|
"psr-18"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/php-fig/http-client"
|
||||||
|
},
|
||||||
|
"time": "2023-09-23T14:17:50+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "psr/http-factory",
|
||||||
|
"version": "1.1.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/php-fig/http-factory.git",
|
||||||
|
"reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
|
||||||
|
"reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.1",
|
||||||
|
"psr/http-message": "^1.0 || ^2.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Psr\\Http\\Message\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "PHP-FIG",
|
||||||
|
"homepage": "https://www.php-fig.org/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PSR-17: Common interfaces for PSR-7 HTTP message factories",
|
||||||
|
"keywords": [
|
||||||
|
"factory",
|
||||||
|
"http",
|
||||||
|
"message",
|
||||||
|
"psr",
|
||||||
|
"psr-17",
|
||||||
|
"psr-7",
|
||||||
|
"request",
|
||||||
|
"response"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/php-fig/http-factory"
|
||||||
|
},
|
||||||
|
"time": "2024-04-15T12:06:14+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "psr/http-message",
|
||||||
|
"version": "2.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/php-fig/http-message.git",
|
||||||
|
"reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71",
|
||||||
|
"reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.2 || ^8.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "2.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Psr\\Http\\Message\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "PHP-FIG",
|
||||||
|
"homepage": "https://www.php-fig.org/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Common interface for HTTP messages",
|
||||||
|
"homepage": "https://github.com/php-fig/http-message",
|
||||||
|
"keywords": [
|
||||||
|
"http",
|
||||||
|
"http-message",
|
||||||
|
"psr",
|
||||||
|
"psr-7",
|
||||||
|
"request",
|
||||||
|
"response"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/php-fig/http-message/tree/2.0"
|
||||||
|
},
|
||||||
|
"time": "2023-04-04T09:54:51+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "psr/simple-cache",
|
||||||
|
"version": "3.0.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/php-fig/simple-cache.git",
|
||||||
|
"reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865",
|
||||||
|
"reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=8.0.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "3.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Psr\\SimpleCache\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "PHP-FIG",
|
||||||
|
"homepage": "https://www.php-fig.org/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Common interfaces for simple caching",
|
||||||
|
"keywords": [
|
||||||
|
"cache",
|
||||||
|
"caching",
|
||||||
|
"psr",
|
||||||
|
"psr-16",
|
||||||
|
"simple-cache"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/php-fig/simple-cache/tree/3.0.0"
|
||||||
|
},
|
||||||
|
"time": "2021-10-29T13:26:27+00:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"packages-dev": [],
|
||||||
|
"aliases": [],
|
||||||
|
"minimum-stability": "stable",
|
||||||
|
"stability-flags": {},
|
||||||
|
"prefer-stable": false,
|
||||||
|
"prefer-lowest": false,
|
||||||
|
"platform": {},
|
||||||
|
"platform-dev": {},
|
||||||
|
"plugin-api-version": "2.6.0"
|
||||||
|
}
|
||||||
BIN
vendor/composer/composer.phar
vendored
Executable file
BIN
vendor/composer/composer.phar
vendored
Executable file
Binary file not shown.
22
vendor/composer/vendor/autoload.php
vendored
Normal file
22
vendor/composer/vendor/autoload.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// autoload.php @generated by Composer
|
||||||
|
|
||||||
|
if (PHP_VERSION_ID < 50600) {
|
||||||
|
if (!headers_sent()) {
|
||||||
|
header('HTTP/1.1 500 Internal Server Error');
|
||||||
|
}
|
||||||
|
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
|
||||||
|
if (!ini_get('display_errors')) {
|
||||||
|
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||||
|
fwrite(STDERR, $err);
|
||||||
|
} elseif (!headers_sent()) {
|
||||||
|
echo $err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new RuntimeException($err);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once __DIR__ . '/composer/autoload_real.php';
|
||||||
|
|
||||||
|
return ComposerAutoloaderInit62e10e6c8df9afc192311b196c75bb33::getLoader();
|
||||||
579
vendor/composer/vendor/composer/ClassLoader.php
vendored
Normal file
579
vendor/composer/vendor/composer/ClassLoader.php
vendored
Normal file
@@ -0,0 +1,579 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Composer.
|
||||||
|
*
|
||||||
|
* (c) Nils Adermann <naderman@naderman.de>
|
||||||
|
* Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer\Autoload;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
|
||||||
|
*
|
||||||
|
* $loader = new \Composer\Autoload\ClassLoader();
|
||||||
|
*
|
||||||
|
* // register classes with namespaces
|
||||||
|
* $loader->add('Symfony\Component', __DIR__.'/component');
|
||||||
|
* $loader->add('Symfony', __DIR__.'/framework');
|
||||||
|
*
|
||||||
|
* // activate the autoloader
|
||||||
|
* $loader->register();
|
||||||
|
*
|
||||||
|
* // to enable searching the include path (eg. for PEAR packages)
|
||||||
|
* $loader->setUseIncludePath(true);
|
||||||
|
*
|
||||||
|
* In this example, if you try to use a class in the Symfony\Component
|
||||||
|
* namespace or one of its children (Symfony\Component\Console for instance),
|
||||||
|
* the autoloader will first look for the class under the component/
|
||||||
|
* directory, and it will then fallback to the framework/ directory if not
|
||||||
|
* found before giving up.
|
||||||
|
*
|
||||||
|
* This class is loosely based on the Symfony UniversalClassLoader.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
* @see https://www.php-fig.org/psr/psr-0/
|
||||||
|
* @see https://www.php-fig.org/psr/psr-4/
|
||||||
|
*/
|
||||||
|
class ClassLoader
|
||||||
|
{
|
||||||
|
/** @var \Closure(string):void */
|
||||||
|
private static $includeFile;
|
||||||
|
|
||||||
|
/** @var string|null */
|
||||||
|
private $vendorDir;
|
||||||
|
|
||||||
|
// PSR-4
|
||||||
|
/**
|
||||||
|
* @var array<string, array<string, int>>
|
||||||
|
*/
|
||||||
|
private $prefixLengthsPsr4 = array();
|
||||||
|
/**
|
||||||
|
* @var array<string, list<string>>
|
||||||
|
*/
|
||||||
|
private $prefixDirsPsr4 = array();
|
||||||
|
/**
|
||||||
|
* @var list<string>
|
||||||
|
*/
|
||||||
|
private $fallbackDirsPsr4 = array();
|
||||||
|
|
||||||
|
// PSR-0
|
||||||
|
/**
|
||||||
|
* List of PSR-0 prefixes
|
||||||
|
*
|
||||||
|
* Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
|
||||||
|
*
|
||||||
|
* @var array<string, array<string, list<string>>>
|
||||||
|
*/
|
||||||
|
private $prefixesPsr0 = array();
|
||||||
|
/**
|
||||||
|
* @var list<string>
|
||||||
|
*/
|
||||||
|
private $fallbackDirsPsr0 = array();
|
||||||
|
|
||||||
|
/** @var bool */
|
||||||
|
private $useIncludePath = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array<string, string>
|
||||||
|
*/
|
||||||
|
private $classMap = array();
|
||||||
|
|
||||||
|
/** @var bool */
|
||||||
|
private $classMapAuthoritative = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array<string, bool>
|
||||||
|
*/
|
||||||
|
private $missingClasses = array();
|
||||||
|
|
||||||
|
/** @var string|null */
|
||||||
|
private $apcuPrefix;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array<string, self>
|
||||||
|
*/
|
||||||
|
private static $registeredLoaders = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|null $vendorDir
|
||||||
|
*/
|
||||||
|
public function __construct($vendorDir = null)
|
||||||
|
{
|
||||||
|
$this->vendorDir = $vendorDir;
|
||||||
|
self::initializeIncludeClosure();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, list<string>>
|
||||||
|
*/
|
||||||
|
public function getPrefixes()
|
||||||
|
{
|
||||||
|
if (!empty($this->prefixesPsr0)) {
|
||||||
|
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
|
||||||
|
}
|
||||||
|
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, list<string>>
|
||||||
|
*/
|
||||||
|
public function getPrefixesPsr4()
|
||||||
|
{
|
||||||
|
return $this->prefixDirsPsr4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return list<string>
|
||||||
|
*/
|
||||||
|
public function getFallbackDirs()
|
||||||
|
{
|
||||||
|
return $this->fallbackDirsPsr0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return list<string>
|
||||||
|
*/
|
||||||
|
public function getFallbackDirsPsr4()
|
||||||
|
{
|
||||||
|
return $this->fallbackDirsPsr4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, string> Array of classname => path
|
||||||
|
*/
|
||||||
|
public function getClassMap()
|
||||||
|
{
|
||||||
|
return $this->classMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, string> $classMap Class to filename map
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function addClassMap(array $classMap)
|
||||||
|
{
|
||||||
|
if ($this->classMap) {
|
||||||
|
$this->classMap = array_merge($this->classMap, $classMap);
|
||||||
|
} else {
|
||||||
|
$this->classMap = $classMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a set of PSR-0 directories for a given prefix, either
|
||||||
|
* appending or prepending to the ones previously set for this prefix.
|
||||||
|
*
|
||||||
|
* @param string $prefix The prefix
|
||||||
|
* @param list<string>|string $paths The PSR-0 root directories
|
||||||
|
* @param bool $prepend Whether to prepend the directories
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function add($prefix, $paths, $prepend = false)
|
||||||
|
{
|
||||||
|
$paths = (array) $paths;
|
||||||
|
if (!$prefix) {
|
||||||
|
if ($prepend) {
|
||||||
|
$this->fallbackDirsPsr0 = array_merge(
|
||||||
|
$paths,
|
||||||
|
$this->fallbackDirsPsr0
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$this->fallbackDirsPsr0 = array_merge(
|
||||||
|
$this->fallbackDirsPsr0,
|
||||||
|
$paths
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$first = $prefix[0];
|
||||||
|
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
||||||
|
$this->prefixesPsr0[$first][$prefix] = $paths;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ($prepend) {
|
||||||
|
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||||
|
$paths,
|
||||||
|
$this->prefixesPsr0[$first][$prefix]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||||
|
$this->prefixesPsr0[$first][$prefix],
|
||||||
|
$paths
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a set of PSR-4 directories for a given namespace, either
|
||||||
|
* appending or prepending to the ones previously set for this namespace.
|
||||||
|
*
|
||||||
|
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||||
|
* @param list<string>|string $paths The PSR-4 base directories
|
||||||
|
* @param bool $prepend Whether to prepend the directories
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function addPsr4($prefix, $paths, $prepend = false)
|
||||||
|
{
|
||||||
|
$paths = (array) $paths;
|
||||||
|
if (!$prefix) {
|
||||||
|
// Register directories for the root namespace.
|
||||||
|
if ($prepend) {
|
||||||
|
$this->fallbackDirsPsr4 = array_merge(
|
||||||
|
$paths,
|
||||||
|
$this->fallbackDirsPsr4
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$this->fallbackDirsPsr4 = array_merge(
|
||||||
|
$this->fallbackDirsPsr4,
|
||||||
|
$paths
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
||||||
|
// Register directories for a new namespace.
|
||||||
|
$length = strlen($prefix);
|
||||||
|
if ('\\' !== $prefix[$length - 1]) {
|
||||||
|
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||||
|
}
|
||||||
|
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||||
|
$this->prefixDirsPsr4[$prefix] = $paths;
|
||||||
|
} elseif ($prepend) {
|
||||||
|
// Prepend directories for an already registered namespace.
|
||||||
|
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||||
|
$paths,
|
||||||
|
$this->prefixDirsPsr4[$prefix]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Append directories for an already registered namespace.
|
||||||
|
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||||
|
$this->prefixDirsPsr4[$prefix],
|
||||||
|
$paths
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a set of PSR-0 directories for a given prefix,
|
||||||
|
* replacing any others previously set for this prefix.
|
||||||
|
*
|
||||||
|
* @param string $prefix The prefix
|
||||||
|
* @param list<string>|string $paths The PSR-0 base directories
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function set($prefix, $paths)
|
||||||
|
{
|
||||||
|
if (!$prefix) {
|
||||||
|
$this->fallbackDirsPsr0 = (array) $paths;
|
||||||
|
} else {
|
||||||
|
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a set of PSR-4 directories for a given namespace,
|
||||||
|
* replacing any others previously set for this namespace.
|
||||||
|
*
|
||||||
|
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||||
|
* @param list<string>|string $paths The PSR-4 base directories
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setPsr4($prefix, $paths)
|
||||||
|
{
|
||||||
|
if (!$prefix) {
|
||||||
|
$this->fallbackDirsPsr4 = (array) $paths;
|
||||||
|
} else {
|
||||||
|
$length = strlen($prefix);
|
||||||
|
if ('\\' !== $prefix[$length - 1]) {
|
||||||
|
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||||
|
}
|
||||||
|
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||||
|
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turns on searching the include path for class files.
|
||||||
|
*
|
||||||
|
* @param bool $useIncludePath
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setUseIncludePath($useIncludePath)
|
||||||
|
{
|
||||||
|
$this->useIncludePath = $useIncludePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can be used to check if the autoloader uses the include path to check
|
||||||
|
* for classes.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function getUseIncludePath()
|
||||||
|
{
|
||||||
|
return $this->useIncludePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turns off searching the prefix and fallback directories for classes
|
||||||
|
* that have not been registered with the class map.
|
||||||
|
*
|
||||||
|
* @param bool $classMapAuthoritative
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setClassMapAuthoritative($classMapAuthoritative)
|
||||||
|
{
|
||||||
|
$this->classMapAuthoritative = $classMapAuthoritative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should class lookup fail if not found in the current class map?
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isClassMapAuthoritative()
|
||||||
|
{
|
||||||
|
return $this->classMapAuthoritative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
||||||
|
*
|
||||||
|
* @param string|null $apcuPrefix
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setApcuPrefix($apcuPrefix)
|
||||||
|
{
|
||||||
|
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The APCu prefix in use, or null if APCu caching is not enabled.
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getApcuPrefix()
|
||||||
|
{
|
||||||
|
return $this->apcuPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers this instance as an autoloader.
|
||||||
|
*
|
||||||
|
* @param bool $prepend Whether to prepend the autoloader or not
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function register($prepend = false)
|
||||||
|
{
|
||||||
|
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||||
|
|
||||||
|
if (null === $this->vendorDir) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($prepend) {
|
||||||
|
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
|
||||||
|
} else {
|
||||||
|
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||||
|
self::$registeredLoaders[$this->vendorDir] = $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregisters this instance as an autoloader.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function unregister()
|
||||||
|
{
|
||||||
|
spl_autoload_unregister(array($this, 'loadClass'));
|
||||||
|
|
||||||
|
if (null !== $this->vendorDir) {
|
||||||
|
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the given class or interface.
|
||||||
|
*
|
||||||
|
* @param string $class The name of the class
|
||||||
|
* @return true|null True if loaded, null otherwise
|
||||||
|
*/
|
||||||
|
public function loadClass($class)
|
||||||
|
{
|
||||||
|
if ($file = $this->findFile($class)) {
|
||||||
|
$includeFile = self::$includeFile;
|
||||||
|
$includeFile($file);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the path to the file where the class is defined.
|
||||||
|
*
|
||||||
|
* @param string $class The name of the class
|
||||||
|
*
|
||||||
|
* @return string|false The path if found, false otherwise
|
||||||
|
*/
|
||||||
|
public function findFile($class)
|
||||||
|
{
|
||||||
|
// class map lookup
|
||||||
|
if (isset($this->classMap[$class])) {
|
||||||
|
return $this->classMap[$class];
|
||||||
|
}
|
||||||
|
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (null !== $this->apcuPrefix) {
|
||||||
|
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
|
||||||
|
if ($hit) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = $this->findFileWithExtension($class, '.php');
|
||||||
|
|
||||||
|
// Search for Hack files if we are running on HHVM
|
||||||
|
if (false === $file && defined('HHVM_VERSION')) {
|
||||||
|
$file = $this->findFileWithExtension($class, '.hh');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null !== $this->apcuPrefix) {
|
||||||
|
apcu_add($this->apcuPrefix.$class, $file);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false === $file) {
|
||||||
|
// Remember that this class does not exist.
|
||||||
|
$this->missingClasses[$class] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the currently registered loaders keyed by their corresponding vendor directories.
|
||||||
|
*
|
||||||
|
* @return array<string, self>
|
||||||
|
*/
|
||||||
|
public static function getRegisteredLoaders()
|
||||||
|
{
|
||||||
|
return self::$registeredLoaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $class
|
||||||
|
* @param string $ext
|
||||||
|
* @return string|false
|
||||||
|
*/
|
||||||
|
private function findFileWithExtension($class, $ext)
|
||||||
|
{
|
||||||
|
// PSR-4 lookup
|
||||||
|
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
||||||
|
|
||||||
|
$first = $class[0];
|
||||||
|
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||||
|
$subPath = $class;
|
||||||
|
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
||||||
|
$subPath = substr($subPath, 0, $lastPos);
|
||||||
|
$search = $subPath . '\\';
|
||||||
|
if (isset($this->prefixDirsPsr4[$search])) {
|
||||||
|
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
||||||
|
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
||||||
|
if (file_exists($file = $dir . $pathEnd)) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PSR-4 fallback dirs
|
||||||
|
foreach ($this->fallbackDirsPsr4 as $dir) {
|
||||||
|
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PSR-0 lookup
|
||||||
|
if (false !== $pos = strrpos($class, '\\')) {
|
||||||
|
// namespaced class name
|
||||||
|
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
||||||
|
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
||||||
|
} else {
|
||||||
|
// PEAR-like class name
|
||||||
|
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($this->prefixesPsr0[$first])) {
|
||||||
|
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
||||||
|
if (0 === strpos($class, $prefix)) {
|
||||||
|
foreach ($dirs as $dir) {
|
||||||
|
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PSR-0 fallback dirs
|
||||||
|
foreach ($this->fallbackDirsPsr0 as $dir) {
|
||||||
|
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PSR-0 include paths.
|
||||||
|
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private static function initializeIncludeClosure()
|
||||||
|
{
|
||||||
|
if (self::$includeFile !== null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scope isolated include.
|
||||||
|
*
|
||||||
|
* Prevents access to $this/self from included files.
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
self::$includeFile = \Closure::bind(static function($file) {
|
||||||
|
include $file;
|
||||||
|
}, null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
396
vendor/composer/vendor/composer/InstalledVersions.php
vendored
Normal file
396
vendor/composer/vendor/composer/InstalledVersions.php
vendored
Normal file
@@ -0,0 +1,396 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Composer.
|
||||||
|
*
|
||||||
|
* (c) Nils Adermann <naderman@naderman.de>
|
||||||
|
* Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer;
|
||||||
|
|
||||||
|
use Composer\Autoload\ClassLoader;
|
||||||
|
use Composer\Semver\VersionParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is copied in every Composer installed project and available to all
|
||||||
|
*
|
||||||
|
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
|
||||||
|
*
|
||||||
|
* To require its presence, you can require `composer-runtime-api ^2.0`
|
||||||
|
*
|
||||||
|
* @final
|
||||||
|
*/
|
||||||
|
class InstalledVersions
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
private static $selfDir = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var mixed[]|null
|
||||||
|
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
|
||||||
|
*/
|
||||||
|
private static $installed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private static $installedIsLocalDir;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool|null
|
||||||
|
*/
|
||||||
|
private static $canGetVendors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array[]
|
||||||
|
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||||
|
*/
|
||||||
|
private static $installedByVendor = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of all package names which are present, either by being installed, replaced or provided
|
||||||
|
*
|
||||||
|
* @return string[]
|
||||||
|
* @psalm-return list<string>
|
||||||
|
*/
|
||||||
|
public static function getInstalledPackages()
|
||||||
|
{
|
||||||
|
$packages = array();
|
||||||
|
foreach (self::getInstalled() as $installed) {
|
||||||
|
$packages[] = array_keys($installed['versions']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (1 === \count($packages)) {
|
||||||
|
return $packages[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of all package names with a specific type e.g. 'library'
|
||||||
|
*
|
||||||
|
* @param string $type
|
||||||
|
* @return string[]
|
||||||
|
* @psalm-return list<string>
|
||||||
|
*/
|
||||||
|
public static function getInstalledPackagesByType($type)
|
||||||
|
{
|
||||||
|
$packagesByType = array();
|
||||||
|
|
||||||
|
foreach (self::getInstalled() as $installed) {
|
||||||
|
foreach ($installed['versions'] as $name => $package) {
|
||||||
|
if (isset($package['type']) && $package['type'] === $type) {
|
||||||
|
$packagesByType[] = $name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $packagesByType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the given package is installed
|
||||||
|
*
|
||||||
|
* This also returns true if the package name is provided or replaced by another package
|
||||||
|
*
|
||||||
|
* @param string $packageName
|
||||||
|
* @param bool $includeDevRequirements
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function isInstalled($packageName, $includeDevRequirements = true)
|
||||||
|
{
|
||||||
|
foreach (self::getInstalled() as $installed) {
|
||||||
|
if (isset($installed['versions'][$packageName])) {
|
||||||
|
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the given package satisfies a version constraint
|
||||||
|
*
|
||||||
|
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
|
||||||
|
*
|
||||||
|
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
|
||||||
|
*
|
||||||
|
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
|
||||||
|
* @param string $packageName
|
||||||
|
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function satisfies(VersionParser $parser, $packageName, $constraint)
|
||||||
|
{
|
||||||
|
$constraint = $parser->parseConstraints((string) $constraint);
|
||||||
|
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
|
||||||
|
|
||||||
|
return $provided->matches($constraint);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a version constraint representing all the range(s) which are installed for a given package
|
||||||
|
*
|
||||||
|
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
|
||||||
|
* whether a given version of a package is installed, and not just whether it exists
|
||||||
|
*
|
||||||
|
* @param string $packageName
|
||||||
|
* @return string Version constraint usable with composer/semver
|
||||||
|
*/
|
||||||
|
public static function getVersionRanges($packageName)
|
||||||
|
{
|
||||||
|
foreach (self::getInstalled() as $installed) {
|
||||||
|
if (!isset($installed['versions'][$packageName])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ranges = array();
|
||||||
|
if (isset($installed['versions'][$packageName]['pretty_version'])) {
|
||||||
|
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
|
||||||
|
}
|
||||||
|
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
|
||||||
|
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
|
||||||
|
}
|
||||||
|
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
|
||||||
|
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
|
||||||
|
}
|
||||||
|
if (array_key_exists('provided', $installed['versions'][$packageName])) {
|
||||||
|
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode(' || ', $ranges);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $packageName
|
||||||
|
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||||
|
*/
|
||||||
|
public static function getVersion($packageName)
|
||||||
|
{
|
||||||
|
foreach (self::getInstalled() as $installed) {
|
||||||
|
if (!isset($installed['versions'][$packageName])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($installed['versions'][$packageName]['version'])) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $installed['versions'][$packageName]['version'];
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $packageName
|
||||||
|
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||||
|
*/
|
||||||
|
public static function getPrettyVersion($packageName)
|
||||||
|
{
|
||||||
|
foreach (self::getInstalled() as $installed) {
|
||||||
|
if (!isset($installed['versions'][$packageName])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $installed['versions'][$packageName]['pretty_version'];
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $packageName
|
||||||
|
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
|
||||||
|
*/
|
||||||
|
public static function getReference($packageName)
|
||||||
|
{
|
||||||
|
foreach (self::getInstalled() as $installed) {
|
||||||
|
if (!isset($installed['versions'][$packageName])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($installed['versions'][$packageName]['reference'])) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $installed['versions'][$packageName]['reference'];
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $packageName
|
||||||
|
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
|
||||||
|
*/
|
||||||
|
public static function getInstallPath($packageName)
|
||||||
|
{
|
||||||
|
foreach (self::getInstalled() as $installed) {
|
||||||
|
if (!isset($installed['versions'][$packageName])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
|
||||||
|
*/
|
||||||
|
public static function getRootPackage()
|
||||||
|
{
|
||||||
|
$installed = self::getInstalled();
|
||||||
|
|
||||||
|
return $installed[0]['root'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the raw installed.php data for custom implementations
|
||||||
|
*
|
||||||
|
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
|
||||||
|
* @return array[]
|
||||||
|
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
|
||||||
|
*/
|
||||||
|
public static function getRawData()
|
||||||
|
{
|
||||||
|
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
|
if (null === self::$installed) {
|
||||||
|
// only require the installed.php file if this file is loaded from its dumped location,
|
||||||
|
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||||
|
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||||
|
self::$installed = include __DIR__ . '/installed.php';
|
||||||
|
} else {
|
||||||
|
self::$installed = array();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$installed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the raw data of all installed.php which are currently loaded for custom implementations
|
||||||
|
*
|
||||||
|
* @return array[]
|
||||||
|
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||||
|
*/
|
||||||
|
public static function getAllRawData()
|
||||||
|
{
|
||||||
|
return self::getInstalled();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lets you reload the static array from another file
|
||||||
|
*
|
||||||
|
* This is only useful for complex integrations in which a project needs to use
|
||||||
|
* this class but then also needs to execute another project's autoloader in process,
|
||||||
|
* and wants to ensure both projects have access to their version of installed.php.
|
||||||
|
*
|
||||||
|
* A typical case would be PHPUnit, where it would need to make sure it reads all
|
||||||
|
* the data it needs from this class, then call reload() with
|
||||||
|
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
|
||||||
|
* the project in which it runs can then also use this class safely, without
|
||||||
|
* interference between PHPUnit's dependencies and the project's dependencies.
|
||||||
|
*
|
||||||
|
* @param array[] $data A vendor/composer/installed.php data set
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
|
||||||
|
*/
|
||||||
|
public static function reload($data)
|
||||||
|
{
|
||||||
|
self::$installed = $data;
|
||||||
|
self::$installedByVendor = array();
|
||||||
|
|
||||||
|
// when using reload, we disable the duplicate protection to ensure that self::$installed data is
|
||||||
|
// always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not,
|
||||||
|
// so we have to assume it does not, and that may result in duplicate data being returned when listing
|
||||||
|
// all installed packages for example
|
||||||
|
self::$installedIsLocalDir = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private static function getSelfDir()
|
||||||
|
{
|
||||||
|
if (self::$selfDir === null) {
|
||||||
|
self::$selfDir = strtr(__DIR__, '\\', '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$selfDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array[]
|
||||||
|
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||||
|
*/
|
||||||
|
private static function getInstalled()
|
||||||
|
{
|
||||||
|
if (null === self::$canGetVendors) {
|
||||||
|
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
|
||||||
|
}
|
||||||
|
|
||||||
|
$installed = array();
|
||||||
|
$copiedLocalDir = false;
|
||||||
|
|
||||||
|
if (self::$canGetVendors) {
|
||||||
|
$selfDir = self::getSelfDir();
|
||||||
|
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
||||||
|
$vendorDir = strtr($vendorDir, '\\', '/');
|
||||||
|
if (isset(self::$installedByVendor[$vendorDir])) {
|
||||||
|
$installed[] = self::$installedByVendor[$vendorDir];
|
||||||
|
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
||||||
|
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
||||||
|
$required = require $vendorDir.'/composer/installed.php';
|
||||||
|
self::$installedByVendor[$vendorDir] = $required;
|
||||||
|
$installed[] = $required;
|
||||||
|
if (self::$installed === null && $vendorDir.'/composer' === $selfDir) {
|
||||||
|
self::$installed = $required;
|
||||||
|
self::$installedIsLocalDir = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) {
|
||||||
|
$copiedLocalDir = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === self::$installed) {
|
||||||
|
// only require the installed.php file if this file is loaded from its dumped location,
|
||||||
|
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||||
|
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||||
|
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
||||||
|
$required = require __DIR__ . '/installed.php';
|
||||||
|
self::$installed = $required;
|
||||||
|
} else {
|
||||||
|
self::$installed = array();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self::$installed !== array() && !$copiedLocalDir) {
|
||||||
|
$installed[] = self::$installed;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $installed;
|
||||||
|
}
|
||||||
|
}
|
||||||
21
vendor/composer/vendor/composer/LICENSE
vendored
Normal file
21
vendor/composer/vendor/composer/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
Copyright (c) Nils Adermann, Jordi Boggiano
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is furnished
|
||||||
|
to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
10
vendor/composer/vendor/composer/autoload_classmap.php
vendored
Normal file
10
vendor/composer/vendor/composer/autoload_classmap.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// autoload_classmap.php @generated by Composer
|
||||||
|
|
||||||
|
$vendorDir = dirname(__DIR__);
|
||||||
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||||
|
);
|
||||||
9
vendor/composer/vendor/composer/autoload_namespaces.php
vendored
Normal file
9
vendor/composer/vendor/composer/autoload_namespaces.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// autoload_namespaces.php @generated by Composer
|
||||||
|
|
||||||
|
$vendorDir = dirname(__DIR__);
|
||||||
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
|
return array(
|
||||||
|
);
|
||||||
17
vendor/composer/vendor/composer/autoload_psr4.php
vendored
Normal file
17
vendor/composer/vendor/composer/autoload_psr4.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// autoload_psr4.php @generated by Composer
|
||||||
|
|
||||||
|
$vendorDir = dirname(__DIR__);
|
||||||
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'ZipStream\\' => array($vendorDir . '/maennchen/zipstream-php/src'),
|
||||||
|
'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'),
|
||||||
|
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'),
|
||||||
|
'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'),
|
||||||
|
'PhpOffice\\PhpSpreadsheet\\' => array($vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet'),
|
||||||
|
'Matrix\\' => array($vendorDir . '/markbaker/matrix/classes/src'),
|
||||||
|
'Composer\\Pcre\\' => array($vendorDir . '/composer/pcre/src'),
|
||||||
|
'Complex\\' => array($vendorDir . '/markbaker/complex/classes/src'),
|
||||||
|
);
|
||||||
38
vendor/composer/vendor/composer/autoload_real.php
vendored
Normal file
38
vendor/composer/vendor/composer/autoload_real.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// autoload_real.php @generated by Composer
|
||||||
|
|
||||||
|
class ComposerAutoloaderInit62e10e6c8df9afc192311b196c75bb33
|
||||||
|
{
|
||||||
|
private static $loader;
|
||||||
|
|
||||||
|
public static function loadClassLoader($class)
|
||||||
|
{
|
||||||
|
if ('Composer\Autoload\ClassLoader' === $class) {
|
||||||
|
require __DIR__ . '/ClassLoader.php';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Composer\Autoload\ClassLoader
|
||||||
|
*/
|
||||||
|
public static function getLoader()
|
||||||
|
{
|
||||||
|
if (null !== self::$loader) {
|
||||||
|
return self::$loader;
|
||||||
|
}
|
||||||
|
|
||||||
|
require __DIR__ . '/platform_check.php';
|
||||||
|
|
||||||
|
spl_autoload_register(array('ComposerAutoloaderInit62e10e6c8df9afc192311b196c75bb33', 'loadClassLoader'), true, true);
|
||||||
|
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
|
||||||
|
spl_autoload_unregister(array('ComposerAutoloaderInit62e10e6c8df9afc192311b196c75bb33', 'loadClassLoader'));
|
||||||
|
|
||||||
|
require __DIR__ . '/autoload_static.php';
|
||||||
|
call_user_func(\Composer\Autoload\ComposerStaticInit62e10e6c8df9afc192311b196c75bb33::getInitializer($loader));
|
||||||
|
|
||||||
|
$loader->register(true);
|
||||||
|
|
||||||
|
return $loader;
|
||||||
|
}
|
||||||
|
}
|
||||||
81
vendor/composer/vendor/composer/autoload_static.php
vendored
Normal file
81
vendor/composer/vendor/composer/autoload_static.php
vendored
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// autoload_static.php @generated by Composer
|
||||||
|
|
||||||
|
namespace Composer\Autoload;
|
||||||
|
|
||||||
|
class ComposerStaticInit62e10e6c8df9afc192311b196c75bb33
|
||||||
|
{
|
||||||
|
public static $prefixLengthsPsr4 = array (
|
||||||
|
'Z' =>
|
||||||
|
array (
|
||||||
|
'ZipStream\\' => 10,
|
||||||
|
),
|
||||||
|
'P' =>
|
||||||
|
array (
|
||||||
|
'Psr\\SimpleCache\\' => 16,
|
||||||
|
'Psr\\Http\\Message\\' => 17,
|
||||||
|
'Psr\\Http\\Client\\' => 16,
|
||||||
|
'PhpOffice\\PhpSpreadsheet\\' => 25,
|
||||||
|
),
|
||||||
|
'M' =>
|
||||||
|
array (
|
||||||
|
'Matrix\\' => 7,
|
||||||
|
),
|
||||||
|
'C' =>
|
||||||
|
array (
|
||||||
|
'Composer\\Pcre\\' => 14,
|
||||||
|
'Complex\\' => 8,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
public static $prefixDirsPsr4 = array (
|
||||||
|
'ZipStream\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/maennchen/zipstream-php/src',
|
||||||
|
),
|
||||||
|
'Psr\\SimpleCache\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/psr/simple-cache/src',
|
||||||
|
),
|
||||||
|
'Psr\\Http\\Message\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/psr/http-factory/src',
|
||||||
|
1 => __DIR__ . '/..' . '/psr/http-message/src',
|
||||||
|
),
|
||||||
|
'Psr\\Http\\Client\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/psr/http-client/src',
|
||||||
|
),
|
||||||
|
'PhpOffice\\PhpSpreadsheet\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet',
|
||||||
|
),
|
||||||
|
'Matrix\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/markbaker/matrix/classes/src',
|
||||||
|
),
|
||||||
|
'Composer\\Pcre\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/composer/pcre/src',
|
||||||
|
),
|
||||||
|
'Complex\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/markbaker/complex/classes/src',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
public static $classMap = array (
|
||||||
|
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||||
|
);
|
||||||
|
|
||||||
|
public static function getInitializer(ClassLoader $loader)
|
||||||
|
{
|
||||||
|
return \Closure::bind(function () use ($loader) {
|
||||||
|
$loader->prefixLengthsPsr4 = ComposerStaticInit62e10e6c8df9afc192311b196c75bb33::$prefixLengthsPsr4;
|
||||||
|
$loader->prefixDirsPsr4 = ComposerStaticInit62e10e6c8df9afc192311b196c75bb33::$prefixDirsPsr4;
|
||||||
|
$loader->classMap = ComposerStaticInit62e10e6c8df9afc192311b196c75bb33::$classMap;
|
||||||
|
|
||||||
|
}, null, ClassLoader::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
614
vendor/composer/vendor/composer/installed.json
vendored
Normal file
614
vendor/composer/vendor/composer/installed.json
vendored
Normal file
@@ -0,0 +1,614 @@
|
|||||||
|
{
|
||||||
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "composer/pcre",
|
||||||
|
"version": "3.3.2",
|
||||||
|
"version_normalized": "3.3.2.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/composer/pcre.git",
|
||||||
|
"reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e",
|
||||||
|
"reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.4 || ^8.0"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"phpstan/phpstan": "<1.11.10"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpstan/phpstan": "^1.12 || ^2",
|
||||||
|
"phpstan/phpstan-strict-rules": "^1 || ^2",
|
||||||
|
"phpunit/phpunit": "^8 || ^9"
|
||||||
|
},
|
||||||
|
"time": "2024-11-12T16:29:46+00:00",
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"phpstan": {
|
||||||
|
"includes": [
|
||||||
|
"extension.neon"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-main": "3.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"installation-source": "dist",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Composer\\Pcre\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Jordi Boggiano",
|
||||||
|
"email": "j.boggiano@seld.be",
|
||||||
|
"homepage": "http://seld.be"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PCRE wrapping library that offers type-safe preg_* replacements.",
|
||||||
|
"keywords": [
|
||||||
|
"PCRE",
|
||||||
|
"preg",
|
||||||
|
"regex",
|
||||||
|
"regular expression"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/composer/pcre/issues",
|
||||||
|
"source": "https://github.com/composer/pcre/tree/3.3.2"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://packagist.com",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/composer",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"install-path": "./pcre"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "maennchen/zipstream-php",
|
||||||
|
"version": "3.1.2",
|
||||||
|
"version_normalized": "3.1.2.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/maennchen/ZipStream-PHP.git",
|
||||||
|
"reference": "aeadcf5c412332eb426c0f9b4485f6accba2a99f"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/aeadcf5c412332eb426c0f9b4485f6accba2a99f",
|
||||||
|
"reference": "aeadcf5c412332eb426c0f9b4485f6accba2a99f",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"ext-zlib": "*",
|
||||||
|
"php-64bit": "^8.2"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"brianium/paratest": "^7.7",
|
||||||
|
"ext-zip": "*",
|
||||||
|
"friendsofphp/php-cs-fixer": "^3.16",
|
||||||
|
"guzzlehttp/guzzle": "^7.5",
|
||||||
|
"mikey179/vfsstream": "^1.6",
|
||||||
|
"php-coveralls/php-coveralls": "^2.5",
|
||||||
|
"phpunit/phpunit": "^11.0",
|
||||||
|
"vimeo/psalm": "^6.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"guzzlehttp/psr7": "^2.4",
|
||||||
|
"psr/http-message": "^2.0"
|
||||||
|
},
|
||||||
|
"time": "2025-01-27T12:07:53+00:00",
|
||||||
|
"type": "library",
|
||||||
|
"installation-source": "dist",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"ZipStream\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Paul Duncan",
|
||||||
|
"email": "pabs@pablotron.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jonatan Männchen",
|
||||||
|
"email": "jonatan@maennchen.ch"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jesse Donat",
|
||||||
|
"email": "donatj@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "András Kolesár",
|
||||||
|
"email": "kolesar@kolesar.hu"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.",
|
||||||
|
"keywords": [
|
||||||
|
"stream",
|
||||||
|
"zip"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/maennchen/ZipStream-PHP/issues",
|
||||||
|
"source": "https://github.com/maennchen/ZipStream-PHP/tree/3.1.2"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/maennchen",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"install-path": "../maennchen/zipstream-php"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "markbaker/complex",
|
||||||
|
"version": "3.0.2",
|
||||||
|
"version_normalized": "3.0.2.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/MarkBaker/PHPComplex.git",
|
||||||
|
"reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
|
||||||
|
"reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.2 || ^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
|
||||||
|
"phpcompatibility/php-compatibility": "^9.3",
|
||||||
|
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
|
||||||
|
"squizlabs/php_codesniffer": "^3.7"
|
||||||
|
},
|
||||||
|
"time": "2022-12-06T16:21:08+00:00",
|
||||||
|
"type": "library",
|
||||||
|
"installation-source": "dist",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Complex\\": "classes/src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Mark Baker",
|
||||||
|
"email": "mark@lange.demon.co.uk"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PHP Class for working with complex numbers",
|
||||||
|
"homepage": "https://github.com/MarkBaker/PHPComplex",
|
||||||
|
"keywords": [
|
||||||
|
"complex",
|
||||||
|
"mathematics"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/MarkBaker/PHPComplex/issues",
|
||||||
|
"source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.2"
|
||||||
|
},
|
||||||
|
"install-path": "../markbaker/complex"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "markbaker/matrix",
|
||||||
|
"version": "3.0.1",
|
||||||
|
"version_normalized": "3.0.1.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/MarkBaker/PHPMatrix.git",
|
||||||
|
"reference": "728434227fe21be27ff6d86621a1b13107a2562c"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/728434227fe21be27ff6d86621a1b13107a2562c",
|
||||||
|
"reference": "728434227fe21be27ff6d86621a1b13107a2562c",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.1 || ^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
|
||||||
|
"phpcompatibility/php-compatibility": "^9.3",
|
||||||
|
"phpdocumentor/phpdocumentor": "2.*",
|
||||||
|
"phploc/phploc": "^4.0",
|
||||||
|
"phpmd/phpmd": "2.*",
|
||||||
|
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
|
||||||
|
"sebastian/phpcpd": "^4.0",
|
||||||
|
"squizlabs/php_codesniffer": "^3.7"
|
||||||
|
},
|
||||||
|
"time": "2022-12-02T22:17:43+00:00",
|
||||||
|
"type": "library",
|
||||||
|
"installation-source": "dist",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Matrix\\": "classes/src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Mark Baker",
|
||||||
|
"email": "mark@demon-angel.eu"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PHP Class for working with matrices",
|
||||||
|
"homepage": "https://github.com/MarkBaker/PHPMatrix",
|
||||||
|
"keywords": [
|
||||||
|
"mathematics",
|
||||||
|
"matrix",
|
||||||
|
"vector"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/MarkBaker/PHPMatrix/issues",
|
||||||
|
"source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.1"
|
||||||
|
},
|
||||||
|
"install-path": "../markbaker/matrix"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "phpoffice/phpspreadsheet",
|
||||||
|
"version": "4.5.0",
|
||||||
|
"version_normalized": "4.5.0.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
|
||||||
|
"reference": "2ea9786632e6fac1aee601b6e426bcc723d8ce13"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/2ea9786632e6fac1aee601b6e426bcc723d8ce13",
|
||||||
|
"reference": "2ea9786632e6fac1aee601b6e426bcc723d8ce13",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"composer/pcre": "^1||^2||^3",
|
||||||
|
"ext-ctype": "*",
|
||||||
|
"ext-dom": "*",
|
||||||
|
"ext-fileinfo": "*",
|
||||||
|
"ext-gd": "*",
|
||||||
|
"ext-iconv": "*",
|
||||||
|
"ext-libxml": "*",
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"ext-simplexml": "*",
|
||||||
|
"ext-xml": "*",
|
||||||
|
"ext-xmlreader": "*",
|
||||||
|
"ext-xmlwriter": "*",
|
||||||
|
"ext-zip": "*",
|
||||||
|
"ext-zlib": "*",
|
||||||
|
"maennchen/zipstream-php": "^2.1 || ^3.0",
|
||||||
|
"markbaker/complex": "^3.0",
|
||||||
|
"markbaker/matrix": "^3.0",
|
||||||
|
"php": "^8.1",
|
||||||
|
"psr/http-client": "^1.0",
|
||||||
|
"psr/http-factory": "^1.0",
|
||||||
|
"psr/simple-cache": "^1.0 || ^2.0 || ^3.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"dealerdirect/phpcodesniffer-composer-installer": "dev-main",
|
||||||
|
"dompdf/dompdf": "^2.0 || ^3.0",
|
||||||
|
"friendsofphp/php-cs-fixer": "^3.2",
|
||||||
|
"mitoteam/jpgraph": "^10.3",
|
||||||
|
"mpdf/mpdf": "^8.1.1",
|
||||||
|
"phpcompatibility/php-compatibility": "^9.3",
|
||||||
|
"phpstan/phpstan": "^1.1 || ^2.0",
|
||||||
|
"phpstan/phpstan-deprecation-rules": "^1.0 || ^2.0",
|
||||||
|
"phpstan/phpstan-phpunit": "^1.0 || ^2.0",
|
||||||
|
"phpunit/phpunit": "^10.5",
|
||||||
|
"squizlabs/php_codesniffer": "^3.7",
|
||||||
|
"tecnickcom/tcpdf": "^6.5"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"dompdf/dompdf": "Option for rendering PDF with PDF Writer",
|
||||||
|
"ext-intl": "PHP Internationalization Functions",
|
||||||
|
"mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
|
||||||
|
"mpdf/mpdf": "Option for rendering PDF with PDF Writer",
|
||||||
|
"tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer"
|
||||||
|
},
|
||||||
|
"time": "2025-07-24T05:15:59+00:00",
|
||||||
|
"type": "library",
|
||||||
|
"installation-source": "dist",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Maarten Balliauw",
|
||||||
|
"homepage": "https://blog.maartenballiauw.be"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Mark Baker",
|
||||||
|
"homepage": "https://markbakeruk.net"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Franck Lefevre",
|
||||||
|
"homepage": "https://rootslabs.net"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Erik Tilt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Adrien Crivelli"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
|
||||||
|
"homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
|
||||||
|
"keywords": [
|
||||||
|
"OpenXML",
|
||||||
|
"excel",
|
||||||
|
"gnumeric",
|
||||||
|
"ods",
|
||||||
|
"php",
|
||||||
|
"spreadsheet",
|
||||||
|
"xls",
|
||||||
|
"xlsx"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
|
||||||
|
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/4.5.0"
|
||||||
|
},
|
||||||
|
"install-path": "../phpoffice/phpspreadsheet"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "psr/http-client",
|
||||||
|
"version": "1.0.3",
|
||||||
|
"version_normalized": "1.0.3.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/php-fig/http-client.git",
|
||||||
|
"reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90",
|
||||||
|
"reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.0 || ^8.0",
|
||||||
|
"psr/http-message": "^1.0 || ^2.0"
|
||||||
|
},
|
||||||
|
"time": "2023-09-23T14:17:50+00:00",
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"installation-source": "dist",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Psr\\Http\\Client\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "PHP-FIG",
|
||||||
|
"homepage": "https://www.php-fig.org/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Common interface for HTTP clients",
|
||||||
|
"homepage": "https://github.com/php-fig/http-client",
|
||||||
|
"keywords": [
|
||||||
|
"http",
|
||||||
|
"http-client",
|
||||||
|
"psr",
|
||||||
|
"psr-18"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/php-fig/http-client"
|
||||||
|
},
|
||||||
|
"install-path": "../psr/http-client"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "psr/http-factory",
|
||||||
|
"version": "1.1.0",
|
||||||
|
"version_normalized": "1.1.0.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/php-fig/http-factory.git",
|
||||||
|
"reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
|
||||||
|
"reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.1",
|
||||||
|
"psr/http-message": "^1.0 || ^2.0"
|
||||||
|
},
|
||||||
|
"time": "2024-04-15T12:06:14+00:00",
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"installation-source": "dist",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Psr\\Http\\Message\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "PHP-FIG",
|
||||||
|
"homepage": "https://www.php-fig.org/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PSR-17: Common interfaces for PSR-7 HTTP message factories",
|
||||||
|
"keywords": [
|
||||||
|
"factory",
|
||||||
|
"http",
|
||||||
|
"message",
|
||||||
|
"psr",
|
||||||
|
"psr-17",
|
||||||
|
"psr-7",
|
||||||
|
"request",
|
||||||
|
"response"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/php-fig/http-factory"
|
||||||
|
},
|
||||||
|
"install-path": "../psr/http-factory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "psr/http-message",
|
||||||
|
"version": "2.0",
|
||||||
|
"version_normalized": "2.0.0.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/php-fig/http-message.git",
|
||||||
|
"reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71",
|
||||||
|
"reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.2 || ^8.0"
|
||||||
|
},
|
||||||
|
"time": "2023-04-04T09:54:51+00:00",
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "2.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"installation-source": "dist",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Psr\\Http\\Message\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "PHP-FIG",
|
||||||
|
"homepage": "https://www.php-fig.org/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Common interface for HTTP messages",
|
||||||
|
"homepage": "https://github.com/php-fig/http-message",
|
||||||
|
"keywords": [
|
||||||
|
"http",
|
||||||
|
"http-message",
|
||||||
|
"psr",
|
||||||
|
"psr-7",
|
||||||
|
"request",
|
||||||
|
"response"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/php-fig/http-message/tree/2.0"
|
||||||
|
},
|
||||||
|
"install-path": "../psr/http-message"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "psr/simple-cache",
|
||||||
|
"version": "3.0.0",
|
||||||
|
"version_normalized": "3.0.0.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/php-fig/simple-cache.git",
|
||||||
|
"reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865",
|
||||||
|
"reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=8.0.0"
|
||||||
|
},
|
||||||
|
"time": "2021-10-29T13:26:27+00:00",
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "3.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"installation-source": "dist",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Psr\\SimpleCache\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "PHP-FIG",
|
||||||
|
"homepage": "https://www.php-fig.org/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Common interfaces for simple caching",
|
||||||
|
"keywords": [
|
||||||
|
"cache",
|
||||||
|
"caching",
|
||||||
|
"psr",
|
||||||
|
"psr-16",
|
||||||
|
"simple-cache"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/php-fig/simple-cache/tree/3.0.0"
|
||||||
|
},
|
||||||
|
"install-path": "../psr/simple-cache"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"dev-package-names": []
|
||||||
|
}
|
||||||
104
vendor/composer/vendor/composer/installed.php
vendored
Normal file
104
vendor/composer/vendor/composer/installed.php
vendored
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
<?php return array(
|
||||||
|
'root' => array(
|
||||||
|
'name' => '__root__',
|
||||||
|
'pretty_version' => '1.0.0+no-version-set',
|
||||||
|
'version' => '1.0.0.0',
|
||||||
|
'reference' => null,
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/../../',
|
||||||
|
'aliases' => array(),
|
||||||
|
'dev' => true,
|
||||||
|
),
|
||||||
|
'versions' => array(
|
||||||
|
'__root__' => array(
|
||||||
|
'pretty_version' => '1.0.0+no-version-set',
|
||||||
|
'version' => '1.0.0.0',
|
||||||
|
'reference' => null,
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/../../',
|
||||||
|
'aliases' => array(),
|
||||||
|
'dev_requirement' => false,
|
||||||
|
),
|
||||||
|
'composer/pcre' => array(
|
||||||
|
'pretty_version' => '3.3.2',
|
||||||
|
'version' => '3.3.2.0',
|
||||||
|
'reference' => 'b2bed4734f0cc156ee1fe9c0da2550420d99a21e',
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/./pcre',
|
||||||
|
'aliases' => array(),
|
||||||
|
'dev_requirement' => false,
|
||||||
|
),
|
||||||
|
'maennchen/zipstream-php' => array(
|
||||||
|
'pretty_version' => '3.1.2',
|
||||||
|
'version' => '3.1.2.0',
|
||||||
|
'reference' => 'aeadcf5c412332eb426c0f9b4485f6accba2a99f',
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/../maennchen/zipstream-php',
|
||||||
|
'aliases' => array(),
|
||||||
|
'dev_requirement' => false,
|
||||||
|
),
|
||||||
|
'markbaker/complex' => array(
|
||||||
|
'pretty_version' => '3.0.2',
|
||||||
|
'version' => '3.0.2.0',
|
||||||
|
'reference' => '95c56caa1cf5c766ad6d65b6344b807c1e8405b9',
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/../markbaker/complex',
|
||||||
|
'aliases' => array(),
|
||||||
|
'dev_requirement' => false,
|
||||||
|
),
|
||||||
|
'markbaker/matrix' => array(
|
||||||
|
'pretty_version' => '3.0.1',
|
||||||
|
'version' => '3.0.1.0',
|
||||||
|
'reference' => '728434227fe21be27ff6d86621a1b13107a2562c',
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/../markbaker/matrix',
|
||||||
|
'aliases' => array(),
|
||||||
|
'dev_requirement' => false,
|
||||||
|
),
|
||||||
|
'phpoffice/phpspreadsheet' => array(
|
||||||
|
'pretty_version' => '4.5.0',
|
||||||
|
'version' => '4.5.0.0',
|
||||||
|
'reference' => '2ea9786632e6fac1aee601b6e426bcc723d8ce13',
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/../phpoffice/phpspreadsheet',
|
||||||
|
'aliases' => array(),
|
||||||
|
'dev_requirement' => false,
|
||||||
|
),
|
||||||
|
'psr/http-client' => array(
|
||||||
|
'pretty_version' => '1.0.3',
|
||||||
|
'version' => '1.0.3.0',
|
||||||
|
'reference' => 'bb5906edc1c324c9a05aa0873d40117941e5fa90',
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/../psr/http-client',
|
||||||
|
'aliases' => array(),
|
||||||
|
'dev_requirement' => false,
|
||||||
|
),
|
||||||
|
'psr/http-factory' => array(
|
||||||
|
'pretty_version' => '1.1.0',
|
||||||
|
'version' => '1.1.0.0',
|
||||||
|
'reference' => '2b4765fddfe3b508ac62f829e852b1501d3f6e8a',
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/../psr/http-factory',
|
||||||
|
'aliases' => array(),
|
||||||
|
'dev_requirement' => false,
|
||||||
|
),
|
||||||
|
'psr/http-message' => array(
|
||||||
|
'pretty_version' => '2.0',
|
||||||
|
'version' => '2.0.0.0',
|
||||||
|
'reference' => '402d35bcb92c70c026d1a6a9883f06b2ead23d71',
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/../psr/http-message',
|
||||||
|
'aliases' => array(),
|
||||||
|
'dev_requirement' => false,
|
||||||
|
),
|
||||||
|
'psr/simple-cache' => array(
|
||||||
|
'pretty_version' => '3.0.0',
|
||||||
|
'version' => '3.0.0.0',
|
||||||
|
'reference' => '764e0b3939f5ca87cb904f570ef9be2d78a07865',
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/../psr/simple-cache',
|
||||||
|
'aliases' => array(),
|
||||||
|
'dev_requirement' => false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
19
vendor/composer/vendor/composer/pcre/LICENSE
vendored
Normal file
19
vendor/composer/vendor/composer/pcre/LICENSE
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
Copyright (C) 2021 Composer
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
189
vendor/composer/vendor/composer/pcre/README.md
vendored
Normal file
189
vendor/composer/vendor/composer/pcre/README.md
vendored
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
composer/pcre
|
||||||
|
=============
|
||||||
|
|
||||||
|
PCRE wrapping library that offers type-safe `preg_*` replacements.
|
||||||
|
|
||||||
|
This library gives you a way to ensure `preg_*` functions do not fail silently, returning
|
||||||
|
unexpected `null`s that may not be handled.
|
||||||
|
|
||||||
|
As of 3.0 this library enforces [`PREG_UNMATCHED_AS_NULL`](#preg_unmatched_as_null) usage
|
||||||
|
for all matching and replaceCallback functions, [read more below](#preg_unmatched_as_null)
|
||||||
|
to understand the implications.
|
||||||
|
|
||||||
|
It thus makes it easier to work with static analysis tools like PHPStan or Psalm as it
|
||||||
|
simplifies and reduces the possible return values from all the `preg_*` functions which
|
||||||
|
are quite packed with edge cases. As of v2.2.0 / v3.2.0 the library also comes with a
|
||||||
|
[PHPStan extension](#phpstan-extension) for parsing regular expressions and giving you even better output types.
|
||||||
|
|
||||||
|
This library is a thin wrapper around `preg_*` functions with [some limitations](#restrictions--limitations).
|
||||||
|
If you are looking for a richer API to handle regular expressions have a look at
|
||||||
|
[rawr/t-regx](https://packagist.org/packages/rawr/t-regx) instead.
|
||||||
|
|
||||||
|
[](https://github.com/composer/pcre/actions)
|
||||||
|
|
||||||
|
|
||||||
|
Installation
|
||||||
|
------------
|
||||||
|
|
||||||
|
Install the latest version with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ composer require composer/pcre
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
------------
|
||||||
|
|
||||||
|
* PHP 7.4.0 is required for 3.x versions
|
||||||
|
* PHP 7.2.0 is required for 2.x versions
|
||||||
|
* PHP 5.3.2 is required for 1.x versions
|
||||||
|
|
||||||
|
|
||||||
|
Basic usage
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Instead of:
|
||||||
|
|
||||||
|
```php
|
||||||
|
if (preg_match('{fo+}', $string, $matches)) { ... }
|
||||||
|
if (preg_match('{fo+}', $string, $matches, PREG_OFFSET_CAPTURE)) { ... }
|
||||||
|
if (preg_match_all('{fo+}', $string, $matches)) { ... }
|
||||||
|
$newString = preg_replace('{fo+}', 'bar', $string);
|
||||||
|
$newString = preg_replace_callback('{fo+}', function ($match) { return strtoupper($match[0]); }, $string);
|
||||||
|
$newString = preg_replace_callback_array(['{fo+}' => fn ($match) => strtoupper($match[0])], $string);
|
||||||
|
$filtered = preg_grep('{[a-z]}', $elements);
|
||||||
|
$array = preg_split('{[a-z]+}', $string);
|
||||||
|
```
|
||||||
|
|
||||||
|
You can now call these on the `Preg` class:
|
||||||
|
|
||||||
|
```php
|
||||||
|
use Composer\Pcre\Preg;
|
||||||
|
|
||||||
|
if (Preg::match('{fo+}', $string, $matches)) { ... }
|
||||||
|
if (Preg::matchWithOffsets('{fo+}', $string, $matches)) { ... }
|
||||||
|
if (Preg::matchAll('{fo+}', $string, $matches)) { ... }
|
||||||
|
$newString = Preg::replace('{fo+}', 'bar', $string);
|
||||||
|
$newString = Preg::replaceCallback('{fo+}', function ($match) { return strtoupper($match[0]); }, $string);
|
||||||
|
$newString = Preg::replaceCallbackArray(['{fo+}' => fn ($match) => strtoupper($match[0])], $string);
|
||||||
|
$filtered = Preg::grep('{[a-z]}', $elements);
|
||||||
|
$array = Preg::split('{[a-z]+}', $string);
|
||||||
|
```
|
||||||
|
|
||||||
|
The main difference is if anything fails to match/replace/.., it will throw a `Composer\Pcre\PcreException`
|
||||||
|
instead of returning `null` (or false in some cases), so you can now use the return values safely relying on
|
||||||
|
the fact that they can only be strings (for replace), ints (for match) or arrays (for grep/split).
|
||||||
|
|
||||||
|
Additionally the `Preg` class provides match methods that return `bool` rather than `int`, for stricter type safety
|
||||||
|
when the number of pattern matches is not useful:
|
||||||
|
|
||||||
|
```php
|
||||||
|
use Composer\Pcre\Preg;
|
||||||
|
|
||||||
|
if (Preg::isMatch('{fo+}', $string, $matches)) // bool
|
||||||
|
if (Preg::isMatchAll('{fo+}', $string, $matches)) // bool
|
||||||
|
```
|
||||||
|
|
||||||
|
Finally the `Preg` class provides a few `*StrictGroups` method variants that ensure match groups
|
||||||
|
are always present and thus non-nullable, making it easier to write type-safe code:
|
||||||
|
|
||||||
|
```php
|
||||||
|
use Composer\Pcre\Preg;
|
||||||
|
|
||||||
|
// $matches is guaranteed to be an array of strings, if a subpattern does not match and produces a null it will throw
|
||||||
|
if (Preg::matchStrictGroups('{fo+}', $string, $matches))
|
||||||
|
if (Preg::matchAllStrictGroups('{fo+}', $string, $matches))
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** This is generally safe to use as long as you do not have optional subpatterns (i.e. `(something)?`
|
||||||
|
or `(something)*` or branches with a `|` that result in some groups not being matched at all).
|
||||||
|
A subpattern that can match an empty string like `(.*)` is **not** optional, it will be present as an
|
||||||
|
empty string in the matches. A non-matching subpattern, even if optional like `(?:foo)?` will anyway not be present in
|
||||||
|
matches so it is also not a problem to use these with `*StrictGroups` methods.
|
||||||
|
|
||||||
|
If you would prefer a slightly more verbose usage, replacing by-ref arguments by result objects, you can use the `Regex` class:
|
||||||
|
|
||||||
|
```php
|
||||||
|
use Composer\Pcre\Regex;
|
||||||
|
|
||||||
|
// this is useful when you are just interested in knowing if something matched
|
||||||
|
// as it returns a bool instead of int(1/0) for match
|
||||||
|
$bool = Regex::isMatch('{fo+}', $string);
|
||||||
|
|
||||||
|
$result = Regex::match('{fo+}', $string);
|
||||||
|
if ($result->matched) { something($result->matches); }
|
||||||
|
|
||||||
|
$result = Regex::matchWithOffsets('{fo+}', $string);
|
||||||
|
if ($result->matched) { something($result->matches); }
|
||||||
|
|
||||||
|
$result = Regex::matchAll('{fo+}', $string);
|
||||||
|
if ($result->matched && $result->count > 3) { something($result->matches); }
|
||||||
|
|
||||||
|
$newString = Regex::replace('{fo+}', 'bar', $string)->result;
|
||||||
|
$newString = Regex::replaceCallback('{fo+}', function ($match) { return strtoupper($match[0]); }, $string)->result;
|
||||||
|
$newString = Regex::replaceCallbackArray(['{fo+}' => fn ($match) => strtoupper($match[0])], $string)->result;
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that `preg_grep` and `preg_split` are only callable via the `Preg` class as they do not have
|
||||||
|
complex return types warranting a specific result object.
|
||||||
|
|
||||||
|
See the [MatchResult](src/MatchResult.php), [MatchWithOffsetsResult](src/MatchWithOffsetsResult.php), [MatchAllResult](src/MatchAllResult.php),
|
||||||
|
[MatchAllWithOffsetsResult](src/MatchAllWithOffsetsResult.php), and [ReplaceResult](src/ReplaceResult.php) class sources for more details.
|
||||||
|
|
||||||
|
Restrictions / Limitations
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
Due to type safety requirements a few restrictions are in place.
|
||||||
|
|
||||||
|
- matching using `PREG_OFFSET_CAPTURE` is made available via `matchWithOffsets` and `matchAllWithOffsets`.
|
||||||
|
You cannot pass the flag to `match`/`matchAll`.
|
||||||
|
- `Preg::split` will also reject `PREG_SPLIT_OFFSET_CAPTURE` and you should use `splitWithOffsets`
|
||||||
|
instead.
|
||||||
|
- `matchAll` rejects `PREG_SET_ORDER` as it also changes the shape of the returned matches. There
|
||||||
|
is no alternative provided as you can fairly easily code around it.
|
||||||
|
- `preg_filter` is not supported as it has a rather crazy API, most likely you should rather
|
||||||
|
use `Preg::grep` in combination with some loop and `Preg::replace`.
|
||||||
|
- `replace`, `replaceCallback` and `replaceCallbackArray` do not support an array `$subject`,
|
||||||
|
only simple strings.
|
||||||
|
- As of 2.0, the library always uses `PREG_UNMATCHED_AS_NULL` for matching, which offers [much
|
||||||
|
saner/more predictable results](#preg_unmatched_as_null). As of 3.0 the flag is also set for
|
||||||
|
`replaceCallback` and `replaceCallbackArray`.
|
||||||
|
|
||||||
|
#### PREG_UNMATCHED_AS_NULL
|
||||||
|
|
||||||
|
As of 2.0, this library always uses PREG_UNMATCHED_AS_NULL for all `match*` and `isMatch*`
|
||||||
|
functions. As of 3.0 it is also done for `replaceCallback` and `replaceCallbackArray`.
|
||||||
|
|
||||||
|
This means your matches will always contain all matching groups, either as null if unmatched
|
||||||
|
or as string if it matched.
|
||||||
|
|
||||||
|
The advantages in clarity and predictability are clearer if you compare the two outputs of
|
||||||
|
running this with and without PREG_UNMATCHED_AS_NULL in $flags:
|
||||||
|
|
||||||
|
```php
|
||||||
|
preg_match('/(a)(b)*(c)(d)*/', 'ac', $matches, $flags);
|
||||||
|
```
|
||||||
|
|
||||||
|
| no flag | PREG_UNMATCHED_AS_NULL |
|
||||||
|
| --- | --- |
|
||||||
|
| array (size=4) | array (size=5) |
|
||||||
|
| 0 => string 'ac' (length=2) | 0 => string 'ac' (length=2) |
|
||||||
|
| 1 => string 'a' (length=1) | 1 => string 'a' (length=1) |
|
||||||
|
| 2 => string '' (length=0) | 2 => null |
|
||||||
|
| 3 => string 'c' (length=1) | 3 => string 'c' (length=1) |
|
||||||
|
| | 4 => null |
|
||||||
|
| group 2 (any unmatched group preceding one that matched) is set to `''`. You cannot tell if it matched an empty string or did not match at all | group 2 is `null` when unmatched and a string if it matched, easy to check for |
|
||||||
|
| group 4 (any optional group without a matching one following) is missing altogether. So you have to check with `isset()`, but really you want `isset($m[4]) && $m[4] !== ''` for safety unless you are very careful to check that a non-optional group follows it | group 4 is always set, and null in this case as there was no match, easy to check for with `$m[4] !== null` |
|
||||||
|
|
||||||
|
PHPStan Extension
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
To use the PHPStan extension if you do not use `phpstan/extension-installer` you can include `vendor/composer/pcre/extension.neon` in your PHPStan config.
|
||||||
|
|
||||||
|
The extension provides much better type information for $matches as well as regex validation where possible.
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
|
||||||
|
composer/pcre is licensed under the MIT License, see the LICENSE file for details.
|
||||||
54
vendor/composer/vendor/composer/pcre/composer.json
vendored
Normal file
54
vendor/composer/vendor/composer/pcre/composer.json
vendored
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"name": "composer/pcre",
|
||||||
|
"description": "PCRE wrapping library that offers type-safe preg_* replacements.",
|
||||||
|
"type": "library",
|
||||||
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"pcre",
|
||||||
|
"regex",
|
||||||
|
"preg",
|
||||||
|
"regular expression"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Jordi Boggiano",
|
||||||
|
"email": "j.boggiano@seld.be",
|
||||||
|
"homepage": "http://seld.be"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"php": "^7.4 || ^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^8 || ^9",
|
||||||
|
"phpstan/phpstan": "^1.12 || ^2",
|
||||||
|
"phpstan/phpstan-strict-rules": "^1 || ^2"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"phpstan/phpstan": "<1.11.10"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Composer\\Pcre\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload-dev": {
|
||||||
|
"psr-4": {
|
||||||
|
"Composer\\Pcre\\": "tests"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-main": "3.x-dev"
|
||||||
|
},
|
||||||
|
"phpstan": {
|
||||||
|
"includes": [
|
||||||
|
"extension.neon"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": "@php vendor/bin/phpunit",
|
||||||
|
"phpstan": "@php phpstan analyse"
|
||||||
|
}
|
||||||
|
}
|
||||||
22
vendor/composer/vendor/composer/pcre/extension.neon
vendored
Normal file
22
vendor/composer/vendor/composer/pcre/extension.neon
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# composer/pcre PHPStan extensions
|
||||||
|
#
|
||||||
|
# These can be reused by third party packages by including 'vendor/composer/pcre/extension.neon'
|
||||||
|
# in your phpstan config
|
||||||
|
|
||||||
|
services:
|
||||||
|
-
|
||||||
|
class: Composer\Pcre\PHPStan\PregMatchParameterOutTypeExtension
|
||||||
|
tags:
|
||||||
|
- phpstan.staticMethodParameterOutTypeExtension
|
||||||
|
-
|
||||||
|
class: Composer\Pcre\PHPStan\PregMatchTypeSpecifyingExtension
|
||||||
|
tags:
|
||||||
|
- phpstan.typeSpecifier.staticMethodTypeSpecifyingExtension
|
||||||
|
-
|
||||||
|
class: Composer\Pcre\PHPStan\PregReplaceCallbackClosureTypeExtension
|
||||||
|
tags:
|
||||||
|
- phpstan.staticMethodParameterClosureTypeExtension
|
||||||
|
|
||||||
|
rules:
|
||||||
|
- Composer\Pcre\PHPStan\UnsafeStrictGroupsCallRule
|
||||||
|
- Composer\Pcre\PHPStan\InvalidRegexPatternRule
|
||||||
46
vendor/composer/vendor/composer/pcre/src/MatchAllResult.php
vendored
Normal file
46
vendor/composer/vendor/composer/pcre/src/MatchAllResult.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of composer/pcre.
|
||||||
|
*
|
||||||
|
* (c) Composer <https://github.com/composer>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer\Pcre;
|
||||||
|
|
||||||
|
final class MatchAllResult
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* An array of match group => list of matched strings
|
||||||
|
*
|
||||||
|
* @readonly
|
||||||
|
* @var array<int|string, list<string|null>>
|
||||||
|
*/
|
||||||
|
public $matches;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var 0|positive-int
|
||||||
|
*/
|
||||||
|
public $count;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
public $matched;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param 0|positive-int $count
|
||||||
|
* @param array<int|string, list<string|null>> $matches
|
||||||
|
*/
|
||||||
|
public function __construct(int $count, array $matches)
|
||||||
|
{
|
||||||
|
$this->matches = $matches;
|
||||||
|
$this->matched = (bool) $count;
|
||||||
|
$this->count = $count;
|
||||||
|
}
|
||||||
|
}
|
||||||
46
vendor/composer/vendor/composer/pcre/src/MatchAllStrictGroupsResult.php
vendored
Normal file
46
vendor/composer/vendor/composer/pcre/src/MatchAllStrictGroupsResult.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of composer/pcre.
|
||||||
|
*
|
||||||
|
* (c) Composer <https://github.com/composer>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer\Pcre;
|
||||||
|
|
||||||
|
final class MatchAllStrictGroupsResult
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* An array of match group => list of matched strings
|
||||||
|
*
|
||||||
|
* @readonly
|
||||||
|
* @var array<int|string, list<string>>
|
||||||
|
*/
|
||||||
|
public $matches;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var 0|positive-int
|
||||||
|
*/
|
||||||
|
public $count;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
public $matched;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param 0|positive-int $count
|
||||||
|
* @param array<list<string>> $matches
|
||||||
|
*/
|
||||||
|
public function __construct(int $count, array $matches)
|
||||||
|
{
|
||||||
|
$this->matches = $matches;
|
||||||
|
$this->matched = (bool) $count;
|
||||||
|
$this->count = $count;
|
||||||
|
}
|
||||||
|
}
|
||||||
48
vendor/composer/vendor/composer/pcre/src/MatchAllWithOffsetsResult.php
vendored
Normal file
48
vendor/composer/vendor/composer/pcre/src/MatchAllWithOffsetsResult.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of composer/pcre.
|
||||||
|
*
|
||||||
|
* (c) Composer <https://github.com/composer>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer\Pcre;
|
||||||
|
|
||||||
|
final class MatchAllWithOffsetsResult
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* An array of match group => list of matches, every match being a pair of string matched + offset in bytes (or -1 if no match)
|
||||||
|
*
|
||||||
|
* @readonly
|
||||||
|
* @var array<int|string, list<array{string|null, int}>>
|
||||||
|
* @phpstan-var array<int|string, list<array{string|null, int<-1, max>}>>
|
||||||
|
*/
|
||||||
|
public $matches;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var 0|positive-int
|
||||||
|
*/
|
||||||
|
public $count;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
public $matched;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param 0|positive-int $count
|
||||||
|
* @param array<int|string, list<array{string|null, int}>> $matches
|
||||||
|
* @phpstan-param array<int|string, list<array{string|null, int<-1, max>}>> $matches
|
||||||
|
*/
|
||||||
|
public function __construct(int $count, array $matches)
|
||||||
|
{
|
||||||
|
$this->matches = $matches;
|
||||||
|
$this->matched = (bool) $count;
|
||||||
|
$this->count = $count;
|
||||||
|
}
|
||||||
|
}
|
||||||
39
vendor/composer/vendor/composer/pcre/src/MatchResult.php
vendored
Normal file
39
vendor/composer/vendor/composer/pcre/src/MatchResult.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of composer/pcre.
|
||||||
|
*
|
||||||
|
* (c) Composer <https://github.com/composer>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer\Pcre;
|
||||||
|
|
||||||
|
final class MatchResult
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* An array of match group => string matched
|
||||||
|
*
|
||||||
|
* @readonly
|
||||||
|
* @var array<int|string, string|null>
|
||||||
|
*/
|
||||||
|
public $matches;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
public $matched;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param 0|positive-int $count
|
||||||
|
* @param array<string|null> $matches
|
||||||
|
*/
|
||||||
|
public function __construct(int $count, array $matches)
|
||||||
|
{
|
||||||
|
$this->matches = $matches;
|
||||||
|
$this->matched = (bool) $count;
|
||||||
|
}
|
||||||
|
}
|
||||||
39
vendor/composer/vendor/composer/pcre/src/MatchStrictGroupsResult.php
vendored
Normal file
39
vendor/composer/vendor/composer/pcre/src/MatchStrictGroupsResult.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of composer/pcre.
|
||||||
|
*
|
||||||
|
* (c) Composer <https://github.com/composer>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer\Pcre;
|
||||||
|
|
||||||
|
final class MatchStrictGroupsResult
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* An array of match group => string matched
|
||||||
|
*
|
||||||
|
* @readonly
|
||||||
|
* @var array<int|string, string>
|
||||||
|
*/
|
||||||
|
public $matches;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
public $matched;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param 0|positive-int $count
|
||||||
|
* @param array<string> $matches
|
||||||
|
*/
|
||||||
|
public function __construct(int $count, array $matches)
|
||||||
|
{
|
||||||
|
$this->matches = $matches;
|
||||||
|
$this->matched = (bool) $count;
|
||||||
|
}
|
||||||
|
}
|
||||||
41
vendor/composer/vendor/composer/pcre/src/MatchWithOffsetsResult.php
vendored
Normal file
41
vendor/composer/vendor/composer/pcre/src/MatchWithOffsetsResult.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of composer/pcre.
|
||||||
|
*
|
||||||
|
* (c) Composer <https://github.com/composer>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer\Pcre;
|
||||||
|
|
||||||
|
final class MatchWithOffsetsResult
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* An array of match group => pair of string matched + offset in bytes (or -1 if no match)
|
||||||
|
*
|
||||||
|
* @readonly
|
||||||
|
* @var array<int|string, array{string|null, int}>
|
||||||
|
* @phpstan-var array<int|string, array{string|null, int<-1, max>}>
|
||||||
|
*/
|
||||||
|
public $matches;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
public $matched;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param 0|positive-int $count
|
||||||
|
* @param array<array{string|null, int}> $matches
|
||||||
|
* @phpstan-param array<int|string, array{string|null, int<-1, max>}> $matches
|
||||||
|
*/
|
||||||
|
public function __construct(int $count, array $matches)
|
||||||
|
{
|
||||||
|
$this->matches = $matches;
|
||||||
|
$this->matched = (bool) $count;
|
||||||
|
}
|
||||||
|
}
|
||||||
142
vendor/composer/vendor/composer/pcre/src/PHPStan/InvalidRegexPatternRule.php
vendored
Normal file
142
vendor/composer/vendor/composer/pcre/src/PHPStan/InvalidRegexPatternRule.php
vendored
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
<?php declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Composer\Pcre\PHPStan;
|
||||||
|
|
||||||
|
use Composer\Pcre\Preg;
|
||||||
|
use Composer\Pcre\Regex;
|
||||||
|
use Composer\Pcre\PcreException;
|
||||||
|
use Nette\Utils\RegexpException;
|
||||||
|
use Nette\Utils\Strings;
|
||||||
|
use PhpParser\Node;
|
||||||
|
use PhpParser\Node\Expr\StaticCall;
|
||||||
|
use PhpParser\Node\Name\FullyQualified;
|
||||||
|
use PHPStan\Analyser\Scope;
|
||||||
|
use PHPStan\Rules\Rule;
|
||||||
|
use PHPStan\Rules\RuleErrorBuilder;
|
||||||
|
use function in_array;
|
||||||
|
use function sprintf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy of PHPStan's RegularExpressionPatternRule
|
||||||
|
*
|
||||||
|
* @implements Rule<StaticCall>
|
||||||
|
*/
|
||||||
|
class InvalidRegexPatternRule implements Rule
|
||||||
|
{
|
||||||
|
public function getNodeType(): string
|
||||||
|
{
|
||||||
|
return StaticCall::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processNode(Node $node, Scope $scope): array
|
||||||
|
{
|
||||||
|
$patterns = $this->extractPatterns($node, $scope);
|
||||||
|
|
||||||
|
$errors = [];
|
||||||
|
foreach ($patterns as $pattern) {
|
||||||
|
$errorMessage = $this->validatePattern($pattern);
|
||||||
|
if ($errorMessage === null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$errors[] = RuleErrorBuilder::message(sprintf('Regex pattern is invalid: %s', $errorMessage))->identifier('regexp.pattern')->build();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
private function extractPatterns(StaticCall $node, Scope $scope): array
|
||||||
|
{
|
||||||
|
if (!$node->class instanceof FullyQualified) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
$isRegex = $node->class->toString() === Regex::class;
|
||||||
|
$isPreg = $node->class->toString() === Preg::class;
|
||||||
|
if (!$isRegex && !$isPreg) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
if (!$node->name instanceof Node\Identifier || !Preg::isMatch('{^(match|isMatch|grep|replace|split)}', $node->name->name)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$functionName = $node->name->name;
|
||||||
|
if (!isset($node->getArgs()[0])) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$patternNode = $node->getArgs()[0]->value;
|
||||||
|
$patternType = $scope->getType($patternNode);
|
||||||
|
|
||||||
|
$patternStrings = [];
|
||||||
|
|
||||||
|
foreach ($patternType->getConstantStrings() as $constantStringType) {
|
||||||
|
if ($functionName === 'replaceCallbackArray') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$patternStrings[] = $constantStringType->getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($patternType->getConstantArrays() as $constantArrayType) {
|
||||||
|
if (
|
||||||
|
in_array($functionName, [
|
||||||
|
'replace',
|
||||||
|
'replaceCallback',
|
||||||
|
], true)
|
||||||
|
) {
|
||||||
|
foreach ($constantArrayType->getValueTypes() as $arrayKeyType) {
|
||||||
|
foreach ($arrayKeyType->getConstantStrings() as $constantString) {
|
||||||
|
$patternStrings[] = $constantString->getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($functionName !== 'replaceCallbackArray') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($constantArrayType->getKeyTypes() as $arrayKeyType) {
|
||||||
|
foreach ($arrayKeyType->getConstantStrings() as $constantString) {
|
||||||
|
$patternStrings[] = $constantString->getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $patternStrings;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function validatePattern(string $pattern): ?string
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$msg = null;
|
||||||
|
$prev = set_error_handler(function (int $severity, string $message, string $file) use (&$msg): bool {
|
||||||
|
$msg = preg_replace("#^preg_match(_all)?\\(.*?\\): #", '', $message);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($pattern === '') {
|
||||||
|
return 'Empty string is not a valid regular expression';
|
||||||
|
}
|
||||||
|
|
||||||
|
Preg::match($pattern, '');
|
||||||
|
if ($msg !== null) {
|
||||||
|
return $msg;
|
||||||
|
}
|
||||||
|
} catch (PcreException $e) {
|
||||||
|
if ($e->getCode() === PREG_INTERNAL_ERROR && $msg !== null) {
|
||||||
|
return $msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
return preg_replace('{.*? failed executing ".*": }', '', $e->getMessage());
|
||||||
|
} finally {
|
||||||
|
restore_error_handler();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
70
vendor/composer/vendor/composer/pcre/src/PHPStan/PregMatchFlags.php
vendored
Normal file
70
vendor/composer/vendor/composer/pcre/src/PHPStan/PregMatchFlags.php
vendored
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Composer\Pcre\PHPStan;
|
||||||
|
|
||||||
|
use PHPStan\Analyser\Scope;
|
||||||
|
use PHPStan\Type\ArrayType;
|
||||||
|
use PHPStan\Type\Constant\ConstantArrayType;
|
||||||
|
use PHPStan\Type\Constant\ConstantIntegerType;
|
||||||
|
use PHPStan\Type\IntersectionType;
|
||||||
|
use PHPStan\Type\TypeCombinator;
|
||||||
|
use PHPStan\Type\Type;
|
||||||
|
use PhpParser\Node\Arg;
|
||||||
|
use PHPStan\Type\Php\RegexArrayShapeMatcher;
|
||||||
|
use PHPStan\Type\TypeTraverser;
|
||||||
|
use PHPStan\Type\UnionType;
|
||||||
|
|
||||||
|
final class PregMatchFlags
|
||||||
|
{
|
||||||
|
static public function getType(?Arg $flagsArg, Scope $scope): ?Type
|
||||||
|
{
|
||||||
|
if ($flagsArg === null) {
|
||||||
|
return new ConstantIntegerType(PREG_UNMATCHED_AS_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
$flagsType = $scope->getType($flagsArg->value);
|
||||||
|
|
||||||
|
$constantScalars = $flagsType->getConstantScalarValues();
|
||||||
|
if ($constantScalars === []) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$internalFlagsTypes = [];
|
||||||
|
foreach ($flagsType->getConstantScalarValues() as $constantScalarValue) {
|
||||||
|
if (!is_int($constantScalarValue)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$internalFlagsTypes[] = new ConstantIntegerType($constantScalarValue | PREG_UNMATCHED_AS_NULL);
|
||||||
|
}
|
||||||
|
return TypeCombinator::union(...$internalFlagsTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function removeNullFromMatches(Type $matchesType): Type
|
||||||
|
{
|
||||||
|
return TypeTraverser::map($matchesType, static function (Type $type, callable $traverse): Type {
|
||||||
|
if ($type instanceof UnionType || $type instanceof IntersectionType) {
|
||||||
|
return $traverse($type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($type instanceof ConstantArrayType) {
|
||||||
|
return new ConstantArrayType(
|
||||||
|
$type->getKeyTypes(),
|
||||||
|
array_map(static function (Type $valueType) use ($traverse): Type {
|
||||||
|
return $traverse($valueType);
|
||||||
|
}, $type->getValueTypes()),
|
||||||
|
$type->getNextAutoIndexes(),
|
||||||
|
[],
|
||||||
|
$type->isList()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($type instanceof ArrayType) {
|
||||||
|
return new ArrayType($type->getKeyType(), $traverse($type->getItemType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return TypeCombinator::removeNull($type);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
65
vendor/composer/vendor/composer/pcre/src/PHPStan/PregMatchParameterOutTypeExtension.php
vendored
Normal file
65
vendor/composer/vendor/composer/pcre/src/PHPStan/PregMatchParameterOutTypeExtension.php
vendored
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Composer\Pcre\PHPStan;
|
||||||
|
|
||||||
|
use Composer\Pcre\Preg;
|
||||||
|
use PhpParser\Node\Expr\StaticCall;
|
||||||
|
use PHPStan\Analyser\Scope;
|
||||||
|
use PHPStan\Reflection\MethodReflection;
|
||||||
|
use PHPStan\Reflection\ParameterReflection;
|
||||||
|
use PHPStan\TrinaryLogic;
|
||||||
|
use PHPStan\Type\Php\RegexArrayShapeMatcher;
|
||||||
|
use PHPStan\Type\StaticMethodParameterOutTypeExtension;
|
||||||
|
use PHPStan\Type\Type;
|
||||||
|
|
||||||
|
final class PregMatchParameterOutTypeExtension implements StaticMethodParameterOutTypeExtension
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var RegexArrayShapeMatcher
|
||||||
|
*/
|
||||||
|
private $regexShapeMatcher;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
RegexArrayShapeMatcher $regexShapeMatcher
|
||||||
|
)
|
||||||
|
{
|
||||||
|
$this->regexShapeMatcher = $regexShapeMatcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isStaticMethodSupported(MethodReflection $methodReflection, ParameterReflection $parameter): bool
|
||||||
|
{
|
||||||
|
return
|
||||||
|
$methodReflection->getDeclaringClass()->getName() === Preg::class
|
||||||
|
&& in_array($methodReflection->getName(), [
|
||||||
|
'match', 'isMatch', 'matchStrictGroups', 'isMatchStrictGroups',
|
||||||
|
'matchAll', 'isMatchAll', 'matchAllStrictGroups', 'isMatchAllStrictGroups'
|
||||||
|
], true)
|
||||||
|
&& $parameter->getName() === 'matches';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParameterOutTypeFromStaticMethodCall(MethodReflection $methodReflection, StaticCall $methodCall, ParameterReflection $parameter, Scope $scope): ?Type
|
||||||
|
{
|
||||||
|
$args = $methodCall->getArgs();
|
||||||
|
$patternArg = $args[0] ?? null;
|
||||||
|
$matchesArg = $args[2] ?? null;
|
||||||
|
$flagsArg = $args[3] ?? null;
|
||||||
|
|
||||||
|
if (
|
||||||
|
$patternArg === null || $matchesArg === null
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$flagsType = PregMatchFlags::getType($flagsArg, $scope);
|
||||||
|
if ($flagsType === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stripos($methodReflection->getName(), 'matchAll') !== false) {
|
||||||
|
return $this->regexShapeMatcher->matchAllExpr($patternArg->value, $flagsType, TrinaryLogic::createMaybe(), $scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->regexShapeMatcher->matchExpr($patternArg->value, $flagsType, TrinaryLogic::createMaybe(), $scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
119
vendor/composer/vendor/composer/pcre/src/PHPStan/PregMatchTypeSpecifyingExtension.php
vendored
Normal file
119
vendor/composer/vendor/composer/pcre/src/PHPStan/PregMatchTypeSpecifyingExtension.php
vendored
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Composer\Pcre\PHPStan;
|
||||||
|
|
||||||
|
use Composer\Pcre\Preg;
|
||||||
|
use PhpParser\Node\Expr\StaticCall;
|
||||||
|
use PHPStan\Analyser\Scope;
|
||||||
|
use PHPStan\Analyser\SpecifiedTypes;
|
||||||
|
use PHPStan\Analyser\TypeSpecifier;
|
||||||
|
use PHPStan\Analyser\TypeSpecifierAwareExtension;
|
||||||
|
use PHPStan\Analyser\TypeSpecifierContext;
|
||||||
|
use PHPStan\Reflection\MethodReflection;
|
||||||
|
use PHPStan\TrinaryLogic;
|
||||||
|
use PHPStan\Type\Constant\ConstantArrayType;
|
||||||
|
use PHPStan\Type\Php\RegexArrayShapeMatcher;
|
||||||
|
use PHPStan\Type\StaticMethodTypeSpecifyingExtension;
|
||||||
|
use PHPStan\Type\TypeCombinator;
|
||||||
|
use PHPStan\Type\Type;
|
||||||
|
|
||||||
|
final class PregMatchTypeSpecifyingExtension implements StaticMethodTypeSpecifyingExtension, TypeSpecifierAwareExtension
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var TypeSpecifier
|
||||||
|
*/
|
||||||
|
private $typeSpecifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var RegexArrayShapeMatcher
|
||||||
|
*/
|
||||||
|
private $regexShapeMatcher;
|
||||||
|
|
||||||
|
public function __construct(RegexArrayShapeMatcher $regexShapeMatcher)
|
||||||
|
{
|
||||||
|
$this->regexShapeMatcher = $regexShapeMatcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void
|
||||||
|
{
|
||||||
|
$this->typeSpecifier = $typeSpecifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getClass(): string
|
||||||
|
{
|
||||||
|
return Preg::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isStaticMethodSupported(MethodReflection $methodReflection, StaticCall $node, TypeSpecifierContext $context): bool
|
||||||
|
{
|
||||||
|
return in_array($methodReflection->getName(), [
|
||||||
|
'match', 'isMatch', 'matchStrictGroups', 'isMatchStrictGroups',
|
||||||
|
'matchAll', 'isMatchAll', 'matchAllStrictGroups', 'isMatchAllStrictGroups'
|
||||||
|
], true)
|
||||||
|
&& !$context->null();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function specifyTypes(MethodReflection $methodReflection, StaticCall $node, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes
|
||||||
|
{
|
||||||
|
$args = $node->getArgs();
|
||||||
|
$patternArg = $args[0] ?? null;
|
||||||
|
$matchesArg = $args[2] ?? null;
|
||||||
|
$flagsArg = $args[3] ?? null;
|
||||||
|
|
||||||
|
if (
|
||||||
|
$patternArg === null || $matchesArg === null
|
||||||
|
) {
|
||||||
|
return new SpecifiedTypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
$flagsType = PregMatchFlags::getType($flagsArg, $scope);
|
||||||
|
if ($flagsType === null) {
|
||||||
|
return new SpecifiedTypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stripos($methodReflection->getName(), 'matchAll') !== false) {
|
||||||
|
$matchedType = $this->regexShapeMatcher->matchAllExpr($patternArg->value, $flagsType, TrinaryLogic::createFromBoolean($context->true()), $scope);
|
||||||
|
} else {
|
||||||
|
$matchedType = $this->regexShapeMatcher->matchExpr($patternArg->value, $flagsType, TrinaryLogic::createFromBoolean($context->true()), $scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($matchedType === null) {
|
||||||
|
return new SpecifiedTypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
in_array($methodReflection->getName(), ['matchStrictGroups', 'isMatchStrictGroups', 'matchAllStrictGroups', 'isMatchAllStrictGroups'], true)
|
||||||
|
) {
|
||||||
|
$matchedType = PregMatchFlags::removeNullFromMatches($matchedType);
|
||||||
|
}
|
||||||
|
|
||||||
|
$overwrite = false;
|
||||||
|
if ($context->false()) {
|
||||||
|
$overwrite = true;
|
||||||
|
$context = $context->negate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// @phpstan-ignore function.alreadyNarrowedType
|
||||||
|
if (method_exists('PHPStan\Analyser\SpecifiedTypes', 'setRootExpr')) {
|
||||||
|
$typeSpecifier = $this->typeSpecifier->create(
|
||||||
|
$matchesArg->value,
|
||||||
|
$matchedType,
|
||||||
|
$context,
|
||||||
|
$scope
|
||||||
|
)->setRootExpr($node);
|
||||||
|
|
||||||
|
return $overwrite ? $typeSpecifier->setAlwaysOverwriteTypes() : $typeSpecifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @phpstan-ignore arguments.count
|
||||||
|
return $this->typeSpecifier->create(
|
||||||
|
$matchesArg->value,
|
||||||
|
$matchedType,
|
||||||
|
$context,
|
||||||
|
// @phpstan-ignore argument.type
|
||||||
|
$overwrite,
|
||||||
|
$scope,
|
||||||
|
$node
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
91
vendor/composer/vendor/composer/pcre/src/PHPStan/PregReplaceCallbackClosureTypeExtension.php
vendored
Normal file
91
vendor/composer/vendor/composer/pcre/src/PHPStan/PregReplaceCallbackClosureTypeExtension.php
vendored
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Composer\Pcre\PHPStan;
|
||||||
|
|
||||||
|
use Composer\Pcre\Preg;
|
||||||
|
use Composer\Pcre\Regex;
|
||||||
|
use PhpParser\Node\Expr\StaticCall;
|
||||||
|
use PHPStan\Analyser\Scope;
|
||||||
|
use PHPStan\Reflection\MethodReflection;
|
||||||
|
use PHPStan\Reflection\Native\NativeParameterReflection;
|
||||||
|
use PHPStan\Reflection\ParameterReflection;
|
||||||
|
use PHPStan\TrinaryLogic;
|
||||||
|
use PHPStan\Type\ClosureType;
|
||||||
|
use PHPStan\Type\Constant\ConstantArrayType;
|
||||||
|
use PHPStan\Type\Php\RegexArrayShapeMatcher;
|
||||||
|
use PHPStan\Type\StaticMethodParameterClosureTypeExtension;
|
||||||
|
use PHPStan\Type\StringType;
|
||||||
|
use PHPStan\Type\TypeCombinator;
|
||||||
|
use PHPStan\Type\Type;
|
||||||
|
|
||||||
|
final class PregReplaceCallbackClosureTypeExtension implements StaticMethodParameterClosureTypeExtension
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var RegexArrayShapeMatcher
|
||||||
|
*/
|
||||||
|
private $regexShapeMatcher;
|
||||||
|
|
||||||
|
public function __construct(RegexArrayShapeMatcher $regexShapeMatcher)
|
||||||
|
{
|
||||||
|
$this->regexShapeMatcher = $regexShapeMatcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isStaticMethodSupported(MethodReflection $methodReflection, ParameterReflection $parameter): bool
|
||||||
|
{
|
||||||
|
return in_array($methodReflection->getDeclaringClass()->getName(), [Preg::class, Regex::class], true)
|
||||||
|
&& in_array($methodReflection->getName(), ['replaceCallback', 'replaceCallbackStrictGroups'], true)
|
||||||
|
&& $parameter->getName() === 'replacement';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTypeFromStaticMethodCall(MethodReflection $methodReflection, StaticCall $methodCall, ParameterReflection $parameter, Scope $scope): ?Type
|
||||||
|
{
|
||||||
|
$args = $methodCall->getArgs();
|
||||||
|
$patternArg = $args[0] ?? null;
|
||||||
|
$flagsArg = $args[5] ?? null;
|
||||||
|
|
||||||
|
if (
|
||||||
|
$patternArg === null
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$flagsType = PregMatchFlags::getType($flagsArg, $scope);
|
||||||
|
|
||||||
|
$matchesType = $this->regexShapeMatcher->matchExpr($patternArg->value, $flagsType, TrinaryLogic::createYes(), $scope);
|
||||||
|
if ($matchesType === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($methodReflection->getName() === 'replaceCallbackStrictGroups' && count($matchesType->getConstantArrays()) === 1) {
|
||||||
|
$matchesType = $matchesType->getConstantArrays()[0];
|
||||||
|
$matchesType = new ConstantArrayType(
|
||||||
|
$matchesType->getKeyTypes(),
|
||||||
|
array_map(static function (Type $valueType): Type {
|
||||||
|
if (count($valueType->getConstantArrays()) === 1) {
|
||||||
|
$valueTypeArray = $valueType->getConstantArrays()[0];
|
||||||
|
return new ConstantArrayType(
|
||||||
|
$valueTypeArray->getKeyTypes(),
|
||||||
|
array_map(static function (Type $valueType): Type {
|
||||||
|
return TypeCombinator::removeNull($valueType);
|
||||||
|
}, $valueTypeArray->getValueTypes()),
|
||||||
|
$valueTypeArray->getNextAutoIndexes(),
|
||||||
|
[],
|
||||||
|
$valueTypeArray->isList()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return TypeCombinator::removeNull($valueType);
|
||||||
|
}, $matchesType->getValueTypes()),
|
||||||
|
$matchesType->getNextAutoIndexes(),
|
||||||
|
[],
|
||||||
|
$matchesType->isList()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ClosureType(
|
||||||
|
[
|
||||||
|
new NativeParameterReflection($parameter->getName(), $parameter->isOptional(), $matchesType, $parameter->passedByReference(), $parameter->isVariadic(), $parameter->getDefaultValue()),
|
||||||
|
],
|
||||||
|
new StringType()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
112
vendor/composer/vendor/composer/pcre/src/PHPStan/UnsafeStrictGroupsCallRule.php
vendored
Normal file
112
vendor/composer/vendor/composer/pcre/src/PHPStan/UnsafeStrictGroupsCallRule.php
vendored
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Composer\Pcre\PHPStan;
|
||||||
|
|
||||||
|
use Composer\Pcre\Preg;
|
||||||
|
use Composer\Pcre\Regex;
|
||||||
|
use PhpParser\Node;
|
||||||
|
use PhpParser\Node\Expr\StaticCall;
|
||||||
|
use PhpParser\Node\Name\FullyQualified;
|
||||||
|
use PHPStan\Analyser\Scope;
|
||||||
|
use PHPStan\Analyser\SpecifiedTypes;
|
||||||
|
use PHPStan\Rules\Rule;
|
||||||
|
use PHPStan\Rules\RuleErrorBuilder;
|
||||||
|
use PHPStan\TrinaryLogic;
|
||||||
|
use PHPStan\Type\ObjectType;
|
||||||
|
use PHPStan\Type\Type;
|
||||||
|
use PHPStan\Type\TypeCombinator;
|
||||||
|
use PHPStan\Type\Php\RegexArrayShapeMatcher;
|
||||||
|
use function sprintf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @implements Rule<StaticCall>
|
||||||
|
*/
|
||||||
|
final class UnsafeStrictGroupsCallRule implements Rule
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var RegexArrayShapeMatcher
|
||||||
|
*/
|
||||||
|
private $regexShapeMatcher;
|
||||||
|
|
||||||
|
public function __construct(RegexArrayShapeMatcher $regexShapeMatcher)
|
||||||
|
{
|
||||||
|
$this->regexShapeMatcher = $regexShapeMatcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getNodeType(): string
|
||||||
|
{
|
||||||
|
return StaticCall::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processNode(Node $node, Scope $scope): array
|
||||||
|
{
|
||||||
|
if (!$node->class instanceof FullyQualified) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
$isRegex = $node->class->toString() === Regex::class;
|
||||||
|
$isPreg = $node->class->toString() === Preg::class;
|
||||||
|
if (!$isRegex && !$isPreg) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
if (!$node->name instanceof Node\Identifier || !in_array($node->name->name, ['matchStrictGroups', 'isMatchStrictGroups', 'matchAllStrictGroups', 'isMatchAllStrictGroups'], true)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$args = $node->getArgs();
|
||||||
|
if (!isset($args[0])) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$patternArg = $args[0] ?? null;
|
||||||
|
if ($isPreg) {
|
||||||
|
if (!isset($args[2])) { // no matches set, skip as the matches won't be used anyway
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
$flagsArg = $args[3] ?? null;
|
||||||
|
} else {
|
||||||
|
$flagsArg = $args[2] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($patternArg === null) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$flagsType = PregMatchFlags::getType($flagsArg, $scope);
|
||||||
|
if ($flagsType === null) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$matchedType = $this->regexShapeMatcher->matchExpr($patternArg->value, $flagsType, TrinaryLogic::createYes(), $scope);
|
||||||
|
if ($matchedType === null) {
|
||||||
|
return [
|
||||||
|
RuleErrorBuilder::message(sprintf('The %s call is potentially unsafe as $matches\' type could not be inferred.', $node->name->name))
|
||||||
|
->identifier('composerPcre.maybeUnsafeStrictGroups')
|
||||||
|
->build(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($matchedType->getConstantArrays()) === 1) {
|
||||||
|
$matchedType = $matchedType->getConstantArrays()[0];
|
||||||
|
$nullableGroups = [];
|
||||||
|
foreach ($matchedType->getValueTypes() as $index => $type) {
|
||||||
|
if (TypeCombinator::containsNull($type)) {
|
||||||
|
$nullableGroups[] = $matchedType->getKeyTypes()[$index]->getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (\count($nullableGroups) > 0) {
|
||||||
|
return [
|
||||||
|
RuleErrorBuilder::message(sprintf(
|
||||||
|
'The %s call is unsafe as match group%s "%s" %s optional and may be null.',
|
||||||
|
$node->name->name,
|
||||||
|
\count($nullableGroups) > 1 ? 's' : '',
|
||||||
|
implode('", "', $nullableGroups),
|
||||||
|
\count($nullableGroups) > 1 ? 'are' : 'is'
|
||||||
|
))->identifier('composerPcre.unsafeStrictGroups')->build(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
55
vendor/composer/vendor/composer/pcre/src/PcreException.php
vendored
Normal file
55
vendor/composer/vendor/composer/pcre/src/PcreException.php
vendored
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of composer/pcre.
|
||||||
|
*
|
||||||
|
* (c) Composer <https://github.com/composer>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer\Pcre;
|
||||||
|
|
||||||
|
class PcreException extends \RuntimeException
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param string $function
|
||||||
|
* @param string|string[] $pattern
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public static function fromFunction($function, $pattern)
|
||||||
|
{
|
||||||
|
$code = preg_last_error();
|
||||||
|
|
||||||
|
if (is_array($pattern)) {
|
||||||
|
$pattern = implode(', ', $pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new PcreException($function.'(): failed executing "'.$pattern.'": '.self::pcreLastErrorMessage($code), $code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $code
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private static function pcreLastErrorMessage($code)
|
||||||
|
{
|
||||||
|
if (function_exists('preg_last_error_msg')) {
|
||||||
|
return preg_last_error_msg();
|
||||||
|
}
|
||||||
|
|
||||||
|
$constants = get_defined_constants(true);
|
||||||
|
if (!isset($constants['pcre']) || !is_array($constants['pcre'])) {
|
||||||
|
return 'UNDEFINED_ERROR';
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($constants['pcre'] as $const => $val) {
|
||||||
|
if ($val === $code && substr($const, -6) === '_ERROR') {
|
||||||
|
return $const;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'UNDEFINED_ERROR';
|
||||||
|
}
|
||||||
|
}
|
||||||
430
vendor/composer/vendor/composer/pcre/src/Preg.php
vendored
Normal file
430
vendor/composer/vendor/composer/pcre/src/Preg.php
vendored
Normal file
@@ -0,0 +1,430 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of composer/pcre.
|
||||||
|
*
|
||||||
|
* (c) Composer <https://github.com/composer>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer\Pcre;
|
||||||
|
|
||||||
|
class Preg
|
||||||
|
{
|
||||||
|
/** @internal */
|
||||||
|
public const ARRAY_MSG = '$subject as an array is not supported. You can use \'foreach\' instead.';
|
||||||
|
/** @internal */
|
||||||
|
public const INVALID_TYPE_MSG = '$subject must be a string, %s given.';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param non-empty-string $pattern
|
||||||
|
* @param array<mixed> $matches Set by method
|
||||||
|
* @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
|
||||||
|
* @return 0|1
|
||||||
|
*
|
||||||
|
* @param-out array<int|string, string|null> $matches
|
||||||
|
*/
|
||||||
|
public static function match(string $pattern, string $subject, ?array &$matches = null, int $flags = 0, int $offset = 0): int
|
||||||
|
{
|
||||||
|
self::checkOffsetCapture($flags, 'matchWithOffsets');
|
||||||
|
|
||||||
|
$result = preg_match($pattern, $subject, $matches, $flags | PREG_UNMATCHED_AS_NULL, $offset);
|
||||||
|
if ($result === false) {
|
||||||
|
throw PcreException::fromFunction('preg_match', $pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variant of `match()` which outputs non-null matches (or throws)
|
||||||
|
*
|
||||||
|
* @param non-empty-string $pattern
|
||||||
|
* @param array<mixed> $matches Set by method
|
||||||
|
* @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
|
||||||
|
* @return 0|1
|
||||||
|
* @throws UnexpectedNullMatchException
|
||||||
|
*
|
||||||
|
* @param-out array<int|string, string> $matches
|
||||||
|
*/
|
||||||
|
public static function matchStrictGroups(string $pattern, string $subject, ?array &$matches = null, int $flags = 0, int $offset = 0): int
|
||||||
|
{
|
||||||
|
$result = self::match($pattern, $subject, $matchesInternal, $flags, $offset);
|
||||||
|
$matches = self::enforceNonNullMatches($pattern, $matchesInternal, 'match');
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs preg_match with PREG_OFFSET_CAPTURE
|
||||||
|
*
|
||||||
|
* @param non-empty-string $pattern
|
||||||
|
* @param array<mixed> $matches Set by method
|
||||||
|
* @param int-mask<PREG_UNMATCHED_AS_NULL|PREG_OFFSET_CAPTURE> $flags PREG_UNMATCHED_AS_NULL and PREG_OFFSET_CAPTURE are always set, no other flags are supported
|
||||||
|
* @return 0|1
|
||||||
|
*
|
||||||
|
* @param-out array<int|string, array{string|null, int<-1, max>}> $matches
|
||||||
|
*/
|
||||||
|
public static function matchWithOffsets(string $pattern, string $subject, ?array &$matches, int $flags = 0, int $offset = 0): int
|
||||||
|
{
|
||||||
|
$result = preg_match($pattern, $subject, $matches, $flags | PREG_UNMATCHED_AS_NULL | PREG_OFFSET_CAPTURE, $offset);
|
||||||
|
if ($result === false) {
|
||||||
|
throw PcreException::fromFunction('preg_match', $pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param non-empty-string $pattern
|
||||||
|
* @param array<mixed> $matches Set by method
|
||||||
|
* @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
|
||||||
|
* @return 0|positive-int
|
||||||
|
*
|
||||||
|
* @param-out array<int|string, list<string|null>> $matches
|
||||||
|
*/
|
||||||
|
public static function matchAll(string $pattern, string $subject, ?array &$matches = null, int $flags = 0, int $offset = 0): int
|
||||||
|
{
|
||||||
|
self::checkOffsetCapture($flags, 'matchAllWithOffsets');
|
||||||
|
self::checkSetOrder($flags);
|
||||||
|
|
||||||
|
$result = preg_match_all($pattern, $subject, $matches, $flags | PREG_UNMATCHED_AS_NULL, $offset);
|
||||||
|
if (!is_int($result)) { // PHP < 8 may return null, 8+ returns int|false
|
||||||
|
throw PcreException::fromFunction('preg_match_all', $pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variant of `match()` which outputs non-null matches (or throws)
|
||||||
|
*
|
||||||
|
* @param non-empty-string $pattern
|
||||||
|
* @param array<mixed> $matches Set by method
|
||||||
|
* @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
|
||||||
|
* @return 0|positive-int
|
||||||
|
* @throws UnexpectedNullMatchException
|
||||||
|
*
|
||||||
|
* @param-out array<int|string, list<string>> $matches
|
||||||
|
*/
|
||||||
|
public static function matchAllStrictGroups(string $pattern, string $subject, ?array &$matches = null, int $flags = 0, int $offset = 0): int
|
||||||
|
{
|
||||||
|
$result = self::matchAll($pattern, $subject, $matchesInternal, $flags, $offset);
|
||||||
|
$matches = self::enforceNonNullMatchAll($pattern, $matchesInternal, 'matchAll');
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs preg_match_all with PREG_OFFSET_CAPTURE
|
||||||
|
*
|
||||||
|
* @param non-empty-string $pattern
|
||||||
|
* @param array<mixed> $matches Set by method
|
||||||
|
* @param int-mask<PREG_UNMATCHED_AS_NULL|PREG_OFFSET_CAPTURE> $flags PREG_UNMATCHED_AS_NULL and PREG_MATCH_OFFSET are always set, no other flags are supported
|
||||||
|
* @return 0|positive-int
|
||||||
|
*
|
||||||
|
* @param-out array<int|string, list<array{string|null, int<-1, max>}>> $matches
|
||||||
|
*/
|
||||||
|
public static function matchAllWithOffsets(string $pattern, string $subject, ?array &$matches, int $flags = 0, int $offset = 0): int
|
||||||
|
{
|
||||||
|
self::checkSetOrder($flags);
|
||||||
|
|
||||||
|
$result = preg_match_all($pattern, $subject, $matches, $flags | PREG_UNMATCHED_AS_NULL | PREG_OFFSET_CAPTURE, $offset);
|
||||||
|
if (!is_int($result)) { // PHP < 8 may return null, 8+ returns int|false
|
||||||
|
throw PcreException::fromFunction('preg_match_all', $pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|string[] $pattern
|
||||||
|
* @param string|string[] $replacement
|
||||||
|
* @param string $subject
|
||||||
|
* @param int $count Set by method
|
||||||
|
*
|
||||||
|
* @param-out int<0, max> $count
|
||||||
|
*/
|
||||||
|
public static function replace($pattern, $replacement, $subject, int $limit = -1, ?int &$count = null): string
|
||||||
|
{
|
||||||
|
if (!is_scalar($subject)) {
|
||||||
|
if (is_array($subject)) {
|
||||||
|
throw new \InvalidArgumentException(static::ARRAY_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \TypeError(sprintf(static::INVALID_TYPE_MSG, gettype($subject)));
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = preg_replace($pattern, $replacement, $subject, $limit, $count);
|
||||||
|
if ($result === null) {
|
||||||
|
throw PcreException::fromFunction('preg_replace', $pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|string[] $pattern
|
||||||
|
* @param ($flags is PREG_OFFSET_CAPTURE ? (callable(array<int|string, array{string|null, int<-1, max>}>): string) : callable(array<int|string, string|null>): string) $replacement
|
||||||
|
* @param string $subject
|
||||||
|
* @param int $count Set by method
|
||||||
|
* @param int-mask<PREG_UNMATCHED_AS_NULL|PREG_OFFSET_CAPTURE> $flags PREG_OFFSET_CAPTURE is supported, PREG_UNMATCHED_AS_NULL is always set
|
||||||
|
*
|
||||||
|
* @param-out int<0, max> $count
|
||||||
|
*/
|
||||||
|
public static function replaceCallback($pattern, callable $replacement, $subject, int $limit = -1, ?int &$count = null, int $flags = 0): string
|
||||||
|
{
|
||||||
|
if (!is_scalar($subject)) {
|
||||||
|
if (is_array($subject)) {
|
||||||
|
throw new \InvalidArgumentException(static::ARRAY_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \TypeError(sprintf(static::INVALID_TYPE_MSG, gettype($subject)));
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = preg_replace_callback($pattern, $replacement, $subject, $limit, $count, $flags | PREG_UNMATCHED_AS_NULL);
|
||||||
|
if ($result === null) {
|
||||||
|
throw PcreException::fromFunction('preg_replace_callback', $pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variant of `replaceCallback()` which outputs non-null matches (or throws)
|
||||||
|
*
|
||||||
|
* @param string $pattern
|
||||||
|
* @param ($flags is PREG_OFFSET_CAPTURE ? (callable(array<int|string, array{string, int<0, max>}>): string) : callable(array<int|string, string>): string) $replacement
|
||||||
|
* @param string $subject
|
||||||
|
* @param int $count Set by method
|
||||||
|
* @param int-mask<PREG_UNMATCHED_AS_NULL|PREG_OFFSET_CAPTURE> $flags PREG_OFFSET_CAPTURE is supported, PREG_UNMATCHED_AS_NULL is always set
|
||||||
|
*
|
||||||
|
* @param-out int<0, max> $count
|
||||||
|
*/
|
||||||
|
public static function replaceCallbackStrictGroups(string $pattern, callable $replacement, $subject, int $limit = -1, ?int &$count = null, int $flags = 0): string
|
||||||
|
{
|
||||||
|
return self::replaceCallback($pattern, function (array $matches) use ($pattern, $replacement) {
|
||||||
|
return $replacement(self::enforceNonNullMatches($pattern, $matches, 'replaceCallback'));
|
||||||
|
}, $subject, $limit, $count, $flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ($flags is PREG_OFFSET_CAPTURE ? (array<string, callable(array<int|string, array{string|null, int<-1, max>}>): string>) : array<string, callable(array<int|string, string|null>): string>) $pattern
|
||||||
|
* @param string $subject
|
||||||
|
* @param int $count Set by method
|
||||||
|
* @param int-mask<PREG_UNMATCHED_AS_NULL|PREG_OFFSET_CAPTURE> $flags PREG_OFFSET_CAPTURE is supported, PREG_UNMATCHED_AS_NULL is always set
|
||||||
|
*
|
||||||
|
* @param-out int<0, max> $count
|
||||||
|
*/
|
||||||
|
public static function replaceCallbackArray(array $pattern, $subject, int $limit = -1, ?int &$count = null, int $flags = 0): string
|
||||||
|
{
|
||||||
|
if (!is_scalar($subject)) {
|
||||||
|
if (is_array($subject)) {
|
||||||
|
throw new \InvalidArgumentException(static::ARRAY_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \TypeError(sprintf(static::INVALID_TYPE_MSG, gettype($subject)));
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = preg_replace_callback_array($pattern, $subject, $limit, $count, $flags | PREG_UNMATCHED_AS_NULL);
|
||||||
|
if ($result === null) {
|
||||||
|
$pattern = array_keys($pattern);
|
||||||
|
throw PcreException::fromFunction('preg_replace_callback_array', $pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int-mask<PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_OFFSET_CAPTURE> $flags PREG_SPLIT_NO_EMPTY or PREG_SPLIT_DELIM_CAPTURE
|
||||||
|
* @return list<string>
|
||||||
|
*/
|
||||||
|
public static function split(string $pattern, string $subject, int $limit = -1, int $flags = 0): array
|
||||||
|
{
|
||||||
|
if (($flags & PREG_SPLIT_OFFSET_CAPTURE) !== 0) {
|
||||||
|
throw new \InvalidArgumentException('PREG_SPLIT_OFFSET_CAPTURE is not supported as it changes the type of $matches, use splitWithOffsets() instead');
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = preg_split($pattern, $subject, $limit, $flags);
|
||||||
|
if ($result === false) {
|
||||||
|
throw PcreException::fromFunction('preg_split', $pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int-mask<PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_OFFSET_CAPTURE> $flags PREG_SPLIT_NO_EMPTY or PREG_SPLIT_DELIM_CAPTURE, PREG_SPLIT_OFFSET_CAPTURE is always set
|
||||||
|
* @return list<array{string, int}>
|
||||||
|
* @phpstan-return list<array{string, int<0, max>}>
|
||||||
|
*/
|
||||||
|
public static function splitWithOffsets(string $pattern, string $subject, int $limit = -1, int $flags = 0): array
|
||||||
|
{
|
||||||
|
$result = preg_split($pattern, $subject, $limit, $flags | PREG_SPLIT_OFFSET_CAPTURE);
|
||||||
|
if ($result === false) {
|
||||||
|
throw PcreException::fromFunction('preg_split', $pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @template T of string|\Stringable
|
||||||
|
* @param string $pattern
|
||||||
|
* @param array<T> $array
|
||||||
|
* @param int-mask<PREG_GREP_INVERT> $flags PREG_GREP_INVERT
|
||||||
|
* @return array<T>
|
||||||
|
*/
|
||||||
|
public static function grep(string $pattern, array $array, int $flags = 0): array
|
||||||
|
{
|
||||||
|
$result = preg_grep($pattern, $array, $flags);
|
||||||
|
if ($result === false) {
|
||||||
|
throw PcreException::fromFunction('preg_grep', $pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variant of match() which returns a bool instead of int
|
||||||
|
*
|
||||||
|
* @param non-empty-string $pattern
|
||||||
|
* @param array<mixed> $matches Set by method
|
||||||
|
* @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
|
||||||
|
*
|
||||||
|
* @param-out array<int|string, string|null> $matches
|
||||||
|
*/
|
||||||
|
public static function isMatch(string $pattern, string $subject, ?array &$matches = null, int $flags = 0, int $offset = 0): bool
|
||||||
|
{
|
||||||
|
return (bool) static::match($pattern, $subject, $matches, $flags, $offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variant of `isMatch()` which outputs non-null matches (or throws)
|
||||||
|
*
|
||||||
|
* @param non-empty-string $pattern
|
||||||
|
* @param array<mixed> $matches Set by method
|
||||||
|
* @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
|
||||||
|
* @throws UnexpectedNullMatchException
|
||||||
|
*
|
||||||
|
* @param-out array<int|string, string> $matches
|
||||||
|
*/
|
||||||
|
public static function isMatchStrictGroups(string $pattern, string $subject, ?array &$matches = null, int $flags = 0, int $offset = 0): bool
|
||||||
|
{
|
||||||
|
return (bool) self::matchStrictGroups($pattern, $subject, $matches, $flags, $offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variant of matchAll() which returns a bool instead of int
|
||||||
|
*
|
||||||
|
* @param non-empty-string $pattern
|
||||||
|
* @param array<mixed> $matches Set by method
|
||||||
|
* @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
|
||||||
|
*
|
||||||
|
* @param-out array<int|string, list<string|null>> $matches
|
||||||
|
*/
|
||||||
|
public static function isMatchAll(string $pattern, string $subject, ?array &$matches = null, int $flags = 0, int $offset = 0): bool
|
||||||
|
{
|
||||||
|
return (bool) static::matchAll($pattern, $subject, $matches, $flags, $offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variant of `isMatchAll()` which outputs non-null matches (or throws)
|
||||||
|
*
|
||||||
|
* @param non-empty-string $pattern
|
||||||
|
* @param array<mixed> $matches Set by method
|
||||||
|
* @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
|
||||||
|
*
|
||||||
|
* @param-out array<int|string, list<string>> $matches
|
||||||
|
*/
|
||||||
|
public static function isMatchAllStrictGroups(string $pattern, string $subject, ?array &$matches = null, int $flags = 0, int $offset = 0): bool
|
||||||
|
{
|
||||||
|
return (bool) self::matchAllStrictGroups($pattern, $subject, $matches, $flags, $offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variant of matchWithOffsets() which returns a bool instead of int
|
||||||
|
*
|
||||||
|
* Runs preg_match with PREG_OFFSET_CAPTURE
|
||||||
|
*
|
||||||
|
* @param non-empty-string $pattern
|
||||||
|
* @param array<mixed> $matches Set by method
|
||||||
|
* @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
|
||||||
|
*
|
||||||
|
* @param-out array<int|string, array{string|null, int<-1, max>}> $matches
|
||||||
|
*/
|
||||||
|
public static function isMatchWithOffsets(string $pattern, string $subject, ?array &$matches, int $flags = 0, int $offset = 0): bool
|
||||||
|
{
|
||||||
|
return (bool) static::matchWithOffsets($pattern, $subject, $matches, $flags, $offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variant of matchAllWithOffsets() which returns a bool instead of int
|
||||||
|
*
|
||||||
|
* Runs preg_match_all with PREG_OFFSET_CAPTURE
|
||||||
|
*
|
||||||
|
* @param non-empty-string $pattern
|
||||||
|
* @param array<mixed> $matches Set by method
|
||||||
|
* @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
|
||||||
|
*
|
||||||
|
* @param-out array<int|string, list<array{string|null, int<-1, max>}>> $matches
|
||||||
|
*/
|
||||||
|
public static function isMatchAllWithOffsets(string $pattern, string $subject, ?array &$matches, int $flags = 0, int $offset = 0): bool
|
||||||
|
{
|
||||||
|
return (bool) static::matchAllWithOffsets($pattern, $subject, $matches, $flags, $offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function checkOffsetCapture(int $flags, string $useFunctionName): void
|
||||||
|
{
|
||||||
|
if (($flags & PREG_OFFSET_CAPTURE) !== 0) {
|
||||||
|
throw new \InvalidArgumentException('PREG_OFFSET_CAPTURE is not supported as it changes the type of $matches, use ' . $useFunctionName . '() instead');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function checkSetOrder(int $flags): void
|
||||||
|
{
|
||||||
|
if (($flags & PREG_SET_ORDER) !== 0) {
|
||||||
|
throw new \InvalidArgumentException('PREG_SET_ORDER is not supported as it changes the type of $matches');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<int|string, string|null|array{string|null, int}> $matches
|
||||||
|
* @return array<int|string, string>
|
||||||
|
* @throws UnexpectedNullMatchException
|
||||||
|
*/
|
||||||
|
private static function enforceNonNullMatches(string $pattern, array $matches, string $variantMethod)
|
||||||
|
{
|
||||||
|
foreach ($matches as $group => $match) {
|
||||||
|
if (is_string($match) || (is_array($match) && is_string($match[0]))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new UnexpectedNullMatchException('Pattern "'.$pattern.'" had an unexpected unmatched group "'.$group.'", make sure the pattern always matches or use '.$variantMethod.'() instead.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var array<string> */
|
||||||
|
return $matches;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<int|string, list<string|null>> $matches
|
||||||
|
* @return array<int|string, list<string>>
|
||||||
|
* @throws UnexpectedNullMatchException
|
||||||
|
*/
|
||||||
|
private static function enforceNonNullMatchAll(string $pattern, array $matches, string $variantMethod)
|
||||||
|
{
|
||||||
|
foreach ($matches as $group => $groupMatches) {
|
||||||
|
foreach ($groupMatches as $match) {
|
||||||
|
if (null === $match) {
|
||||||
|
throw new UnexpectedNullMatchException('Pattern "'.$pattern.'" had an unexpected unmatched group "'.$group.'", make sure the pattern always matches or use '.$variantMethod.'() instead.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var array<int|string, list<string>> */
|
||||||
|
return $matches;
|
||||||
|
}
|
||||||
|
}
|
||||||
176
vendor/composer/vendor/composer/pcre/src/Regex.php
vendored
Normal file
176
vendor/composer/vendor/composer/pcre/src/Regex.php
vendored
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of composer/pcre.
|
||||||
|
*
|
||||||
|
* (c) Composer <https://github.com/composer>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer\Pcre;
|
||||||
|
|
||||||
|
class Regex
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param non-empty-string $pattern
|
||||||
|
*/
|
||||||
|
public static function isMatch(string $pattern, string $subject, int $offset = 0): bool
|
||||||
|
{
|
||||||
|
return (bool) Preg::match($pattern, $subject, $matches, 0, $offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param non-empty-string $pattern
|
||||||
|
* @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
|
||||||
|
*/
|
||||||
|
public static function match(string $pattern, string $subject, int $flags = 0, int $offset = 0): MatchResult
|
||||||
|
{
|
||||||
|
self::checkOffsetCapture($flags, 'matchWithOffsets');
|
||||||
|
|
||||||
|
$count = Preg::match($pattern, $subject, $matches, $flags, $offset);
|
||||||
|
|
||||||
|
return new MatchResult($count, $matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variant of `match()` which returns non-null matches (or throws)
|
||||||
|
*
|
||||||
|
* @param non-empty-string $pattern
|
||||||
|
* @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
|
||||||
|
* @throws UnexpectedNullMatchException
|
||||||
|
*/
|
||||||
|
public static function matchStrictGroups(string $pattern, string $subject, int $flags = 0, int $offset = 0): MatchStrictGroupsResult
|
||||||
|
{
|
||||||
|
// @phpstan-ignore composerPcre.maybeUnsafeStrictGroups
|
||||||
|
$count = Preg::matchStrictGroups($pattern, $subject, $matches, $flags, $offset);
|
||||||
|
|
||||||
|
return new MatchStrictGroupsResult($count, $matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs preg_match with PREG_OFFSET_CAPTURE
|
||||||
|
*
|
||||||
|
* @param non-empty-string $pattern
|
||||||
|
* @param int-mask<PREG_UNMATCHED_AS_NULL|PREG_OFFSET_CAPTURE> $flags PREG_UNMATCHED_AS_NULL and PREG_MATCH_OFFSET are always set, no other flags are supported
|
||||||
|
*/
|
||||||
|
public static function matchWithOffsets(string $pattern, string $subject, int $flags = 0, int $offset = 0): MatchWithOffsetsResult
|
||||||
|
{
|
||||||
|
$count = Preg::matchWithOffsets($pattern, $subject, $matches, $flags, $offset);
|
||||||
|
|
||||||
|
return new MatchWithOffsetsResult($count, $matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param non-empty-string $pattern
|
||||||
|
* @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
|
||||||
|
*/
|
||||||
|
public static function matchAll(string $pattern, string $subject, int $flags = 0, int $offset = 0): MatchAllResult
|
||||||
|
{
|
||||||
|
self::checkOffsetCapture($flags, 'matchAllWithOffsets');
|
||||||
|
self::checkSetOrder($flags);
|
||||||
|
|
||||||
|
$count = Preg::matchAll($pattern, $subject, $matches, $flags, $offset);
|
||||||
|
|
||||||
|
return new MatchAllResult($count, $matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variant of `matchAll()` which returns non-null matches (or throws)
|
||||||
|
*
|
||||||
|
* @param non-empty-string $pattern
|
||||||
|
* @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
|
||||||
|
* @throws UnexpectedNullMatchException
|
||||||
|
*/
|
||||||
|
public static function matchAllStrictGroups(string $pattern, string $subject, int $flags = 0, int $offset = 0): MatchAllStrictGroupsResult
|
||||||
|
{
|
||||||
|
self::checkOffsetCapture($flags, 'matchAllWithOffsets');
|
||||||
|
self::checkSetOrder($flags);
|
||||||
|
|
||||||
|
// @phpstan-ignore composerPcre.maybeUnsafeStrictGroups
|
||||||
|
$count = Preg::matchAllStrictGroups($pattern, $subject, $matches, $flags, $offset);
|
||||||
|
|
||||||
|
return new MatchAllStrictGroupsResult($count, $matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs preg_match_all with PREG_OFFSET_CAPTURE
|
||||||
|
*
|
||||||
|
* @param non-empty-string $pattern
|
||||||
|
* @param int-mask<PREG_UNMATCHED_AS_NULL|PREG_OFFSET_CAPTURE> $flags PREG_UNMATCHED_AS_NULL and PREG_MATCH_OFFSET are always set, no other flags are supported
|
||||||
|
*/
|
||||||
|
public static function matchAllWithOffsets(string $pattern, string $subject, int $flags = 0, int $offset = 0): MatchAllWithOffsetsResult
|
||||||
|
{
|
||||||
|
self::checkSetOrder($flags);
|
||||||
|
|
||||||
|
$count = Preg::matchAllWithOffsets($pattern, $subject, $matches, $flags, $offset);
|
||||||
|
|
||||||
|
return new MatchAllWithOffsetsResult($count, $matches);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param string|string[] $pattern
|
||||||
|
* @param string|string[] $replacement
|
||||||
|
* @param string $subject
|
||||||
|
*/
|
||||||
|
public static function replace($pattern, $replacement, $subject, int $limit = -1): ReplaceResult
|
||||||
|
{
|
||||||
|
$result = Preg::replace($pattern, $replacement, $subject, $limit, $count);
|
||||||
|
|
||||||
|
return new ReplaceResult($count, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|string[] $pattern
|
||||||
|
* @param ($flags is PREG_OFFSET_CAPTURE ? (callable(array<int|string, array{string|null, int<-1, max>}>): string) : callable(array<int|string, string|null>): string) $replacement
|
||||||
|
* @param string $subject
|
||||||
|
* @param int-mask<PREG_UNMATCHED_AS_NULL|PREG_OFFSET_CAPTURE> $flags PREG_OFFSET_CAPTURE is supported, PREG_UNMATCHED_AS_NULL is always set
|
||||||
|
*/
|
||||||
|
public static function replaceCallback($pattern, callable $replacement, $subject, int $limit = -1, int $flags = 0): ReplaceResult
|
||||||
|
{
|
||||||
|
$result = Preg::replaceCallback($pattern, $replacement, $subject, $limit, $count, $flags);
|
||||||
|
|
||||||
|
return new ReplaceResult($count, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variant of `replaceCallback()` which outputs non-null matches (or throws)
|
||||||
|
*
|
||||||
|
* @param string $pattern
|
||||||
|
* @param ($flags is PREG_OFFSET_CAPTURE ? (callable(array<int|string, array{string, int<0, max>}>): string) : callable(array<int|string, string>): string) $replacement
|
||||||
|
* @param string $subject
|
||||||
|
* @param int-mask<PREG_UNMATCHED_AS_NULL|PREG_OFFSET_CAPTURE> $flags PREG_OFFSET_CAPTURE is supported, PREG_UNMATCHED_AS_NULL is always set
|
||||||
|
*/
|
||||||
|
public static function replaceCallbackStrictGroups($pattern, callable $replacement, $subject, int $limit = -1, int $flags = 0): ReplaceResult
|
||||||
|
{
|
||||||
|
$result = Preg::replaceCallbackStrictGroups($pattern, $replacement, $subject, $limit, $count, $flags);
|
||||||
|
|
||||||
|
return new ReplaceResult($count, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ($flags is PREG_OFFSET_CAPTURE ? (array<string, callable(array<int|string, array{string|null, int<-1, max>}>): string>) : array<string, callable(array<int|string, string|null>): string>) $pattern
|
||||||
|
* @param string $subject
|
||||||
|
* @param int-mask<PREG_UNMATCHED_AS_NULL|PREG_OFFSET_CAPTURE> $flags PREG_OFFSET_CAPTURE is supported, PREG_UNMATCHED_AS_NULL is always set
|
||||||
|
*/
|
||||||
|
public static function replaceCallbackArray(array $pattern, $subject, int $limit = -1, int $flags = 0): ReplaceResult
|
||||||
|
{
|
||||||
|
$result = Preg::replaceCallbackArray($pattern, $subject, $limit, $count, $flags);
|
||||||
|
|
||||||
|
return new ReplaceResult($count, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function checkOffsetCapture(int $flags, string $useFunctionName): void
|
||||||
|
{
|
||||||
|
if (($flags & PREG_OFFSET_CAPTURE) !== 0) {
|
||||||
|
throw new \InvalidArgumentException('PREG_OFFSET_CAPTURE is not supported as it changes the return type, use '.$useFunctionName.'() instead');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function checkSetOrder(int $flags): void
|
||||||
|
{
|
||||||
|
if (($flags & PREG_SET_ORDER) !== 0) {
|
||||||
|
throw new \InvalidArgumentException('PREG_SET_ORDER is not supported as it changes the return type');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
43
vendor/composer/vendor/composer/pcre/src/ReplaceResult.php
vendored
Normal file
43
vendor/composer/vendor/composer/pcre/src/ReplaceResult.php
vendored
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of composer/pcre.
|
||||||
|
*
|
||||||
|
* (c) Composer <https://github.com/composer>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer\Pcre;
|
||||||
|
|
||||||
|
final class ReplaceResult
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $result;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var 0|positive-int
|
||||||
|
*/
|
||||||
|
public $count;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
public $matched;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param 0|positive-int $count
|
||||||
|
*/
|
||||||
|
public function __construct(int $count, string $result)
|
||||||
|
{
|
||||||
|
$this->count = $count;
|
||||||
|
$this->matched = (bool) $count;
|
||||||
|
$this->result = $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
20
vendor/composer/vendor/composer/pcre/src/UnexpectedNullMatchException.php
vendored
Normal file
20
vendor/composer/vendor/composer/pcre/src/UnexpectedNullMatchException.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of composer/pcre.
|
||||||
|
*
|
||||||
|
* (c) Composer <https://github.com/composer>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer\Pcre;
|
||||||
|
|
||||||
|
class UnexpectedNullMatchException extends PcreException
|
||||||
|
{
|
||||||
|
public static function fromFunction($function, $pattern)
|
||||||
|
{
|
||||||
|
throw new \LogicException('fromFunction should not be called on '.self::class.', use '.PcreException::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
29
vendor/composer/vendor/composer/platform_check.php
vendored
Normal file
29
vendor/composer/vendor/composer/platform_check.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// platform_check.php @generated by Composer
|
||||||
|
|
||||||
|
$issues = array();
|
||||||
|
|
||||||
|
if (!(PHP_VERSION_ID >= 80200)) {
|
||||||
|
$issues[] = 'Your Composer dependencies require a PHP version ">= 8.2.0". You are running ' . PHP_VERSION . '.';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PHP_INT_SIZE !== 8) {
|
||||||
|
$issues[] = 'Your Composer dependencies require a 64-bit build of PHP.';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($issues) {
|
||||||
|
if (!headers_sent()) {
|
||||||
|
header('HTTP/1.1 500 Internal Server Error');
|
||||||
|
}
|
||||||
|
if (!ini_get('display_errors')) {
|
||||||
|
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||||
|
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
|
||||||
|
} elseif (!headers_sent()) {
|
||||||
|
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new \RuntimeException(
|
||||||
|
'Composer detected issues in your platform: ' . implode(' ', $issues)
|
||||||
|
);
|
||||||
|
}
|
||||||
22
vendor/composer/vendor/maennchen/zipstream-php/.editorconfig
vendored
Normal file
22
vendor/composer/vendor/maennchen/zipstream-php/.editorconfig
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
charset = utf-8
|
||||||
|
|
||||||
|
[*.{yml,md,xml}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.{rst,php}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
[composer.json]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[composer.lock]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
6
vendor/composer/vendor/maennchen/zipstream-php/.gitattributes
vendored
Normal file
6
vendor/composer/vendor/maennchen/zipstream-php/.gitattributes
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
.gitignore text eol=lf
|
||||||
|
.gitattributes text eol=lf
|
||||||
|
*.md text eol=lf
|
||||||
|
*.php text eol=lf
|
||||||
|
*.yml text eol=lf
|
||||||
|
*.xml text eol=lf
|
||||||
132
vendor/composer/vendor/maennchen/zipstream-php/.github/CODE_OF_CONDUCT.md
vendored
Normal file
132
vendor/composer/vendor/maennchen/zipstream-php/.github/CODE_OF_CONDUCT.md
vendored
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
We as members, contributors, and leaders pledge to make participation in our
|
||||||
|
community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||||
|
identity and expression, level of experience, education, socio-economic status,
|
||||||
|
nationality, personal appearance, race, caste, color, religion, or sexual
|
||||||
|
identity and orientation.
|
||||||
|
|
||||||
|
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||||
|
diverse, inclusive, and healthy community.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to a positive environment for our
|
||||||
|
community include:
|
||||||
|
|
||||||
|
- Demonstrating empathy and kindness toward other people
|
||||||
|
- Being respectful of differing opinions, viewpoints, and experiences
|
||||||
|
- Giving and gracefully accepting constructive feedback
|
||||||
|
- Accepting responsibility and apologizing to those affected by our mistakes,
|
||||||
|
and learning from the experience
|
||||||
|
- Focusing on what is best not just for us as individuals, but for the overall
|
||||||
|
community
|
||||||
|
|
||||||
|
Examples of unacceptable behavior include:
|
||||||
|
|
||||||
|
- The use of sexualized language or imagery, and sexual attention or advances of
|
||||||
|
any kind
|
||||||
|
- Trolling, insulting or derogatory comments, and personal or political attacks
|
||||||
|
- Public or private harassment
|
||||||
|
- Publishing others' private information, such as a physical or email address,
|
||||||
|
without their explicit permission
|
||||||
|
- Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Enforcement Responsibilities
|
||||||
|
|
||||||
|
Community leaders are responsible for clarifying and enforcing our standards of
|
||||||
|
acceptable behavior and will take appropriate and fair corrective action in
|
||||||
|
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||||
|
or harmful.
|
||||||
|
|
||||||
|
Community leaders have the right and responsibility to remove, edit, or reject
|
||||||
|
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||||
|
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||||
|
decisions when appropriate.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies within all community spaces, and also applies when
|
||||||
|
an individual is officially representing the community in public spaces.
|
||||||
|
Examples of representing our community include using an official e-mail address,
|
||||||
|
posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported to the community leaders responsible for enforcement at
|
||||||
|
jonatan@maennchen.ch.
|
||||||
|
All complaints will be reviewed and investigated promptly and fairly.
|
||||||
|
|
||||||
|
All community leaders are obligated to respect the privacy and security of the
|
||||||
|
reporter of any incident.
|
||||||
|
|
||||||
|
## Enforcement Guidelines
|
||||||
|
|
||||||
|
Community leaders will follow these Community Impact Guidelines in determining
|
||||||
|
the consequences for any action they deem in violation of this Code of Conduct:
|
||||||
|
|
||||||
|
### 1. Correction
|
||||||
|
|
||||||
|
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||||
|
unprofessional or unwelcome in the community.
|
||||||
|
|
||||||
|
**Consequence**: A private, written warning from community leaders, providing
|
||||||
|
clarity around the nature of the violation and an explanation of why the
|
||||||
|
behavior was inappropriate. A public apology may be requested.
|
||||||
|
|
||||||
|
### 2. Warning
|
||||||
|
|
||||||
|
**Community Impact**: A violation through a single incident or series of
|
||||||
|
actions.
|
||||||
|
|
||||||
|
**Consequence**: A warning with consequences for continued behavior. No
|
||||||
|
interaction with the people involved, including unsolicited interaction with
|
||||||
|
those enforcing the Code of Conduct, for a specified period of time. This
|
||||||
|
includes avoiding interactions in community spaces as well as external channels
|
||||||
|
like social media. Violating these terms may lead to a temporary or permanent
|
||||||
|
ban.
|
||||||
|
|
||||||
|
### 3. Temporary Ban
|
||||||
|
|
||||||
|
**Community Impact**: A serious violation of community standards, including
|
||||||
|
sustained inappropriate behavior.
|
||||||
|
|
||||||
|
**Consequence**: A temporary ban from any sort of interaction or public
|
||||||
|
communication with the community for a specified period of time. No public or
|
||||||
|
private interaction with the people involved, including unsolicited interaction
|
||||||
|
with those enforcing the Code of Conduct, is allowed during this period.
|
||||||
|
Violating these terms may lead to a permanent ban.
|
||||||
|
|
||||||
|
### 4. Permanent Ban
|
||||||
|
|
||||||
|
**Community Impact**: Demonstrating a pattern of violation of community
|
||||||
|
standards, including sustained inappropriate behavior, harassment of an
|
||||||
|
individual, or aggression toward or disparagement of classes of individuals.
|
||||||
|
|
||||||
|
**Consequence**: A permanent ban from any sort of public interaction within the
|
||||||
|
community.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||||
|
version 2.1, available at
|
||||||
|
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
|
||||||
|
|
||||||
|
Community Impact Guidelines were inspired by
|
||||||
|
[Mozilla's code of conduct enforcement ladder][mozilla coc].
|
||||||
|
|
||||||
|
For answers to common questions about this code of conduct, see the FAQ at
|
||||||
|
[https://www.contributor-covenant.org/faq][faq]. Translations are available at
|
||||||
|
[https://www.contributor-covenant.org/translations][translations].
|
||||||
|
|
||||||
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
|
||||||
|
[mozilla coc]: https://github.com/mozilla/diversity
|
||||||
|
[faq]: https://www.contributor-covenant.org/faq
|
||||||
|
[translations]: https://www.contributor-covenant.org/translations
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user