Pakate importe

require(dplyr)
require(broom)
require(ggplot2)
require(ggdendro)
require(cluster)

Einlesen der Datei

#library(readxl)
#Clusteranalyse <- read_excel("python_webseite/Clusteranalyse/Clusteranalyse.xlsx")
#View(Clusteranalyse)
Clusteranalyse$KlassenBudget <- as.numeric(Clusteranalyse$KlassenBudget)
Clusteranalyse$digitaler_Ausstattungsscore <- as.numeric(Clusteranalyse$digitaler_Ausstattungsscore)
rownames(Clusteranalyse) <- make.unique(as.character(Clusteranalyse$Schule))

1. Voraussetzungen der Clusteranalyse

✓ Damit verlässliche Aussagen über die Grundgesamtheit möglich sind, sollte die Stichprobe ausreichend groß sein – auch wenn in der Praxis häufig kleinere Stichproben verwendet werden.

✓ Fehlende Werte müssen vor der Durchführung einer Clusteranalyse bereinigt werden. Dazu stehen verschiedene Methoden zur Verfügung, etwa das Entfernen unvollständiger Fälle, das Ersetzen fehlender Werte durch Mittelwerte oder die Imputation.

✓ Alle Variablen, die in die Clusteranalyse einfließen, sollten möglichst dasselbe Skalenniveau aufweisen. Falls dies nicht gegeben ist, kann eine Angleichung auf ein gemeinsames (meist niedrigeres) Skalenniveau erforderlich sein.

✓ Unterscheiden sich die Variablen stark in ihrem Wertebereich, ist eine Standardisierung – beispielsweise durch z-Transformation – sinnvoll, um Verzerrungen in der Clusterbildung zu vermeiden.

2. Grundlegende Konzepte

Die Clusteranalyse ist ein Verfahren der multivariaten Statistik, das dazu dient, Objekte (zum Beispiel Personen, Unternehmen oder – wie in deinem Fall – Schulen) anhand ihrer Merkmale in Gruppen (sogenannte Cluster) einzuteilen. Ziel ist es, dass die Objekte innerhalb eines Clusters möglichst ähnlich sind, während sich die Cluster untereinander möglichst stark unterscheiden. Dabei weiß man zu Beginn meist nicht, wie viele Cluster es geben wird – dies ergibt sich aus den Daten selbst. Die Clusteranalyse kommt häufig in den Sozialwissenschaften, im Marketing oder der Biologie zum Einsatz, um verborgene Muster und Strukturen in großen Datensätzen zu entdecken. Typische Schritte bei einer Clusteranalyse sind die Auswahl relevanter Variablen, das Bereinigen der Daten (z.B. Umgang mit fehlenden Werten), eventuell eine Standardisierung der Merkmale sowie die Anwendung eines Algorithmus (wie K-Means oder hierarchisches Clustering). Die Ergebnisse der Analyse helfen dabei, Gruppen mit ähnlichen Eigenschaften zu identifizieren und diese anschließend zu interpretieren und weiterzuverwenden.

3. Deskriptive Statistiken

describe(Clusteranalyse)
library(dplyr)
Clusteranalyse %>%
  summarise(
    Mittelwert_KlassenBudget = mean(KlassenBudget),
    Mittelwert_DigitalScore = mean(digitaler_Ausstattungsscore),
    n = n()
  )

4. Prüfung der Voraussetzung

✓ Damit verlässliche Aussagen über die Grundgesamtheit möglich sind, sollte die Stichprobe ausreichend groß sein – auch wenn in der Praxis häufig kleinere Stichproben verwendet werden.

N ist mit größer 30

✓ Alle Variablen, die in die Clusteranalyse einfließen, sollten möglichst dasselbe Skalenniveau aufweisen. Falls dies nicht gegeben ist, kann eine Angleichung auf ein gemeinsames (meist niedrigeres) Skalenniveau erforderlich sein.

Beide Spalten sind metrisch.

✓ Fehlende Werte müssen vor der Durchführung einer Clusteranalyse bereinigt werden. Dazu stehen verschiedene Methoden zur Verfügung, etwa das Entfernen unvollständiger Fälle, das Ersetzen fehlender Werte durch Mittelwerte oder die Imputation.

missing_value <- sum(as.numeric(is.na(Clusteranalyse)))
sprintf("Fehlende Werte: %.2f", missing_value)
[1] "Fehlende Werte: 0.00"

✓ Unterscheiden sich die Variablen stark in ihrem Wertebereich, ist eine Standardisierung – beispielsweise durch z-Transformation – sinnvoll, um Verzerrungen in der Clusterbildung zu vermeiden.

daten <- Clusteranalyse[, 2:3]

# # 3. Labels (Schulnamen)
labels <- Clusteranalyse$Schule

rownames(daten) <- labels
Warnung: Setting row names on a tibble is deprecated.
# Standardisierung (z-Transformation)
daten_scaled <- scale(daten)

Da sich die Variablen in ihrem Wertebereich deutlich unterscheiden, wurden die Daten vor der Clusteranalyse mittels z-Transformation standardisiert. So wird sichergestellt, dass beide Merkmale gleich gewichtet in die Distanzberechnung und Clusterbildung eingehen und keine Verzerrungen entstehen.

4. Prozess der Clusterbildung

Bevor mit der eigentlichen Clusterbildung begonnen werden kann, ist die Erstellung einer Distanzmatrix ein zentraler erster Schritt. Sie liefert die Grundlage, um objektiv zu bestimmen, wie ähnlich oder verschieden die einzelnen Fälle im Datensatz zueinander sind und bildet damit die Basis für alle weiteren Schritte der Clusteranalyse.

# Distanzmatrix (euklidisch)
distanz <- dist(daten_scaled, method = "euclidean")

# Quadrierte Distanzen (wie im Beispiel)
naeherungsmatrix <- as.matrix(distanz)^2

# Runden für bessere Lesbarkeit
naeherungsmatrix <- round(naeherungsmatrix, 3)

# Spalten- und Zeilennamen setzen (Überschriften)
colnames(naeherungsmatrix) <- labels
rownames(naeherungsmatrix) <- labels

# Matrix anzeigen
print(naeherungsmatrix)
        AEG    AFS   EvTG    EKG    EAO    FSR    GSS    GG    HHG    HR   MMS   MLS    PS   SSG    TSG
AEG   0.000  0.391  0.219  2.471  6.715  1.554 10.357 7.313  3.339 8.061 7.733 7.385 7.756 6.690 25.739
AFS   0.391  0.000  0.539  0.910  3.988  0.407  6.813 4.353  1.477 4.923 4.673 4.422 4.736 4.021 20.232
EvTG  0.219  0.539  0.000  2.684  7.305  1.443 10.844 7.566  3.072 8.246 7.319 6.897 7.141 5.855 23.688
EKG   2.471  0.910  2.684  0.000  1.140  0.261  2.754 1.283  0.297 1.606 1.717 1.641 1.921 1.830 14.176
EAO   6.715  3.988  7.305  1.140  0.000  2.423  0.427 0.150  1.495 0.265 1.170 1.330 1.664 2.377 11.561
FSR   1.554  0.407  1.443  0.261  2.423  0.000  4.447 2.426  0.338 2.800 2.360 2.164 2.372 1.883 14.930
GSS  10.357  6.813 10.844  2.754  0.427  4.447  0.000 0.315  2.766 0.240 1.189 1.444 1.711 2.774  8.935
GG    7.313  4.353  7.566  1.283  0.150  2.426  0.315 0.000  1.216 0.024 0.508 0.636 0.864 1.496  9.135
HHG   3.339  1.477  3.072  0.297  1.495  0.338  2.766 1.216  0.000 1.416 0.918 0.793 0.924 0.701 10.944
HR    8.061  4.923  8.246  1.606  0.265  2.800  0.240 0.024  1.416 0.000 0.430 0.570 0.770 1.452  8.327
MMS   7.733  4.673  7.319  1.717  1.170  2.360  1.189 0.508  0.918 0.430 0.000 0.014 0.049 0.340  6.154
MLS   7.385  4.422  6.897  1.641  1.330  2.164  1.444 0.636  0.793 0.570 0.014 0.000 0.019 0.218  6.196
PS    7.756  4.736  7.141  1.921  1.664  2.372  1.711 0.864  0.924 0.770 0.049 0.019 0.000 0.152  5.660
SSG   6.690  4.021  5.855  1.830  2.377  1.883  2.774 1.496  0.701 1.452 0.340 0.218 0.152 0.000  6.214
TSG  25.739 20.232 23.688 14.176 11.561 14.930  8.935 9.135 10.944 8.327 6.154 6.196 5.660 6.214  0.000

Bei der Durchführung einer Clusteranalyse wird zunächst eine sogenannte Näherungsmatrix (Distanzmatrix) erstellt. Diese Matrix enthält die quadrierten euklidischen Distanzen für sämtliche Kombinationen von Fällen (hier: Schulen) im Datensatz. Für jedes Wertepaar lässt sich daraus direkt ablesen, wie groß der Abstand zwischen den einzelnen Fällen im Merkmalsraum ist. Die Werte geben jeweils die quadrierte Entfernung zwischen zwei Schulen an.

Beispielsweise beträgt der Abstand zwischen „AEG“ und „AFS“ exakt 0,391 Einheiten, was auf eine hohe Ähnlichkeit dieser beiden Schulen bezüglich der untersuchten Merkmale hindeutet. Im Gegensatz dazu zeigt der Wert von 25,739 für das Paar „AEG“ und „TSG“ eine sehr große Verschiedenheit.

Besonders niedrige Werte in der Matrix deuten darauf hin, dass diese Fälle sich hinsichtlich ihrer Merkmalsausprägungen besonders ähnlich sind und somit bei der Clusterbildung früh zusammengefasst werden. Hohe Distanzwerte zeigen dagegen besonders unterschiedliche Fälle an, die erst in späten Schritten des Clustering-Prozesses gemeinsam einem Cluster zugeordnet werden.

Die Näherungsmatrix bildet somit die Basis für das hierarchische Clustering, da in jedem Schritt stets die jeweils ähnlichsten Fälle bzw. Cluster zusammengefasst werden.

# Hierarchisches Clustering (Ward)
hc <- hclust(dist(daten_scaled), method = "ward.D2")

# Tabelle für die Zuordnungsübersicht bauen
zuordnung <- data.frame(
  Schritt = 1:length(hc$height),
  Cluster_1 = hc$merge[,1],
  Cluster_2 = hc$merge[,2],
  Koeffizient = round(hc$height^2, 3)) # quadrierte Distanz 

zuordnung$Cluster_1_ID <- ifelse(zuordnung$Cluster_1 < 0, -zuordnung$Cluster_1, zuordnung$Cluster_1)
zuordnung$Cluster_2_ID <- ifelse(zuordnung$Cluster_2 < 0, -zuordnung$Cluster_2, zuordnung$Cluster_2)

colnames(zuordnung) <- c("Schritt", "Cluster 1 (intern)", "Cluster 2 (intern)", "Koeffizienten", "Cluster 1", "Cluster 2")


zuordnung_tab <- zuordnung[,c("Schritt", "Cluster 1", "Cluster 2", "Koeffizienten")]
print(zuordnung_tab)
View(zuordnung_tab)

Im weiteren Verlauf der Analyse wird in der sogenannten Zuordnungsübersicht detailliert aufgezeigt, wie die einzelnen Schritte der Clusterbildung ablaufen. Zu Beginn der Analyse bildet jeder Fall ein eigenes Cluster. In jedem Schritt werden dann die beiden Cluster zusammengeführt, die den jeweils geringsten Abstand zueinander aufweisen – dies ist in der Spalte „Koeffizienten“ an den kleinsten Werten zu erkennen.

So zeigt die Übersicht beispielsweise, dass im ersten Schritt (Schritt 14) die Cluster 1 und 14 miteinander verschmolzen werden, da sie den minimalen Abstand zueinander aufweisen (Koeffizient: 0.014). Im darauf folgenden Schritt (Schritt 12) wird dieses neu gebildete Cluster (1/14) direkt mit Cluster 11 zusammengeführt (Koeffizient: 0.019). Dadurch entsteht ein größeres Cluster (1, 11, 14). Parallel dazu werden auch weitere Fälle mit geringer Distanz zusammengefasst, zum Beispiel Cluster 3 und 5 (Schritt 8, Koeffizient: 0.041).

Mit jedem weiteren Schritt in der Tabelle werden jeweils die aktuell ähnlichsten Clusterpaare vereinigt, was sich daran zeigt, dass die jeweiligen Koeffizienten weiterhin eher klein bleiben (z.B. 0.024, 0.219, 0.261 usw.), bevor mit zunehmender Clustergröße die Werte deutlich ansteigen. Am Ende des Prozesses (Schritt 14 und Schritt 13) werden schließlich die größten, verbliebenen Cluster zusammengeführt, wobei die Koeffizienten nun deutlich größer sind (z.B. 13.190 oder 30.693). Dies zeigt, dass in den letzten Schritten auch weniger ähnliche Gruppen zu einem Gesamtcluster verschmolzen werden.

Die Koeffizienten-Spalte dokumentiert dabei die jeweils aktuelle Heterogenität beim Zusammenführen der Cluster – kleine Werte stehen für sehr ähnliche Gruppen, große Werte für die Vereinigung sehr unterschiedlicher Cluster. Die Tabelle macht somit transparent, wie der Algorithmus Schritt für Schritt immer größere, aber auch immer weniger homogene Gruppen bildet, bis alle Fälle in einem einzigen Gesamtcluster vereint sind.

6. Bestimmen der Anzahl Cluster

Zu Beginn eines Clusteranalyse-Verfahrens wird jeder einzelne Fall als eigenständiges Cluster betrachtet. Im Verlauf des Analyseprozesses werden diese Einzelfälle schrittweise zu immer größeren Gruppen zusammengeführt, bis schließlich alle Fälle in einem einzigen, umfassenden Cluster vereint sind. Die zentrale Frage, die sich dabei stellt, ist: Wie viele Cluster sind für die Interpretation der Daten sinnvoll? Das heißt, wo zwischen der maximalen Anzahl von Clustern (bei 15 Fällen: 15 Cluster) und nur einem einzigen Cluster liegt die optimale Lösung?

Um diese Entscheidung zu treffen, wird häufig sowohl auf inhaltliche Überlegungen (also die Sinnhaftigkeit bestimmter Gruppenzahlen für das Untersuchungsziel) als auch auf grafische Hilfsmittel wie das sogenannte Dendrogramm zurückgegriffen.

# Dendrogramm plotten
plot(hc, main = "Dendrogramm mit Ward-Verknüpfung", xlab = "", sub = "")

# Rote Markierung für optimale Cluster-Anzahl (hier: 2-Cluster-Lösung)
rect.hclust(hc, k = 2, border = "red")

Alternative

ggdendro::ggdendrogram(hc, labels = T, rotate =  T)

Das oben dargestellte Dendrogramm visualisiert den gesamten Clusterbildungsprozess in Form einer Baumstruktur. Am Anfang steht jede Schule als eigenständiger Punkt ganz unten in dieser Baumstruktur. Mit jedem Schritt werden jeweils die beiden ähnlichsten Schulen oder Cluster zu einem gemeinsamen Ast zusammengefasst – dies ist an den vertikalen Linien der Baumstruktur erkennbar. Je höher die Verbindung in der Baumstruktur angesetzt ist, desto größer ist die Unterschiedlichkeit (Heterogenität) der zusammengeführten Cluster.

Die vertikale Achse (“Height”) gibt die Distanz an, mit der jeweils zwei Cluster fusionieren. Ein besonders großer Sprung auf dieser Achse signalisiert, dass an dieser Stelle zwei Gruppen zusammengelegt werden, die sich bereits deutlich voneinander unterscheiden.

In diesem Beispiel ist klar zu erkennen, dass sich eine Zwei-Cluster-Lösung anbietet. Die beiden roten Kästen markieren die Cluster, die nach dem größten Sprung in der Baumstruktur entstehen:

Der linke Cluster enthält die Schulen HHG, EKG, FSR, AFS, AEG und EvTG,

der rechte Cluster fasst die übrigen Schulen zusammen (TSG, SSG, PS, MMS, MLS, GSS, EAO, GG, HR).

Die Wahl der optimalen Clusterzahl orientiert sich an dem Punkt, an dem in der Baumstruktur der größte Abstand (“Height”) zwischen zwei Verbindungen auftritt. Dadurch werden zwei Gruppen gebildet, die intern möglichst ähnlich und untereinander möglichst unterschiedlich sind.

Diese Darstellung in Baumstruktur-Form macht den Prozess der Clusterbildung besonders anschaulich und erleichtert die nachvollziehbare Einteilung der betrachteten Schulen in sinnvolle Gruppen.

7. Beschreibung der Cluster

Die Tabelle zur Cluster-Zugehörigkeit zeigt, welche Fälle jeweils demselben Cluster zugeordnet sind. In diesem Beispiel wurde eine Zwei-Cluster-Lösung gewählt, sodass das Hauptaugenmerk auf der Spalte liegt, die die Zugehörigkeit zu den beiden Clustern angibt. Dabei wird deutlich, dass die Fälle 1, 2, 3, 4, 5, 10, 11, 12 und 14 das erste Cluster bilden, während die Fälle 6, 7, 8, 9, 13 und 15 dem zweiten Cluster zugeordnet werden.


# Clusterzugehörigkeiten für 5, 4, 3, 2 Cluster berechnen
clusters <- data.frame(
  Fall = labels,
  `5 Cluster` = cutree(hc, k = 5),
  `4 Cluster` = cutree(hc, k = 4),
  `3 Cluster` = cutree(hc, k = 3),
  `2 Cluster` = cutree(hc, k = 2)
)

# Ausgabe wie im SPSS-Beispiel
print(clusters)

Um die optimale Anzahl an Clustern für das k-Means-Verfahren festzulegen, wird häufig das sogenannte Elbow-Kriterium (Kniepunkt-Kriterium) herangezogen. Dazu wird für verschiedene Werte von k (Anzahl der Cluster) die gesamte innerhalb der Cluster liegende Quadratsumme („Total Within-Cluster Sum of Squares“, tot.withinss) berechnet und grafisch dargestellt. Der daraus entstehende Elbow-Plot zeigt, wie stark die Heterogenität innerhalb der Cluster mit steigender Clusterzahl abnimmt.

Das Ziel dieses Ansatzes ist es, den Punkt zu identifizieren, an dem eine weitere Erhöhung der Clusteranzahl zu keiner wesentlichen Verbesserung mehr führt. Dieser Punkt – der sogenannte „Knick“ oder „Elbow“ – gibt einen Hinweis darauf, wie viele Cluster die vorhandene Struktur der Daten am besten beschreiben. Auf diese Weise lässt sich eine ausgewogene Balance zwischen zu grober und zu feiner Gruppierung finden.

multi.clust <- data.frame(k = 1:4) %>% group_by(k) %>% do(clust = kmeans(Clusteranalyse, .$k))
sumsq.clust <- multi.clust %>% group_by(k) %>% do(glance(.$clust[[1]]))

ggplot(sumsq.clust, aes(k, tot.withinss)) + geom_line() + geom_point()

Die Grafik zeigt den Verlauf der gesamten innerhalb der Cluster liegenden Quadratsumme (tot.withinss) in Abhängigkeit von der gewählten Clusteranzahl (k). Man erkennt deutlich, dass der Wert für tot.withinss beim Wechsel von einem auf zwei Cluster stark abnimmt. Dieser starke Rückgang bedeutet, dass durch die Aufteilung in zwei Cluster ein Großteil der Heterogenität innerhalb der Gruppen bereits erklärt wird.

Mit jeder weiteren Erhöhung von k sinkt die tot.withinss zwar weiter, der Zugewinn an Homogenität fällt jedoch zunehmend geringer aus. Besonders auffällig ist der „Knick“ zwischen k = 2 und k = 3, ab dem sich die Kurve abflacht. Dies deutet darauf hin, dass die Wahl von zwei Clustern eine sinnvolle Lösung darstellt, da zusätzliche Cluster nur noch einen vergleichsweise geringen Mehrwert bringen.

Zusammenfassend lässt sich festhalten, dass das Elbow-Kriterium hier klar für eine Zwei-Cluster-Lösung spricht, weil an dieser Stelle der größte relative Zugewinn an Homogenität erzielt wird und die Daten somit effizient und sinnvoll gruppiert werden.

weitere Klärung

Zur grafischen Darstellung der Cluster eignet sich ein Streudiagramm (Scatterplot), bei dem die Fälle entsprechend ihrer Clusterzugehörigkeit farblich unterschieden werden. Dabei werden die beiden ausgewählten Merkmale auf den Achsen abgetragen, und die Datenpunkte erhalten unterschiedliche Farben oder Symbole, je nachdem, zu welchem Cluster sie gehören. Die Gruppenzugehörigkeit wird dabei durch die Variable dargestellt, die die Clusterzuordnung enthält. Auf diese Weise lässt sich die Verteilung der Cluster visuell leicht nachvollziehen.

Vorbereitung

Clusteranalyse$Schule <- NULL
row.names(Clusteranalyse)<- clusters$Fall
Warnung: Setting row names on a tibble is deprecated.
View(Clusteranalyse)
p.cluster <- Clusteranalyse %>% kmeans(., 2)


p.cluster$cluster <- as.factor(p.cluster$cluster)

ggplot(Clusteranalyse, aes(KlassenBudget, digitaler_Ausstattungsscore, label = rownames(Clusteranalyse))) + 
  scale_fill_discrete(name = "Cluster")  +
  geom_label(aes(fill = p.cluster$cluster), colour = "white", 
  fontface = "bold", size=2)

Das Streudiagramm zeigt anschaulich, wie die einzelnen Datenpunkte den Clustern zugeordnet sind. Dabei fällt auf, dass der Wert für „CEO“ möglicherweise einen Ausreißer darstellt. Obwohl dieser Fall dennoch einem der beiden Cluster zugeordnet wurde, könnte man alternativ auch überlegen, ihn als eigenes Cluster zu behandeln (z. B. durch eine Drei-Cluster-Lösung) oder ihn ganz aus der Analyse auszuschließen.

Cluster 1 umfasst Schulen mit niedrigem Klassenbudget und geringem digitalen Ausstattungs-Score. Diese Gruppe besteht meist aus kleineren oder finanziell schwächer ausgestatteten Schulen mit Nachholbedarf bei der Digitalisierung.

Cluster 2 beinhaltet Schulen mit hohem Budget und fortschrittlicher digitaler Ausstattung. Hierzu zählen häufig größere oder besser geförderte Schulen, die bereits umfassender in moderne Technologien investiert haben.

alle

multi.clust <- data.frame(k = 1:5) %>% group_by(k) %>% do(clust = kmeans(Clusteranalyse, .$k))
multi.k <- multi.clust %>% group_by(k) %>% do(augment(.$clust[[1]], Clusteranalyse))

ggplot(multi.k, aes(KlassenBudget, digitaler_Ausstattungsscore,)) + geom_point(aes(color = .cluster)) + 
  facet_wrap(~k)

Für die Interpretation und Beschreibung der gefundenen Cluster werden häufig deskriptive Statistiken genutzt. Dazu teilt man den Datensatz entsprechend der Clusterzugehörigkeit auf und berechnet für jedes Cluster beispielsweise Mittelwerte oder Häufigkeiten wichtiger Merkmale. So lässt sich die Zusammensetzung der Cluster gezielt vergleichen und charakterisieren.

Clusteranalyse$Cluster2 <- as.factor(cutree(hc, k = 2))

# 9. Clusterbeschreibung (Mittelwerte je Cluster)
cluster_summary <- Clusteranalyse %>%
  group_by(Cluster2) %>%
  summarise(
    Mittelwert_KlassenBudget = mean(KlassenBudget),
    Mittelwert_DigitalScore = mean(digitaler_Ausstattungsscore),
    Anzahl = n()
  )
print(cluster_summary)

# 10. (Optional) t-Test zum Clustervergleich
t.test(KlassenBudget ~ Cluster2, data = Clusteranalyse)

    Welch Two Sample t-test

data:  KlassenBudget by Cluster2
t = -3.2603, df = 11.787, p-value = 0.006975
alternative hypothesis: true difference in means between group 1 and group 2 is not equal to 0
95 percent confidence interval:
 -52.04893 -10.29885
sample estimates:
mean in group 1 mean in group 2 
       36.58167        67.75556 
t.test(digitaler_Ausstattungsscore ~ Cluster2, data = Clusteranalyse)

    Welch Two Sample t-test

data:  digitaler_Ausstattungsscore by Cluster2
t = -5.2889, df = 8.0922, p-value = 0.000711
alternative hypothesis: true difference in means between group 1 and group 2 is not equal to 0
95 percent confidence interval:
 -155.30066  -61.12489
sample estimates:
mean in group 1 mean in group 2 
       131.0250        239.2378 

Zur Überprüfung, ob sich die Cluster hinsichtlich des Klassenbudgets und des digitalen Ausstattungs­scores signifikant unterscheiden, wurden unabhängige Stichproben-t-Tests durchgeführt.

Für das Klassenbudget ergab der Test einen signifikanten Unterschied zwischen den beiden Clustern, t(11.79) = -3.26, p = .007. Die mittleren Klassenbudgets lagen bei Cluster 1 bei M = 36.58 und bei Cluster 2 bei M = 67.76. Das 95%-Konfidenzintervall für die Mittelwertsdifferenz lag zwischen -52.05 und -10.30.

Auch für den digitalen Ausstattungsscore zeigte sich ein hochsignifikanter Unterschied zwischen den Clustern, t(8.09) = -5.29, p < .001. Der Mittelwert im ersten Cluster betrug M = 131.03, im zweiten Cluster M = 239.24. Das 95%-Konfidenzintervall für die Mittelwertsdifferenz reichte von -155.30 bis -61.12.

Interpretation: Die Ergebnisse zeigen, dass sich die beiden identifizierten Cluster sowohl im Klassenbudget als auch im digitalen Ausstattungsgrad signifikant unterscheiden.

8. Eine Aussage

Im Rahmen der vorliegenden Untersuchung wurde eine hierarchische Clusteranalyse unter Anwendung der Ward-Methode und auf Basis der quadrierten euklidischen Distanz durchgeführt. Ziel war es, die untersuchten Schulen anhand der Merkmale „Klassenbudget“ und „digitaler Ausstattungs-Score“ in möglichst homogene Gruppen einzuteilen und so verborgene Strukturen innerhalb des Datensatzes sichtbar zu machen.

Die Auswertung des zugehörigen Dendrogramms und die Anwendung des Elbow-Kriteriums (vgl. Abbildung X) deuten darauf hin, dass eine Zwei-Cluster-Lösung die vorhandene Heterogenität in den Daten am besten abbildet. Der markanteste Anstieg der Fusionsdistanzen im Dendrogramm legt nahe, dass die Zusammenfassung auf zwei Gruppen sowohl statistisch sinnvoll als auch aus inhaltlicher Perspektive plausibel ist.

Zur Überprüfung der Unterschiede zwischen den Clustern wurden unabhängige Stichproben-t-Tests durchgeführt. Die Ergebnisse zeigen, dass sich die beiden Cluster signifikant sowohl im Klassenbudget (t(11.79) = -3.26, p = .007, 95%-CI [-52.05; -10.30]) als auch im digitalen Ausstattungs-Score (t(8.09) = -5.29, p < .001, 95%-CI [-155.30; -61.12]) unterscheiden. Die Mittelwerte in den beiden Clustern liegen beim Klassenbudget bei M₁ = 36.58 (SD nicht ausgewiesen) und M₂ = 67.76, beim Ausstattungs-Score bei M₁ = 131.03 und M₂ = 239.24. Die Differenzen sind somit sowohl statistisch signifikant als auch praktisch bedeutsam.

Interpretation der Clusterstruktur: Cluster 1 umfasst jene Schulen, die sowohl über ein unterdurchschnittliches Klassenbudget als auch über einen vergleichsweise niedrigen digitalen Ausstattungs-Score verfügen. Typischerweise gehören zu dieser Gruppe beispielsweise kleinere oder finanziell weniger stark ausgestattete Schulen, die möglicherweise im Bereich der digitalen Infrastruktur noch Entwicklungsbedarf aufweisen.

Cluster 2 hingegen setzt sich aus Schulen zusammen, die sowohl ein deutlich höheres Budget als auch eine fortschrittlichere digitale Ausstattung aufweisen. Diese Gruppe könnte zum Beispiel Gymnasien oder Schulen in wohlhabenderen Regionen umfassen, bei denen mehr Mittel für moderne Ausstattung zur Verfügung stehen und die tendenziell auch von gezielten Digitalisierungsinitiativen profitiert haben.

Die grafische Darstellung der Cluster in der Baumstruktur des Dendrogramms zeigt deutlich, dass innerhalb der beiden Gruppen eine hohe Ähnlichkeit hinsichtlich der betrachteten Merkmale besteht, während sich die Gruppen untereinander klar voneinander abgrenzen. Diese Befunde werden durch die Ergebnisse der t-Tests weiter untermauert.

Zusammenfassend lässt sich festhalten: Die durchgeführte Clusteranalyse bestätigt, dass Schulen anhand der beiden untersuchten Merkmale zuverlässig in zwei unterschiedliche Typen eingeteilt werden können. Die Zugehörigkeit zu einem der beiden Cluster ist dabei eng mit den jeweiligen Ausprägungen in Budget und Digitalisierung verknüpft. Die Analyse bietet somit eine belastbare Grundlage für eine gezielte Förder- oder Interventionsstrategie, etwa indem Schulen mit niedrigerem Budget und Ausstattungsgrad gezielt in ihrer digitalen Entwicklung unterstützt werden.

LS0tCnRpdGxlOiAiQ2x1c3RlcmFuYWx5c2UiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCiMgUGFrYXRlIGltcG9ydGUKYGBge3J9CmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoYnJvb20pCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShnZ2RlbmRybykKbGlicmFyeShjbHVzdGVyKQpsaWJyYXJ5KHJlYWR4bCkKYGBgCgojIEVpbmxlc2VuIGRlciBEYXRlaQoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KI2xpYnJhcnkocmVhZHhsKQojQ2x1c3RlcmFuYWx5c2UgPC0gcmVhZF9leGNlbCgicHl0aG9uX3dlYnNlaXRlL0NsdXN0ZXJhbmFseXNlL0NsdXN0ZXJhbmFseXNlLnhsc3giKQojVmlldyhDbHVzdGVyYW5hbHlzZSkKQ2x1c3RlcmFuYWx5c2UkS2xhc3NlbkJ1ZGdldCA8LSBhcy5udW1lcmljKENsdXN0ZXJhbmFseXNlJEtsYXNzZW5CdWRnZXQpCkNsdXN0ZXJhbmFseXNlJGRpZ2l0YWxlcl9BdXNzdGF0dHVuZ3NzY29yZSA8LSBhcy5udW1lcmljKENsdXN0ZXJhbmFseXNlJGRpZ2l0YWxlcl9BdXNzdGF0dHVuZ3NzY29yZSkKcm93bmFtZXMoQ2x1c3RlcmFuYWx5c2UpIDwtIG1ha2UudW5pcXVlKGFzLmNoYXJhY3RlcihDbHVzdGVyYW5hbHlzZSRTY2h1bGUpKQpgYGAKCgojIDEuCVZvcmF1c3NldHp1bmdlbiBkZXIgQ2x1c3RlcmFuYWx5c2UKCuKckyBEYW1pdCB2ZXJsw6Rzc2xpY2hlIEF1c3NhZ2VuIMO8YmVyIGRpZSBHcnVuZGdlc2FtdGhlaXQgbcO2Z2xpY2ggc2luZCwgc29sbHRlIGRpZSBTdGljaHByb2JlIGF1c3JlaWNoZW5kIGdyb8OfIHNlaW4g4oCTIGF1Y2ggd2VubiBpbiBkZXIgUHJheGlzIGjDpHVmaWcga2xlaW5lcmUgU3RpY2hwcm9iZW4gdmVyd2VuZGV0IHdlcmRlbi4KCuKckyBGZWhsZW5kZSBXZXJ0ZSBtw7xzc2VuIHZvciBkZXIgRHVyY2hmw7xocnVuZyBlaW5lciBDbHVzdGVyYW5hbHlzZSBiZXJlaW5pZ3Qgd2VyZGVuLiBEYXp1IHN0ZWhlbiB2ZXJzY2hpZWRlbmUgTWV0aG9kZW4genVyIFZlcmbDvGd1bmcsIGV0d2EgZGFzIEVudGZlcm5lbiB1bnZvbGxzdMOkbmRpZ2VyIEbDpGxsZSwgZGFzIEVyc2V0emVuIGZlaGxlbmRlciBXZXJ0ZSBkdXJjaCBNaXR0ZWx3ZXJ0ZSBvZGVyIGRpZSBJbXB1dGF0aW9uLgoK4pyTIEFsbGUgVmFyaWFibGVuLCBkaWUgaW4gZGllIENsdXN0ZXJhbmFseXNlIGVpbmZsaWXDn2VuLCBzb2xsdGVuIG3DtmdsaWNoc3QgZGFzc2VsYmUgU2thbGVubml2ZWF1IGF1ZndlaXNlbi4gRmFsbHMgZGllcyBuaWNodCBnZWdlYmVuIGlzdCwga2FubiBlaW5lIEFuZ2xlaWNodW5nIGF1ZiBlaW4gZ2VtZWluc2FtZXMgKG1laXN0IG5pZWRyaWdlcmVzKSBTa2FsZW5uaXZlYXUgZXJmb3JkZXJsaWNoIHNlaW4uCgrinJMgVW50ZXJzY2hlaWRlbiBzaWNoIGRpZSBWYXJpYWJsZW4gc3RhcmsgaW4gaWhyZW0gV2VydGViZXJlaWNoLCBpc3QgZWluZSBTdGFuZGFyZGlzaWVydW5nIOKAkyBiZWlzcGllbHN3ZWlzZSBkdXJjaCB6LVRyYW5zZm9ybWF0aW9uIOKAkyBzaW5udm9sbCwgdW0gVmVyemVycnVuZ2VuIGluIGRlciBDbHVzdGVyYmlsZHVuZyB6dSB2ZXJtZWlkZW4uCgoKCgojIDIuCUdydW5kbGVnZW5kZSBLb256ZXB0ZQoKRGllIENsdXN0ZXJhbmFseXNlIGlzdCBlaW4gVmVyZmFocmVuIGRlciBtdWx0aXZhcmlhdGVuIFN0YXRpc3RpaywgZGFzIGRhenUgZGllbnQsIE9iamVrdGUgKHp1bSBCZWlzcGllbCBQZXJzb25lbiwgVW50ZXJuZWhtZW4gb2RlciDigJMgd2llIGluIGRlaW5lbSBGYWxsIOKAkyBTY2h1bGVuKSBhbmhhbmQgaWhyZXIgTWVya21hbGUgaW4gR3J1cHBlbiAoc29nZW5hbm50ZSBDbHVzdGVyKSBlaW56dXRlaWxlbi4gWmllbCBpc3QgZXMsIGRhc3MgZGllIE9iamVrdGUgaW5uZXJoYWxiIGVpbmVzIENsdXN0ZXJzIG3DtmdsaWNoc3Qgw6RobmxpY2ggc2luZCwgd8OkaHJlbmQgc2ljaCBkaWUgQ2x1c3RlciB1bnRlcmVpbmFuZGVyIG3DtmdsaWNoc3Qgc3RhcmsgdW50ZXJzY2hlaWRlbi4gRGFiZWkgd2Vpw58gbWFuIHp1IEJlZ2lubiBtZWlzdCBuaWNodCwgd2llIHZpZWxlIENsdXN0ZXIgZXMgZ2ViZW4gd2lyZCDigJMgZGllcyBlcmdpYnQgc2ljaCBhdXMgZGVuIERhdGVuIHNlbGJzdC4gRGllIENsdXN0ZXJhbmFseXNlIGtvbW10IGjDpHVmaWcgaW4gZGVuIFNvemlhbHdpc3NlbnNjaGFmdGVuLCBpbSBNYXJrZXRpbmcgb2RlciBkZXIgQmlvbG9naWUgenVtIEVpbnNhdHosIHVtIHZlcmJvcmdlbmUgTXVzdGVyIHVuZCBTdHJ1a3R1cmVuIGluIGdyb8OfZW4gRGF0ZW5zw6R0emVuIHp1IGVudGRlY2tlbi4gVHlwaXNjaGUgU2Nocml0dGUgYmVpIGVpbmVyIENsdXN0ZXJhbmFseXNlIHNpbmQgZGllIEF1c3dhaGwgcmVsZXZhbnRlciBWYXJpYWJsZW4sIGRhcyBCZXJlaW5pZ2VuIGRlciBEYXRlbiAoei5CLiBVbWdhbmcgbWl0IGZlaGxlbmRlbiBXZXJ0ZW4pLCBldmVudHVlbGwgZWluZSBTdGFuZGFyZGlzaWVydW5nIGRlciBNZXJrbWFsZSBzb3dpZSBkaWUgQW53ZW5kdW5nIGVpbmVzIEFsZ29yaXRobXVzICh3aWUgSy1NZWFucyBvZGVyIGhpZXJhcmNoaXNjaGVzIENsdXN0ZXJpbmcpLiBEaWUgRXJnZWJuaXNzZSBkZXIgQW5hbHlzZSBoZWxmZW4gZGFiZWksIEdydXBwZW4gbWl0IMOkaG5saWNoZW4gRWlnZW5zY2hhZnRlbiB6dSBpZGVudGlmaXppZXJlbiB1bmQgZGllc2UgYW5zY2hsaWXDn2VuZCB6dSBpbnRlcnByZXRpZXJlbiB1bmQgd2VpdGVyenV2ZXJ3ZW5kZW4uCgojIDMuCURlc2tyaXB0aXZlIFN0YXRpc3Rpa2VuCgpgYGB7cn0KZGVzY3JpYmUoQ2x1c3RlcmFuYWx5c2UpCmBgYApgYGB7cn0KbGlicmFyeShkcGx5cikKQ2x1c3RlcmFuYWx5c2UgJT4lCiAgc3VtbWFyaXNlKAogICAgTWl0dGVsd2VydF9LbGFzc2VuQnVkZ2V0ID0gbWVhbihLbGFzc2VuQnVkZ2V0KSwKICAgIE1pdHRlbHdlcnRfRGlnaXRhbFNjb3JlID0gbWVhbihkaWdpdGFsZXJfQXVzc3RhdHR1bmdzc2NvcmUpLAogICAgbiA9IG4oKQogICkKYGBgCgoKCiMgNC4gUHLDvGZ1bmcgZGVyIFZvcmF1c3NldHp1bmcKCuKckyBEYW1pdCB2ZXJsw6Rzc2xpY2hlIEF1c3NhZ2VuIMO8YmVyIGRpZSBHcnVuZGdlc2FtdGhlaXQgbcO2Z2xpY2ggc2luZCwgc29sbHRlIGRpZSBTdGljaHByb2JlIGF1c3JlaWNoZW5kIGdyb8OfIHNlaW4g4oCTIGF1Y2ggd2VubiBpbiBkZXIgUHJheGlzIGjDpHVmaWcga2xlaW5lcmUgU3RpY2hwcm9iZW4gdmVyd2VuZGV0IHdlcmRlbi4KCiAqKk4qKiBpc3QgbWl0IGdyw7bDn2VyICoqMzAqKgoKCuKckyBBbGxlIFZhcmlhYmxlbiwgZGllIGluIGRpZSBDbHVzdGVyYW5hbHlzZSBlaW5mbGllw59lbiwgc29sbHRlbiBtw7ZnbGljaHN0IGRhc3NlbGJlIFNrYWxlbm5pdmVhdSBhdWZ3ZWlzZW4uIEZhbGxzIGRpZXMgbmljaHQgZ2VnZWJlbiBpc3QsIGthbm4gZWluZSBBbmdsZWljaHVuZyBhdWYgZWluIGdlbWVpbnNhbWVzIChtZWlzdCBuaWVkcmlnZXJlcykgU2thbGVubml2ZWF1IGVyZm9yZGVybGljaCBzZWluLgoKKipCZWlkZSBTcGFsdGVuIHNpbmQgbWV0cmlzY2guKioKCgrinJMgRmVobGVuZGUgV2VydGUgbcO8c3NlbiB2b3IgZGVyIER1cmNoZsO8aHJ1bmcgZWluZXIgQ2x1c3RlcmFuYWx5c2UgYmVyZWluaWd0IHdlcmRlbi4gRGF6dSBzdGVoZW4gdmVyc2NoaWVkZW5lIE1ldGhvZGVuIHp1ciBWZXJmw7xndW5nLCBldHdhIGRhcyBFbnRmZXJuZW4gdW52b2xsc3TDpG5kaWdlciBGw6RsbGUsIGRhcyBFcnNldHplbiBmZWhsZW5kZXIgV2VydGUgZHVyY2ggTWl0dGVsd2VydGUgb2RlciBkaWUgSW1wdXRhdGlvbi4KCmBgYHtyfQptaXNzaW5nX3ZhbHVlIDwtIHN1bShhcy5udW1lcmljKGlzLm5hKENsdXN0ZXJhbmFseXNlKSkpCnNwcmludGYoIkZlaGxlbmRlIFdlcnRlOiAlLjJmIiwgbWlzc2luZ192YWx1ZSkKYGBgCgoK4pyTIFVudGVyc2NoZWlkZW4gc2ljaCBkaWUgVmFyaWFibGVuIHN0YXJrIGluIGlocmVtIFdlcnRlYmVyZWljaCwgaXN0IGVpbmUgU3RhbmRhcmRpc2llcnVuZyDigJMgYmVpc3BpZWxzd2Vpc2UgZHVyY2ggei1UcmFuc2Zvcm1hdGlvbiDigJMgc2lubnZvbGwsIHVtIFZlcnplcnJ1bmdlbiBpbiBkZXIgQ2x1c3RlcmJpbGR1bmcgenUgdmVybWVpZGVuLgoKYGBge3J9CmRhdGVuIDwtIENsdXN0ZXJhbmFseXNlWywgMjozXQoKIyAjIDMuIExhYmVscyAoU2NodWxuYW1lbikKbGFiZWxzIDwtIENsdXN0ZXJhbmFseXNlJFNjaHVsZQoKcm93bmFtZXMoZGF0ZW4pIDwtIGxhYmVscwoKIyBTdGFuZGFyZGlzaWVydW5nICh6LVRyYW5zZm9ybWF0aW9uKQpkYXRlbl9zY2FsZWQgPC0gc2NhbGUoZGF0ZW4pCmBgYAoKRGEgc2ljaCBkaWUgVmFyaWFibGVuIGluIGlocmVtIFdlcnRlYmVyZWljaCBkZXV0bGljaCB1bnRlcnNjaGVpZGVuLCB3dXJkZW4gZGllIERhdGVuIHZvciBkZXIgQ2x1c3RlcmFuYWx5c2UgbWl0dGVscyB6LVRyYW5zZm9ybWF0aW9uIHN0YW5kYXJkaXNpZXJ0LiBTbyB3aXJkIHNpY2hlcmdlc3RlbGx0LCBkYXNzIGJlaWRlIE1lcmttYWxlIGdsZWljaCBnZXdpY2h0ZXQgaW4gZGllIERpc3RhbnpiZXJlY2hudW5nIHVuZCBDbHVzdGVyYmlsZHVuZyBlaW5nZWhlbiB1bmQga2VpbmUgVmVyemVycnVuZ2VuIGVudHN0ZWhlbi4KCgoKCiMgNC4JUHJvemVzcyBkZXIgQ2x1c3RlcmJpbGR1bmcKCkJldm9yIG1pdCBkZXIgZWlnZW50bGljaGVuIENsdXN0ZXJiaWxkdW5nIGJlZ29ubmVuIHdlcmRlbiBrYW5uLCBpc3QgZGllIEVyc3RlbGx1bmcgZWluZXIgRGlzdGFuem1hdHJpeCBlaW4gemVudHJhbGVyIGVyc3RlciBTY2hyaXR0LiBTaWUgbGllZmVydCBkaWUgR3J1bmRsYWdlLCB1bSBvYmpla3RpdiB6dSBiZXN0aW1tZW4sIHdpZSDDpGhubGljaCBvZGVyIHZlcnNjaGllZGVuIGRpZSBlaW56ZWxuZW4gRsOkbGxlIGltIERhdGVuc2F0eiB6dWVpbmFuZGVyIHNpbmQgdW5kIGJpbGRldCBkYW1pdCBkaWUgQmFzaXMgZsO8ciBhbGxlIHdlaXRlcmVuIFNjaHJpdHRlIGRlciBDbHVzdGVyYW5hbHlzZS4KCmBgYHtyfQojIERpc3RhbnptYXRyaXggKGV1a2xpZGlzY2gpCmRpc3RhbnogPC0gZGlzdChkYXRlbl9zY2FsZWQsIG1ldGhvZCA9ICJldWNsaWRlYW4iKQoKIyBRdWFkcmllcnRlIERpc3RhbnplbiAod2llIGltIEJlaXNwaWVsKQpuYWVoZXJ1bmdzbWF0cml4IDwtIGFzLm1hdHJpeChkaXN0YW56KV4yCgojIFJ1bmRlbiBmw7xyIGJlc3NlcmUgTGVzYmFya2VpdApuYWVoZXJ1bmdzbWF0cml4IDwtIHJvdW5kKG5hZWhlcnVuZ3NtYXRyaXgsIDMpCgojIFNwYWx0ZW4tIHVuZCBaZWlsZW5uYW1lbiBzZXR6ZW4gKMOcYmVyc2NocmlmdGVuKQpjb2xuYW1lcyhuYWVoZXJ1bmdzbWF0cml4KSA8LSBsYWJlbHMKcm93bmFtZXMobmFlaGVydW5nc21hdHJpeCkgPC0gbGFiZWxzCgojIE1hdHJpeCBhbnplaWdlbgpwcmludChuYWVoZXJ1bmdzbWF0cml4KQoKYGBgCgpCZWkgZGVyIER1cmNoZsO8aHJ1bmcgZWluZXIgQ2x1c3RlcmFuYWx5c2Ugd2lyZCB6dW7DpGNoc3QgZWluZSBzb2dlbmFubnRlIE7DpGhlcnVuZ3NtYXRyaXggKERpc3RhbnptYXRyaXgpIGVyc3RlbGx0LiBEaWVzZSBNYXRyaXggZW50aMOkbHQgZGllIHF1YWRyaWVydGVuIGV1a2xpZGlzY2hlbiBEaXN0YW56ZW4gZsO8ciBzw6RtdGxpY2hlIEtvbWJpbmF0aW9uZW4gdm9uIEbDpGxsZW4gKGhpZXI6IFNjaHVsZW4pIGltIERhdGVuc2F0ei4gRsO8ciBqZWRlcyBXZXJ0ZXBhYXIgbMOkc3N0IHNpY2ggZGFyYXVzIGRpcmVrdCBhYmxlc2VuLCB3aWUgZ3Jvw58gZGVyIEFic3RhbmQgendpc2NoZW4gZGVuIGVpbnplbG5lbiBGw6RsbGVuIGltIE1lcmttYWxzcmF1bSBpc3QuIERpZSBXZXJ0ZSBnZWJlbiBqZXdlaWxzIGRpZSBxdWFkcmllcnRlIEVudGZlcm51bmcgendpc2NoZW4gendlaSBTY2h1bGVuIGFuLgoKQmVpc3BpZWxzd2Vpc2UgYmV0csOkZ3QgZGVyIEFic3RhbmQgendpc2NoZW4g4oCeQUVH4oCcIHVuZCDigJ5BRlPigJwgZXhha3QgMCwzOTEgRWluaGVpdGVuLCB3YXMgYXVmIGVpbmUgaG9oZSDDhGhubGljaGtlaXQgZGllc2VyIGJlaWRlbiBTY2h1bGVuIGJlesO8Z2xpY2ggZGVyIHVudGVyc3VjaHRlbiBNZXJrbWFsZSBoaW5kZXV0ZXQuIEltIEdlZ2Vuc2F0eiBkYXp1IHplaWd0IGRlciBXZXJ0IHZvbiAyNSw3MzkgZsO8ciBkYXMgUGFhciDigJ5BRUfigJwgdW5kIOKAnlRTR+KAnCBlaW5lIHNlaHIgZ3Jvw59lIFZlcnNjaGllZGVuaGVpdC4KCkJlc29uZGVycyBuaWVkcmlnZSBXZXJ0ZSBpbiBkZXIgTWF0cml4IGRldXRlbiBkYXJhdWYgaGluLCBkYXNzIGRpZXNlIEbDpGxsZSBzaWNoIGhpbnNpY2h0bGljaCBpaHJlciBNZXJrbWFsc2F1c3Byw6RndW5nZW4gYmVzb25kZXJzIMOkaG5saWNoIHNpbmQgdW5kIHNvbWl0IGJlaSBkZXIgQ2x1c3RlcmJpbGR1bmcgZnLDvGggenVzYW1tZW5nZWZhc3N0IHdlcmRlbi4gSG9oZSBEaXN0YW56d2VydGUgemVpZ2VuIGRhZ2VnZW4gYmVzb25kZXJzIHVudGVyc2NoaWVkbGljaGUgRsOkbGxlIGFuLCBkaWUgZXJzdCBpbiBzcMOkdGVuIFNjaHJpdHRlbiBkZXMgQ2x1c3RlcmluZy1Qcm96ZXNzZXMgZ2VtZWluc2FtIGVpbmVtIENsdXN0ZXIgenVnZW9yZG5ldCB3ZXJkZW4uCgpEaWUgTsOkaGVydW5nc21hdHJpeCBiaWxkZXQgc29taXQgZGllIEJhc2lzIGbDvHIgZGFzIGhpZXJhcmNoaXNjaGUgQ2x1c3RlcmluZywgZGEgaW4gamVkZW0gU2Nocml0dCBzdGV0cyBkaWUgamV3ZWlscyDDpGhubGljaHN0ZW4gRsOkbGxlIGJ6dy4gQ2x1c3RlciB6dXNhbW1lbmdlZmFzc3Qgd2VyZGVuLgoKCmBgYHtyfQojIEhpZXJhcmNoaXNjaGVzIENsdXN0ZXJpbmcgKFdhcmQpCmhjIDwtIGhjbHVzdChkaXN0KGRhdGVuX3NjYWxlZCksIG1ldGhvZCA9ICJ3YXJkLkQyIikKYGBgCgoKYGBge3J9CgojIFRhYmVsbGUgZsO8ciBkaWUgWnVvcmRudW5nc8O8YmVyc2ljaHQgYmF1ZW4KenVvcmRudW5nIDwtIGRhdGEuZnJhbWUoCiAgU2Nocml0dCA9IDE6bGVuZ3RoKGhjJGhlaWdodCksCiAgQ2x1c3Rlcl8xID0gaGMkbWVyZ2VbLDFdLAogIENsdXN0ZXJfMiA9IGhjJG1lcmdlWywyXSwKICBLb2VmZml6aWVudCA9IHJvdW5kKGhjJGhlaWdodF4yLCAzKSkgIyBxdWFkcmllcnRlIERpc3RhbnogCgp6dW9yZG51bmckQ2x1c3Rlcl8xX0lEIDwtIGlmZWxzZSh6dW9yZG51bmckQ2x1c3Rlcl8xIDwgMCwgLXp1b3JkbnVuZyRDbHVzdGVyXzEsIHp1b3JkbnVuZyRDbHVzdGVyXzEpCnp1b3JkbnVuZyRDbHVzdGVyXzJfSUQgPC0gaWZlbHNlKHp1b3JkbnVuZyRDbHVzdGVyXzIgPCAwLCAtenVvcmRudW5nJENsdXN0ZXJfMiwgenVvcmRudW5nJENsdXN0ZXJfMikKCmNvbG5hbWVzKHp1b3JkbnVuZykgPC0gYygiU2Nocml0dCIsICJDbHVzdGVyIDEgKGludGVybikiLCAiQ2x1c3RlciAyIChpbnRlcm4pIiwgIktvZWZmaXppZW50ZW4iLCAiQ2x1c3RlciAxIiwgIkNsdXN0ZXIgMiIpCgoKenVvcmRudW5nX3RhYiA8LSB6dW9yZG51bmdbLGMoIlNjaHJpdHQiLCAiQ2x1c3RlciAxIiwgIkNsdXN0ZXIgMiIsICJLb2VmZml6aWVudGVuIildCnByaW50KHp1b3JkbnVuZ190YWIpCmBgYAoKCgpJbSB3ZWl0ZXJlbiBWZXJsYXVmIGRlciBBbmFseXNlIHdpcmQgaW4gZGVyIHNvZ2VuYW5udGVuIFp1b3JkbnVuZ3PDvGJlcnNpY2h0IGRldGFpbGxpZXJ0IGF1ZmdlemVpZ3QsIHdpZSBkaWUgZWluemVsbmVuIFNjaHJpdHRlIGRlciBDbHVzdGVyYmlsZHVuZyBhYmxhdWZlbi4gWnUgQmVnaW5uIGRlciBBbmFseXNlIGJpbGRldCBqZWRlciBGYWxsIGVpbiBlaWdlbmVzIENsdXN0ZXIuIEluIGplZGVtIFNjaHJpdHQgd2VyZGVuIGRhbm4gZGllIGJlaWRlbiBDbHVzdGVyIHp1c2FtbWVuZ2Vmw7xocnQsIGRpZSBkZW4gamV3ZWlscyBnZXJpbmdzdGVuIEFic3RhbmQgenVlaW5hbmRlciBhdWZ3ZWlzZW4g4oCTIGRpZXMgaXN0IGluIGRlciBTcGFsdGUg4oCeS29lZmZpemllbnRlbuKAnCBhbiBkZW4ga2xlaW5zdGVuIFdlcnRlbiB6dSBlcmtlbm5lbi4KClNvIHplaWd0IGRpZSDDnGJlcnNpY2h0IGJlaXNwaWVsc3dlaXNlLCBkYXNzIGltIGVyc3RlbiBTY2hyaXR0IChTY2hyaXR0IDE0KSBkaWUgQ2x1c3RlciAxIHVuZCAxNCBtaXRlaW5hbmRlciB2ZXJzY2htb2x6ZW4gd2VyZGVuLCBkYSBzaWUgZGVuIG1pbmltYWxlbiBBYnN0YW5kIHp1ZWluYW5kZXIgYXVmd2Vpc2VuIChLb2VmZml6aWVudDogMC4wMTQpLiBJbSBkYXJhdWYgZm9sZ2VuZGVuIFNjaHJpdHQgKFNjaHJpdHQgMTIpIHdpcmQgZGllc2VzIG5ldSBnZWJpbGRldGUgQ2x1c3RlciAoMS8xNCkgZGlyZWt0IG1pdCBDbHVzdGVyIDExIHp1c2FtbWVuZ2Vmw7xocnQgKEtvZWZmaXppZW50OiAwLjAxOSkuIERhZHVyY2ggZW50c3RlaHQgZWluIGdyw7bDn2VyZXMgQ2x1c3RlciAoMSwgMTEsIDE0KS4gUGFyYWxsZWwgZGF6dSB3ZXJkZW4gYXVjaCB3ZWl0ZXJlIEbDpGxsZSBtaXQgZ2VyaW5nZXIgRGlzdGFueiB6dXNhbW1lbmdlZmFzc3QsIHp1bSBCZWlzcGllbCBDbHVzdGVyIDMgdW5kIDUgKFNjaHJpdHQgOCwgS29lZmZpemllbnQ6IDAuMDQxKS4KCk1pdCBqZWRlbSB3ZWl0ZXJlbiBTY2hyaXR0IGluIGRlciBUYWJlbGxlIHdlcmRlbiBqZXdlaWxzIGRpZSBha3R1ZWxsIMOkaG5saWNoc3RlbiBDbHVzdGVycGFhcmUgdmVyZWluaWd0LCB3YXMgc2ljaCBkYXJhbiB6ZWlndCwgZGFzcyBkaWUgamV3ZWlsaWdlbiBLb2VmZml6aWVudGVuIHdlaXRlcmhpbiBlaGVyIGtsZWluIGJsZWliZW4gKHouQi4gMC4wMjQsIDAuMjE5LCAwLjI2MSB1c3cuKSwgYmV2b3IgbWl0IHp1bmVobWVuZGVyIENsdXN0ZXJncsO2w59lIGRpZSBXZXJ0ZSBkZXV0bGljaCBhbnN0ZWlnZW4uIEFtIEVuZGUgZGVzIFByb3plc3NlcyAoU2Nocml0dCAxNCB1bmQgU2Nocml0dCAxMykgd2VyZGVuIHNjaGxpZcOfbGljaCBkaWUgZ3LDtsOfdGVuLCB2ZXJibGllYmVuZW4gQ2x1c3RlciB6dXNhbW1lbmdlZsO8aHJ0LCB3b2JlaSBkaWUgS29lZmZpemllbnRlbiBudW4gZGV1dGxpY2ggZ3LDtsOfZXIgc2luZCAoei5CLiAxMy4xOTAgb2RlciAzMC42OTMpLiBEaWVzIHplaWd0LCBkYXNzIGluIGRlbiBsZXR6dGVuIFNjaHJpdHRlbiBhdWNoIHdlbmlnZXIgw6RobmxpY2hlIEdydXBwZW4genUgZWluZW0gR2VzYW10Y2x1c3RlciB2ZXJzY2htb2x6ZW4gd2VyZGVuLgoKRGllIEtvZWZmaXppZW50ZW4tU3BhbHRlIGRva3VtZW50aWVydCBkYWJlaSBkaWUgamV3ZWlscyBha3R1ZWxsZSBIZXRlcm9nZW5pdMOkdCBiZWltIFp1c2FtbWVuZsO8aHJlbiBkZXIgQ2x1c3RlciDigJMga2xlaW5lIFdlcnRlIHN0ZWhlbiBmw7xyIHNlaHIgw6RobmxpY2hlIEdydXBwZW4sIGdyb8OfZSBXZXJ0ZSBmw7xyIGRpZSBWZXJlaW5pZ3VuZyBzZWhyIHVudGVyc2NoaWVkbGljaGVyIENsdXN0ZXIuIERpZSBUYWJlbGxlIG1hY2h0IHNvbWl0IHRyYW5zcGFyZW50LCB3aWUgZGVyIEFsZ29yaXRobXVzIFNjaHJpdHQgZsO8ciBTY2hyaXR0IGltbWVyIGdyw7bDn2VyZSwgYWJlciBhdWNoIGltbWVyIHdlbmlnZXIgaG9tb2dlbmUgR3J1cHBlbiBiaWxkZXQsIGJpcyBhbGxlIEbDpGxsZSBpbiBlaW5lbSBlaW56aWdlbiBHZXNhbXRjbHVzdGVyIHZlcmVpbnQgc2luZC4KCgoKCiMgNi4JQmVzdGltbWVuIGRlciBBbnphaGwgQ2x1c3RlcgoKClp1IEJlZ2lubiBlaW5lcyBDbHVzdGVyYW5hbHlzZS1WZXJmYWhyZW5zIHdpcmQgamVkZXIgZWluemVsbmUgRmFsbCBhbHMgZWlnZW5zdMOkbmRpZ2VzIENsdXN0ZXIgYmV0cmFjaHRldC4gSW0gVmVybGF1ZiBkZXMgQW5hbHlzZXByb3plc3NlcyB3ZXJkZW4gZGllc2UgRWluemVsZsOkbGxlIHNjaHJpdHR3ZWlzZSB6dSBpbW1lciBncsO2w59lcmVuIEdydXBwZW4genVzYW1tZW5nZWbDvGhydCwgYmlzIHNjaGxpZcOfbGljaCBhbGxlIEbDpGxsZSBpbiBlaW5lbSBlaW56aWdlbiwgdW1mYXNzZW5kZW4gQ2x1c3RlciB2ZXJlaW50IHNpbmQuIERpZSB6ZW50cmFsZSBGcmFnZSwgZGllIHNpY2ggZGFiZWkgc3RlbGx0LCBpc3Q6ICoqV2llIHZpZWxlIENsdXN0ZXIgc2luZCBmw7xyIGRpZSBJbnRlcnByZXRhdGlvbiBkZXIgRGF0ZW4gc2lubnZvbGw/KiogRGFzIGhlacOfdCwgd28gendpc2NoZW4gZGVyIG1heGltYWxlbiBBbnphaGwgdm9uIENsdXN0ZXJuIChiZWkgMTUgRsOkbGxlbjogMTUgQ2x1c3RlcikgdW5kIG51ciBlaW5lbSBlaW56aWdlbiBDbHVzdGVyIGxpZWd0IGRpZSBvcHRpbWFsZSBMw7ZzdW5nPwoKVW0gZGllc2UgRW50c2NoZWlkdW5nIHp1IHRyZWZmZW4sIHdpcmQgaMOkdWZpZyBzb3dvaGwgYXVmIGluaGFsdGxpY2hlIMOcYmVybGVndW5nZW4gKGFsc28gZGllIFNpbm5oYWZ0aWdrZWl0IGJlc3RpbW10ZXIgR3J1cHBlbnphaGxlbiBmw7xyIGRhcyBVbnRlcnN1Y2h1bmdzemllbCkgYWxzIGF1Y2ggYXVmIGdyYWZpc2NoZSBIaWxmc21pdHRlbCB3aWUgZGFzIHNvZ2VuYW5udGUgKkRlbmRyb2dyYW1tKiB6dXLDvGNrZ2VncmlmZmVuLgoKYGBge3J9CiMgRGVuZHJvZ3JhbW0gcGxvdHRlbgpwbG90KGhjLCBtYWluID0gIkRlbmRyb2dyYW1tIG1pdCBXYXJkLVZlcmtuw7xwZnVuZyIsIHhsYWIgPSAiIiwgc3ViID0gIiIpCgojIFJvdGUgTWFya2llcnVuZyBmw7xyIG9wdGltYWxlIENsdXN0ZXItQW56YWhsIChoaWVyOiAyLUNsdXN0ZXItTMO2c3VuZykKcmVjdC5oY2x1c3QoaGMsIGsgPSAyLCBib3JkZXIgPSAicmVkIikKCmBgYAoKKipBbHRlcm5hdGl2ZSoqCgoKYGBge3J9CmdnZGVuZHJvOjpnZ2RlbmRyb2dyYW0oaGMsIGxhYmVscyA9IFQsIHJvdGF0ZSA9ICBUKQpgYGAKCkRhcyBvYmVuIGRhcmdlc3RlbGx0ZSBEZW5kcm9ncmFtbSB2aXN1YWxpc2llcnQgZGVuIGdlc2FtdGVuIENsdXN0ZXJiaWxkdW5nc3Byb3plc3MgaW4gRm9ybSBlaW5lciBCYXVtc3RydWt0dXIuIEFtIEFuZmFuZyBzdGVodCBqZWRlIFNjaHVsZSBhbHMgZWlnZW5zdMOkbmRpZ2VyIFB1bmt0IGdhbnogdW50ZW4gaW4gZGllc2VyIEJhdW1zdHJ1a3R1ci4gTWl0IGplZGVtIFNjaHJpdHQgd2VyZGVuIGpld2VpbHMgZGllIGJlaWRlbiDDpGhubGljaHN0ZW4gU2NodWxlbiBvZGVyIENsdXN0ZXIgenUgZWluZW0gZ2VtZWluc2FtZW4gQXN0IHp1c2FtbWVuZ2VmYXNzdCDigJMgZGllcyBpc3QgYW4gZGVuIHZlcnRpa2FsZW4gTGluaWVuIGRlciBCYXVtc3RydWt0dXIgZXJrZW5uYmFyLiBKZSBow7ZoZXIgZGllIFZlcmJpbmR1bmcgaW4gZGVyIEJhdW1zdHJ1a3R1ciBhbmdlc2V0enQgaXN0LCBkZXN0byBncsO2w59lciBpc3QgZGllIFVudGVyc2NoaWVkbGljaGtlaXQgKEhldGVyb2dlbml0w6R0KSBkZXIgenVzYW1tZW5nZWbDvGhydGVuIENsdXN0ZXIuCgpEaWUgdmVydGlrYWxlIEFjaHNlICgiSGVpZ2h0IikgZ2lidCBkaWUgRGlzdGFueiBhbiwgbWl0IGRlciBqZXdlaWxzIHp3ZWkgQ2x1c3RlciBmdXNpb25pZXJlbi4gRWluIGJlc29uZGVycyBncm/Dn2VyIFNwcnVuZyBhdWYgZGllc2VyIEFjaHNlIHNpZ25hbGlzaWVydCwgZGFzcyBhbiBkaWVzZXIgU3RlbGxlIHp3ZWkgR3J1cHBlbiB6dXNhbW1lbmdlbGVndCB3ZXJkZW4sIGRpZSBzaWNoIGJlcmVpdHMgZGV1dGxpY2ggdm9uZWluYW5kZXIgdW50ZXJzY2hlaWRlbi4KCkluIGRpZXNlbSBCZWlzcGllbCBpc3Qga2xhciB6dSBlcmtlbm5lbiwgZGFzcyBzaWNoIGVpbmUgWndlaS1DbHVzdGVyLUzDtnN1bmcgYW5iaWV0ZXQuIERpZSBiZWlkZW4gcm90ZW4gS8Okc3RlbiBtYXJraWVyZW4gZGllIENsdXN0ZXIsIGRpZSBuYWNoIGRlbSBncsO2w590ZW4gU3BydW5nIGluIGRlciBCYXVtc3RydWt0dXIgZW50c3RlaGVuOgoKKipEZXIgbGlua2UgQ2x1c3RlciBlbnRow6RsdCBkaWUgU2NodWxlbiBISEcsIEVLRywgRlNSLCBBRlMsIEFFRyB1bmQgRXZURywqKgoKKipkZXIgcmVjaHRlIENsdXN0ZXIgZmFzc3QgZGllIMO8YnJpZ2VuIFNjaHVsZW4genVzYW1tZW4gKFRTRywgU1NHLCBQUywgTU1TLCBNTFMsIEdTUywgRUFPLCBHRywgSFIpLioqCgpEaWUgV2FobCBkZXIgb3B0aW1hbGVuIENsdXN0ZXJ6YWhsIG9yaWVudGllcnQgc2ljaCBhbiBkZW0gUHVua3QsIGFuIGRlbSBpbiBkZXIgQmF1bXN0cnVrdHVyIGRlciBncsO2w590ZSBBYnN0YW5kICgiSGVpZ2h0Iikgendpc2NoZW4gendlaSBWZXJiaW5kdW5nZW4gYXVmdHJpdHQuIERhZHVyY2ggd2VyZGVuIHp3ZWkgR3J1cHBlbiBnZWJpbGRldCwgZGllIGludGVybiBtw7ZnbGljaHN0IMOkaG5saWNoIHVuZCB1bnRlcmVpbmFuZGVyIG3DtmdsaWNoc3QgdW50ZXJzY2hpZWRsaWNoIHNpbmQuCgpEaWVzZSBEYXJzdGVsbHVuZyBpbiBCYXVtc3RydWt0dXItRm9ybSBtYWNodCBkZW4gUHJvemVzcyBkZXIgQ2x1c3RlcmJpbGR1bmcgYmVzb25kZXJzIGFuc2NoYXVsaWNoIHVuZCBlcmxlaWNodGVydCBkaWUgbmFjaHZvbGx6aWVoYmFyZSBFaW50ZWlsdW5nIGRlciBiZXRyYWNodGV0ZW4gU2NodWxlbiBpbiBzaW5udm9sbGUgR3J1cHBlbi4KCgojIDcuCUJlc2NocmVpYnVuZyBkZXIgQ2x1c3RlcgoKRGllIFRhYmVsbGUgenVyIENsdXN0ZXItWnVnZWjDtnJpZ2tlaXQgemVpZ3QsIHdlbGNoZSBGw6RsbGUgamV3ZWlscyBkZW1zZWxiZW4gQ2x1c3RlciB6dWdlb3JkbmV0IHNpbmQuIEluIGRpZXNlbSBCZWlzcGllbCB3dXJkZSBlaW5lIFp3ZWktQ2x1c3Rlci1Mw7ZzdW5nIGdld8OkaGx0LCBzb2Rhc3MgZGFzIEhhdXB0YXVnZW5tZXJrIGF1ZiBkZXIgU3BhbHRlIGxpZWd0LCBkaWUgZGllIFp1Z2Vow7ZyaWdrZWl0IHp1IGRlbiBiZWlkZW4gQ2x1c3Rlcm4gYW5naWJ0LiBEYWJlaSB3aXJkIGRldXRsaWNoLCBkYXNzIGRpZSBGw6RsbGUgMSwgMiwgMywgNCwgNSwgMTAsIDExLCAxMiB1bmQgMTQgZGFzIGVyc3RlIENsdXN0ZXIgYmlsZGVuLCB3w6RocmVuZCBkaWUgRsOkbGxlIDYsIDcsIDgsIDksIDEzIHVuZCAxNSBkZW0gendlaXRlbiBDbHVzdGVyIHp1Z2VvcmRuZXQgd2VyZGVuLgoKCmBgYHtyfQoKIyBDbHVzdGVyenVnZWjDtnJpZ2tlaXRlbiBmw7xyIDUsIDQsIDMsIDIgQ2x1c3RlciBiZXJlY2huZW4KY2x1c3RlcnMgPC0gZGF0YS5mcmFtZSgKICBGYWxsID0gbGFiZWxzLAogIGA1IENsdXN0ZXJgID0gY3V0cmVlKGhjLCBrID0gNSksCiAgYDQgQ2x1c3RlcmAgPSBjdXRyZWUoaGMsIGsgPSA0KSwKICBgMyBDbHVzdGVyYCA9IGN1dHJlZShoYywgayA9IDMpLAogIGAyIENsdXN0ZXJgID0gY3V0cmVlKGhjLCBrID0gMikKKQoKIyBBdXNnYWJlIHdpZSBpbSBTUFNTLUJlaXNwaWVsCnByaW50KGNsdXN0ZXJzKQpgYGAKClVtIGRpZSBvcHRpbWFsZSBBbnphaGwgYW4gQ2x1c3Rlcm4gZsO8ciBkYXMgay1NZWFucy1WZXJmYWhyZW4gZmVzdHp1bGVnZW4sIHdpcmQgaMOkdWZpZyBkYXMgc29nZW5hbm50ZSBFbGJvdy1Lcml0ZXJpdW0gKEtuaWVwdW5rdC1Lcml0ZXJpdW0pIGhlcmFuZ2V6b2dlbi4gRGF6dSB3aXJkIGbDvHIgdmVyc2NoaWVkZW5lIFdlcnRlIHZvbiBrIChBbnphaGwgZGVyIENsdXN0ZXIpIGRpZSBnZXNhbXRlIGlubmVyaGFsYiBkZXIgQ2x1c3RlciBsaWVnZW5kZSBRdWFkcmF0c3VtbWUgKOKAnlRvdGFsIFdpdGhpbi1DbHVzdGVyIFN1bSBvZiBTcXVhcmVz4oCcLCB0b3Qud2l0aGluc3MpIGJlcmVjaG5ldCB1bmQgZ3JhZmlzY2ggZGFyZ2VzdGVsbHQuIERlciBkYXJhdXMgZW50c3RlaGVuZGUgRWxib3ctUGxvdCB6ZWlndCwgd2llIHN0YXJrIGRpZSBIZXRlcm9nZW5pdMOkdCBpbm5lcmhhbGIgZGVyIENsdXN0ZXIgbWl0IHN0ZWlnZW5kZXIgQ2x1c3RlcnphaGwgYWJuaW1tdC4KCkRhcyBaaWVsIGRpZXNlcyBBbnNhdHplcyBpc3QgZXMsIGRlbiBQdW5rdCB6dSBpZGVudGlmaXppZXJlbiwgYW4gZGVtIGVpbmUgd2VpdGVyZSBFcmjDtmh1bmcgZGVyIENsdXN0ZXJhbnphaGwgenUga2VpbmVyIHdlc2VudGxpY2hlbiBWZXJiZXNzZXJ1bmcgbWVociBmw7xocnQuIERpZXNlciBQdW5rdCDigJMgZGVyIHNvZ2VuYW5udGUg4oCeS25pY2vigJwgb2RlciDigJ5FbGJvd+KAnCDigJMgZ2lidCBlaW5lbiBIaW53ZWlzIGRhcmF1Ziwgd2llIHZpZWxlIENsdXN0ZXIgZGllIHZvcmhhbmRlbmUgU3RydWt0dXIgZGVyIERhdGVuIGFtIGJlc3RlbiBiZXNjaHJlaWJlbi4gQXVmIGRpZXNlIFdlaXNlIGzDpHNzdCBzaWNoIGVpbmUgYXVzZ2V3b2dlbmUgQmFsYW5jZSB6d2lzY2hlbiB6dSBncm9iZXIgdW5kIHp1IGZlaW5lciBHcnVwcGllcnVuZyBmaW5kZW4uCgoKYGBge3J9Cm11bHRpLmNsdXN0IDwtIGRhdGEuZnJhbWUoayA9IDE6NCkgJT4lIGdyb3VwX2J5KGspICU+JSBkbyhjbHVzdCA9IGttZWFucyhDbHVzdGVyYW5hbHlzZSwgLiRrKSkKc3Vtc3EuY2x1c3QgPC0gbXVsdGkuY2x1c3QgJT4lIGdyb3VwX2J5KGspICU+JSBkbyhnbGFuY2UoLiRjbHVzdFtbMV1dKSkKCmdncGxvdChzdW1zcS5jbHVzdCwgYWVzKGssIHRvdC53aXRoaW5zcykpICsgZ2VvbV9saW5lKCkgKyBnZW9tX3BvaW50KCkKYGBgCgpEaWUgR3JhZmlrIHplaWd0IGRlbiBWZXJsYXVmIGRlciBnZXNhbXRlbiBpbm5lcmhhbGIgZGVyIENsdXN0ZXIgbGllZ2VuZGVuIFF1YWRyYXRzdW1tZSAodG90LndpdGhpbnNzKSBpbiBBYmjDpG5naWdrZWl0IHZvbiBkZXIgZ2V3w6RobHRlbiBDbHVzdGVyYW56YWhsIChrKS4gTWFuIGVya2VubnQgZGV1dGxpY2gsIGRhc3MgZGVyIFdlcnQgZsO8ciB0b3Qud2l0aGluc3MgYmVpbSBXZWNoc2VsIHZvbiBlaW5lbSBhdWYgendlaSBDbHVzdGVyIHN0YXJrIGFibmltbXQuIERpZXNlciBzdGFya2UgUsO8Y2tnYW5nIGJlZGV1dGV0LCBkYXNzIGR1cmNoIGRpZSBBdWZ0ZWlsdW5nIGluIHp3ZWkgQ2x1c3RlciBlaW4gR3Jvw590ZWlsIGRlciBIZXRlcm9nZW5pdMOkdCBpbm5lcmhhbGIgZGVyIEdydXBwZW4gYmVyZWl0cyBlcmtsw6RydCB3aXJkLgoKTWl0IGplZGVyIHdlaXRlcmVuIEVyaMO2aHVuZyB2b24gayBzaW5rdCBkaWUgdG90LndpdGhpbnNzIHp3YXIgd2VpdGVyLCBkZXIgWnVnZXdpbm4gYW4gSG9tb2dlbml0w6R0IGbDpGxsdCBqZWRvY2ggenVuZWhtZW5kIGdlcmluZ2VyIGF1cy4gQmVzb25kZXJzIGF1ZmbDpGxsaWcgaXN0IGRlciDigJ5Lbmlja+KAnCB6d2lzY2hlbiBrID0gMiB1bmQgayA9IDMsIGFiIGRlbSBzaWNoIGRpZSBLdXJ2ZSBhYmZsYWNodC4gRGllcyBkZXV0ZXQgZGFyYXVmIGhpbiwgZGFzcyBkaWUgV2FobCB2b24gendlaSBDbHVzdGVybiBlaW5lIHNpbm52b2xsZSBMw7ZzdW5nIGRhcnN0ZWxsdCwgZGEgenVzw6R0emxpY2hlIENsdXN0ZXIgbnVyIG5vY2ggZWluZW4gdmVyZ2xlaWNoc3dlaXNlIGdlcmluZ2VuIE1laHJ3ZXJ0IGJyaW5nZW4uCgpadXNhbW1lbmZhc3NlbmQgbMOkc3N0IHNpY2ggZmVzdGhhbHRlbiwgZGFzcyBkYXMgRWxib3ctS3JpdGVyaXVtIGhpZXIga2xhciBmw7xyIGVpbmUgWndlaS1DbHVzdGVyLUzDtnN1bmcgc3ByaWNodCwgd2VpbCBhbiBkaWVzZXIgU3RlbGxlIGRlciBncsO2w590ZSByZWxhdGl2ZSBadWdld2lubiBhbiBIb21vZ2VuaXTDpHQgZXJ6aWVsdCB3aXJkIHVuZCBkaWUgRGF0ZW4gc29taXQgZWZmaXppZW50IHVuZCBzaW5udm9sbCBncnVwcGllcnQgd2VyZGVuLgoKKip3ZWl0ZXJlIEtsw6RydW5nKioKClp1ciBncmFmaXNjaGVuIERhcnN0ZWxsdW5nIGRlciBDbHVzdGVyIGVpZ25ldCBzaWNoIGVpbiBTdHJldWRpYWdyYW1tIChTY2F0dGVycGxvdCksIGJlaSBkZW0gZGllIEbDpGxsZSBlbnRzcHJlY2hlbmQgaWhyZXIgQ2x1c3Rlcnp1Z2Vow7ZyaWdrZWl0IGZhcmJsaWNoIHVudGVyc2NoaWVkZW4gd2VyZGVuLiBEYWJlaSB3ZXJkZW4gZGllIGJlaWRlbiBhdXNnZXfDpGhsdGVuIE1lcmttYWxlIGF1ZiBkZW4gQWNoc2VuIGFiZ2V0cmFnZW4sIHVuZCBkaWUgRGF0ZW5wdW5rdGUgZXJoYWx0ZW4gdW50ZXJzY2hpZWRsaWNoZSBGYXJiZW4gb2RlciBTeW1ib2xlLCBqZSBuYWNoZGVtLCB6dSB3ZWxjaGVtIENsdXN0ZXIgc2llIGdlaMO2cmVuLiBEaWUgR3J1cHBlbnp1Z2Vow7ZyaWdrZWl0IHdpcmQgZGFiZWkgZHVyY2ggZGllIFZhcmlhYmxlIGRhcmdlc3RlbGx0LCBkaWUgZGllIENsdXN0ZXJ6dW9yZG51bmcgZW50aMOkbHQuIEF1ZiBkaWVzZSBXZWlzZSBsw6Rzc3Qgc2ljaCBkaWUgVmVydGVpbHVuZyBkZXIgQ2x1c3RlciB2aXN1ZWxsIGxlaWNodCBuYWNodm9sbHppZWhlbi4KCgoKCioqVm9yYmVyZWl0dW5nKioKYGBge3J9CkNsdXN0ZXJhbmFseXNlJFNjaHVsZSA8LSBOVUxMCnJvdy5uYW1lcyhDbHVzdGVyYW5hbHlzZSk8LSBjbHVzdGVycyRGYWxsClZpZXcoQ2x1c3RlcmFuYWx5c2UpCmBgYAoKCmBgYHtyfQpwLmNsdXN0ZXIgPC0gQ2x1c3RlcmFuYWx5c2UgJT4lIGttZWFucyguLCAyKQpwLmNsdXN0ZXIkY2x1c3RlciA8LSBhcy5mYWN0b3IocC5jbHVzdGVyJGNsdXN0ZXIpCmdncGxvdChDbHVzdGVyYW5hbHlzZSwgYWVzKEtsYXNzZW5CdWRnZXQsIGRpZ2l0YWxlcl9BdXNzdGF0dHVuZ3NzY29yZSwgbGFiZWwgPSByb3duYW1lcyhDbHVzdGVyYW5hbHlzZSkpKSArIAogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZSA9ICJDbHVzdGVyIikgICsKICBnZW9tX2xhYmVsKGFlcyhmaWxsID0gcC5jbHVzdGVyJGNsdXN0ZXIpLCBjb2xvdXIgPSAid2hpdGUiLCAKICBmb250ZmFjZSA9ICJib2xkIiwgc2l6ZT0yKQpgYGAKCgpEYXMgU3RyZXVkaWFncmFtbSB6ZWlndCBhbnNjaGF1bGljaCwgd2llIGRpZSBlaW56ZWxuZW4gRGF0ZW5wdW5rdGUgZGVuIENsdXN0ZXJuIHp1Z2VvcmRuZXQgc2luZC4gRGFiZWkgZsOkbGx0IGF1ZiwgZGFzcyBkZXIgV2VydCBmw7xyIOKAnkNFT+KAnCBtw7ZnbGljaGVyd2Vpc2UgZWluZW4gQXVzcmVpw59lciBkYXJzdGVsbHQuIE9id29obCBkaWVzZXIgRmFsbCBkZW5ub2NoIGVpbmVtIGRlciBiZWlkZW4gQ2x1c3RlciB6dWdlb3JkbmV0IHd1cmRlLCBrw7ZubnRlIG1hbiBhbHRlcm5hdGl2IGF1Y2ggw7xiZXJsZWdlbiwgaWhuIGFscyBlaWdlbmVzIENsdXN0ZXIgenUgYmVoYW5kZWxuICh6LuKAr0IuIGR1cmNoIGVpbmUgRHJlaS1DbHVzdGVyLUzDtnN1bmcpIG9kZXIgaWhuIGdhbnogYXVzIGRlciBBbmFseXNlIGF1c3p1c2NobGllw59lbi4KCgoKKipDbHVzdGVyIDEqKiB1bWZhc3N0IFNjaHVsZW4gbWl0IG5pZWRyaWdlbSBLbGFzc2VuYnVkZ2V0IHVuZCBnZXJpbmdlbSBkaWdpdGFsZW4gQXVzc3RhdHR1bmdzLVNjb3JlLiBEaWVzZSBHcnVwcGUgYmVzdGVodCBtZWlzdCBhdXMga2xlaW5lcmVuIG9kZXIgZmluYW56aWVsbCBzY2h3w6RjaGVyIGF1c2dlc3RhdHRldGVuIFNjaHVsZW4gbWl0IE5hY2hob2xiZWRhcmYgYmVpIGRlciBEaWdpdGFsaXNpZXJ1bmcuCgoqKkNsdXN0ZXIgMioqIGJlaW5oYWx0ZXQgU2NodWxlbiBtaXQgaG9oZW0gQnVkZ2V0IHVuZCBmb3J0c2Nocml0dGxpY2hlciBkaWdpdGFsZXIgQXVzc3RhdHR1bmcuIEhpZXJ6dSB6w6RobGVuIGjDpHVmaWcgZ3LDtsOfZXJlIG9kZXIgYmVzc2VyIGdlZsO2cmRlcnRlIFNjaHVsZW4sIGRpZSBiZXJlaXRzIHVtZmFzc2VuZGVyIGluIG1vZGVybmUgVGVjaG5vbG9naWVuIGludmVzdGllcnQgaGFiZW4uCgoKCiphbGxlICoKCgoKYGBge3J9Cm11bHRpLmNsdXN0IDwtIGRhdGEuZnJhbWUoayA9IDE6NSkgJT4lIGdyb3VwX2J5KGspICU+JSBkbyhjbHVzdCA9IGttZWFucyhDbHVzdGVyYW5hbHlzZSwgLiRrKSkKbXVsdGkuayA8LSBtdWx0aS5jbHVzdCAlPiUgZ3JvdXBfYnkoaykgJT4lIGRvKGF1Z21lbnQoLiRjbHVzdFtbMV1dLCBDbHVzdGVyYW5hbHlzZSkpCgpnZ3Bsb3QobXVsdGkuaywgYWVzKEtsYXNzZW5CdWRnZXQsIGRpZ2l0YWxlcl9BdXNzdGF0dHVuZ3NzY29yZSwpKSArIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gLmNsdXN0ZXIpKSArIAogIGZhY2V0X3dyYXAofmspCmBgYAoKRsO8ciBkaWUgSW50ZXJwcmV0YXRpb24gdW5kIEJlc2NocmVpYnVuZyBkZXIgZ2VmdW5kZW5lbiBDbHVzdGVyIHdlcmRlbiBow6R1ZmlnIGRlc2tyaXB0aXZlIFN0YXRpc3Rpa2VuIGdlbnV0enQuIERhenUgdGVpbHQgbWFuIGRlbiBEYXRlbnNhdHogZW50c3ByZWNoZW5kIGRlciBDbHVzdGVyenVnZWjDtnJpZ2tlaXQgYXVmIHVuZCBiZXJlY2huZXQgZsO8ciBqZWRlcyBDbHVzdGVyIGJlaXNwaWVsc3dlaXNlIE1pdHRlbHdlcnRlIG9kZXIgSMOkdWZpZ2tlaXRlbiB3aWNodGlnZXIgTWVya21hbGUuIFNvIGzDpHNzdCBzaWNoIGRpZSBadXNhbW1lbnNldHp1bmcgZGVyIENsdXN0ZXIgZ2V6aWVsdCB2ZXJnbGVpY2hlbiB1bmQgY2hhcmFrdGVyaXNpZXJlbi4KCgpgYGB7cn0KQ2x1c3RlcmFuYWx5c2UkQ2x1c3RlcjIgPC0gYXMuZmFjdG9yKGN1dHJlZShoYywgayA9IDIpKQoKIyA5LiBDbHVzdGVyYmVzY2hyZWlidW5nIChNaXR0ZWx3ZXJ0ZSBqZSBDbHVzdGVyKQpjbHVzdGVyX3N1bW1hcnkgPC0gQ2x1c3RlcmFuYWx5c2UgJT4lCiAgZ3JvdXBfYnkoQ2x1c3RlcjIpICU+JQogIHN1bW1hcmlzZSgKICAgIE1pdHRlbHdlcnRfS2xhc3NlbkJ1ZGdldCA9IG1lYW4oS2xhc3NlbkJ1ZGdldCksCiAgICBNaXR0ZWx3ZXJ0X0RpZ2l0YWxTY29yZSA9IG1lYW4oZGlnaXRhbGVyX0F1c3N0YXR0dW5nc3Njb3JlKSwKICAgIEFuemFobCA9IG4oKQogICkKcHJpbnQoY2x1c3Rlcl9zdW1tYXJ5KQoKIyAxMC4gKE9wdGlvbmFsKSB0LVRlc3QgenVtIENsdXN0ZXJ2ZXJnbGVpY2gKdC50ZXN0KEtsYXNzZW5CdWRnZXQgfiBDbHVzdGVyMiwgZGF0YSA9IENsdXN0ZXJhbmFseXNlKQp0LnRlc3QoZGlnaXRhbGVyX0F1c3N0YXR0dW5nc3Njb3JlIH4gQ2x1c3RlcjIsIGRhdGEgPSBDbHVzdGVyYW5hbHlzZSkKYGBgCgoKWnVyIMOcYmVycHLDvGZ1bmcsIG9iIHNpY2ggZGllIENsdXN0ZXIgaGluc2ljaHRsaWNoIGRlcyBLbGFzc2VuYnVkZ2V0cyB1bmQgZGVzIGRpZ2l0YWxlbiBBdXNzdGF0dHVuZ3PCrXNjb3JlcyBzaWduaWZpa2FudCB1bnRlcnNjaGVpZGVuLCB3dXJkZW4gdW5hYmjDpG5naWdlIFN0aWNocHJvYmVuLXQtVGVzdHMgZHVyY2hnZWbDvGhydC4KCkbDvHIgZGFzIEtsYXNzZW5idWRnZXQgZXJnYWIgZGVyIFRlc3QgZWluZW4gc2lnbmlmaWthbnRlbiBVbnRlcnNjaGllZCB6d2lzY2hlbiBkZW4gYmVpZGVuIENsdXN0ZXJuLCB0KDExLjc5KSA9IC0zLjI2LCBwID0gLjAwNy4gRGllIG1pdHRsZXJlbiBLbGFzc2VuYnVkZ2V0cyBsYWdlbiBiZWkgQ2x1c3RlciAxIGJlaSBNID0gMzYuNTggdW5kIGJlaSBDbHVzdGVyIDIgYmVpIE0gPSA2Ny43Ni4gRGFzIDk1JS1Lb25maWRlbnppbnRlcnZhbGwgZsO8ciBkaWUgTWl0dGVsd2VydHNkaWZmZXJlbnogbGFnIHp3aXNjaGVuIC01Mi4wNSB1bmQgLTEwLjMwLgoKQXVjaCBmw7xyIGRlbiBkaWdpdGFsZW4gQXVzc3RhdHR1bmdzc2NvcmUgemVpZ3RlIHNpY2ggZWluIGhvY2hzaWduaWZpa2FudGVyIFVudGVyc2NoaWVkIHp3aXNjaGVuIGRlbiBDbHVzdGVybiwgdCg4LjA5KSA9IC01LjI5LCBwIDwgLjAwMS4gRGVyIE1pdHRlbHdlcnQgaW0gZXJzdGVuIENsdXN0ZXIgYmV0cnVnIE0gPSAxMzEuMDMsIGltIHp3ZWl0ZW4gQ2x1c3RlciBNID0gMjM5LjI0LiBEYXMgOTUlLUtvbmZpZGVuemludGVydmFsbCBmw7xyIGRpZSBNaXR0ZWx3ZXJ0c2RpZmZlcmVueiByZWljaHRlIHZvbiAtMTU1LjMwIGJpcyAtNjEuMTIuCgpJbnRlcnByZXRhdGlvbjoKRGllIEVyZ2Vibmlzc2UgemVpZ2VuLCBkYXNzIHNpY2ggZGllIGJlaWRlbiBpZGVudGlmaXppZXJ0ZW4gQ2x1c3RlciBzb3dvaGwgaW0gS2xhc3NlbmJ1ZGdldCBhbHMgYXVjaCBpbSBkaWdpdGFsZW4gQXVzc3RhdHR1bmdzZ3JhZCBzaWduaWZpa2FudCB1bnRlcnNjaGVpZGVuLgoKCgoKIyA4LglFaW5lIEF1c3NhZ2UKSW0gUmFobWVuIGRlciB2b3JsaWVnZW5kZW4gVW50ZXJzdWNodW5nIHd1cmRlIGVpbmUgaGllcmFyY2hpc2NoZSBDbHVzdGVyYW5hbHlzZSB1bnRlciBBbndlbmR1bmcgZGVyIFdhcmQtTWV0aG9kZSB1bmQgYXVmIEJhc2lzIGRlciBxdWFkcmllcnRlbiBldWtsaWRpc2NoZW4gRGlzdGFueiBkdXJjaGdlZsO8aHJ0LiBaaWVsIHdhciBlcywgZGllIHVudGVyc3VjaHRlbiBTY2h1bGVuIGFuaGFuZCBkZXIgTWVya21hbGUg4oCeS2xhc3NlbmJ1ZGdldOKAnCB1bmQg4oCeZGlnaXRhbGVyIEF1c3N0YXR0dW5ncy1TY29yZeKAnCBpbiBtw7ZnbGljaHN0IGhvbW9nZW5lIEdydXBwZW4gZWluenV0ZWlsZW4gdW5kIHNvIHZlcmJvcmdlbmUgU3RydWt0dXJlbiBpbm5lcmhhbGIgZGVzIERhdGVuc2F0emVzIHNpY2h0YmFyIHp1IG1hY2hlbi4KCkRpZSBBdXN3ZXJ0dW5nIGRlcyB6dWdlaMO2cmlnZW4gRGVuZHJvZ3JhbW1zIHVuZCBkaWUgQW53ZW5kdW5nIGRlcyBFbGJvdy1Lcml0ZXJpdW1zICh2Z2wuIEFiYmlsZHVuZyBYKSBkZXV0ZW4gZGFyYXVmIGhpbiwgZGFzcyBlaW5lIFp3ZWktQ2x1c3Rlci1Mw7ZzdW5nIGRpZSB2b3JoYW5kZW5lIEhldGVyb2dlbml0w6R0IGluIGRlbiBEYXRlbiBhbSBiZXN0ZW4gYWJiaWxkZXQuIERlciBtYXJrYW50ZXN0ZSBBbnN0aWVnIGRlciBGdXNpb25zZGlzdGFuemVuIGltIERlbmRyb2dyYW1tIGxlZ3QgbmFoZSwgZGFzcyBkaWUgWnVzYW1tZW5mYXNzdW5nIGF1ZiB6d2VpIEdydXBwZW4gc293b2hsIHN0YXRpc3Rpc2NoIHNpbm52b2xsIGFscyBhdWNoIGF1cyBpbmhhbHRsaWNoZXIgUGVyc3Bla3RpdmUgcGxhdXNpYmVsIGlzdC4KClp1ciDDnGJlcnByw7xmdW5nIGRlciBVbnRlcnNjaGllZGUgendpc2NoZW4gZGVuIENsdXN0ZXJuIHd1cmRlbiB1bmFiaMOkbmdpZ2UgU3RpY2hwcm9iZW4tdC1UZXN0cyBkdXJjaGdlZsO8aHJ0LiBEaWUgRXJnZWJuaXNzZSB6ZWlnZW4sIGRhc3Mgc2ljaCBkaWUgYmVpZGVuIENsdXN0ZXIgc2lnbmlmaWthbnQgc293b2hsIGltIEtsYXNzZW5idWRnZXQgKHQoMTEuNzkpID0gLTMuMjYsIHAgPSAuMDA3LCA5NSUtQ0kgWy01Mi4wNTsgLTEwLjMwXSkgYWxzIGF1Y2ggaW0gZGlnaXRhbGVuIEF1c3N0YXR0dW5ncy1TY29yZSAodCg4LjA5KSA9IC01LjI5LCBwIDwgLjAwMSwgOTUlLUNJIFstMTU1LjMwOyAtNjEuMTJdKSB1bnRlcnNjaGVpZGVuLiBEaWUgTWl0dGVsd2VydGUgaW4gZGVuIGJlaWRlbiBDbHVzdGVybiBsaWVnZW4gYmVpbSBLbGFzc2VuYnVkZ2V0IGJlaSBN4oKBID0gMzYuNTggKFNEIG5pY2h0IGF1c2dld2llc2VuKSB1bmQgTeKCgiA9IDY3Ljc2LCBiZWltIEF1c3N0YXR0dW5ncy1TY29yZSBiZWkgTeKCgSA9IDEzMS4wMyB1bmQgTeKCgiA9IDIzOS4yNC4gRGllIERpZmZlcmVuemVuIHNpbmQgc29taXQgc293b2hsIHN0YXRpc3Rpc2NoIHNpZ25pZmlrYW50IGFscyBhdWNoIHByYWt0aXNjaCBiZWRldXRzYW0uCgpJbnRlcnByZXRhdGlvbiBkZXIgQ2x1c3RlcnN0cnVrdHVyOgpDbHVzdGVyIDEgdW1mYXNzdCBqZW5lIFNjaHVsZW4sIGRpZSBzb3dvaGwgw7xiZXIgZWluIHVudGVyZHVyY2hzY2huaXR0bGljaGVzIEtsYXNzZW5idWRnZXQgYWxzIGF1Y2ggw7xiZXIgZWluZW4gdmVyZ2xlaWNoc3dlaXNlIG5pZWRyaWdlbiBkaWdpdGFsZW4gQXVzc3RhdHR1bmdzLVNjb3JlIHZlcmbDvGdlbi4gVHlwaXNjaGVyd2Vpc2UgZ2Vow7ZyZW4genUgZGllc2VyIEdydXBwZSBiZWlzcGllbHN3ZWlzZSBrbGVpbmVyZSBvZGVyIGZpbmFuemllbGwgd2VuaWdlciBzdGFyayBhdXNnZXN0YXR0ZXRlIFNjaHVsZW4sIGRpZSBtw7ZnbGljaGVyd2Vpc2UgaW0gQmVyZWljaCBkZXIgZGlnaXRhbGVuIEluZnJhc3RydWt0dXIgbm9jaCBFbnR3aWNrbHVuZ3NiZWRhcmYgYXVmd2Vpc2VuLgoKQ2x1c3RlciAyIGhpbmdlZ2VuIHNldHp0IHNpY2ggYXVzIFNjaHVsZW4genVzYW1tZW4sIGRpZSBzb3dvaGwgZWluIGRldXRsaWNoIGjDtmhlcmVzIEJ1ZGdldCBhbHMgYXVjaCBlaW5lIGZvcnRzY2hyaXR0bGljaGVyZSBkaWdpdGFsZSBBdXNzdGF0dHVuZyBhdWZ3ZWlzZW4uIERpZXNlIEdydXBwZSBrw7ZubnRlIHp1bSBCZWlzcGllbCBHeW1uYXNpZW4gb2RlciBTY2h1bGVuIGluIHdvaGxoYWJlbmRlcmVuIFJlZ2lvbmVuIHVtZmFzc2VuLCBiZWkgZGVuZW4gbWVociBNaXR0ZWwgZsO8ciBtb2Rlcm5lIEF1c3N0YXR0dW5nIHp1ciBWZXJmw7xndW5nIHN0ZWhlbiB1bmQgZGllIHRlbmRlbnppZWxsIGF1Y2ggdm9uIGdlemllbHRlbiBEaWdpdGFsaXNpZXJ1bmdzaW5pdGlhdGl2ZW4gcHJvZml0aWVydCBoYWJlbi4KCkRpZSBncmFmaXNjaGUgRGFyc3RlbGx1bmcgZGVyIENsdXN0ZXIgaW4gZGVyIEJhdW1zdHJ1a3R1ciBkZXMgRGVuZHJvZ3JhbW1zIHplaWd0IGRldXRsaWNoLCBkYXNzIGlubmVyaGFsYiBkZXIgYmVpZGVuIEdydXBwZW4gZWluZSBob2hlIMOEaG5saWNoa2VpdCBoaW5zaWNodGxpY2ggZGVyIGJldHJhY2h0ZXRlbiBNZXJrbWFsZSBiZXN0ZWh0LCB3w6RocmVuZCBzaWNoIGRpZSBHcnVwcGVuIHVudGVyZWluYW5kZXIga2xhciB2b25laW5hbmRlciBhYmdyZW56ZW4uIERpZXNlIEJlZnVuZGUgd2VyZGVuIGR1cmNoIGRpZSBFcmdlYm5pc3NlIGRlciB0LVRlc3RzIHdlaXRlciB1bnRlcm1hdWVydC4KClp1c2FtbWVuZmFzc2VuZCBsw6Rzc3Qgc2ljaCBmZXN0aGFsdGVuOgpEaWUgZHVyY2hnZWbDvGhydGUgQ2x1c3RlcmFuYWx5c2UgYmVzdMOkdGlndCwgZGFzcyBTY2h1bGVuIGFuaGFuZCBkZXIgYmVpZGVuIHVudGVyc3VjaHRlbiBNZXJrbWFsZSB6dXZlcmzDpHNzaWcgaW4gendlaSB1bnRlcnNjaGllZGxpY2hlIFR5cGVuIGVpbmdldGVpbHQgd2VyZGVuIGvDtm5uZW4uIERpZSBadWdlaMO2cmlna2VpdCB6dSBlaW5lbSBkZXIgYmVpZGVuIENsdXN0ZXIgaXN0IGRhYmVpIGVuZyBtaXQgZGVuIGpld2VpbGlnZW4gQXVzcHLDpGd1bmdlbiBpbiBCdWRnZXQgdW5kIERpZ2l0YWxpc2llcnVuZyB2ZXJrbsO8cGZ0LiBEaWUgQW5hbHlzZSBiaWV0ZXQgc29taXQgZWluZSBiZWxhc3RiYXJlIEdydW5kbGFnZSBmw7xyIGVpbmUgZ2V6aWVsdGUgRsO2cmRlci0gb2RlciBJbnRlcnZlbnRpb25zc3RyYXRlZ2llLCBldHdhIGluZGVtIFNjaHVsZW4gbWl0IG5pZWRyaWdlcmVtIEJ1ZGdldCB1bmQgQXVzc3RhdHR1bmdzZ3JhZCBnZXppZWx0IGluIGlocmVyIGRpZ2l0YWxlbiBFbnR3aWNrbHVuZyB1bnRlcnN0w7x0enQgd2VyZGVuLgoKCgoKCgo=