Hinweise


Antwort
 
LinkBack (10) Themen-Optionen Thema durchsuchen
Alt 25.04.2008, 18:27   #76
TP-Specialist
 
Benutzerbild von theo
 
Registriert seit: Apr 2002
Ort: 743, evergreen terrace
theo bringt sich richtig ein
Zitat:
Zitat von Boris Beitrag anzeigen
Die Liste funktioniert so nicht, weil das HTML falsch ist, bzw. die Liste falsch verschachtelt.

Man kann das nicht einfach "vergessen" oder sollte sich dann nicht wundern, wenn die Liste nicht korrekt dargestellt wird.
hi boris,
schoen, dass es wenigstens dazu gefuehrt hat, dass wir uns mal wieder in einem thread treffen.

@peter: bevor wir uns den kopf ueber komplizierte mysql-statements, riesige mehrdimensionale arrays und deren moeglichst fehlerfreier speicherung in einer session die koepfe zerbrechen stellt sich mir nur eine frage: warum nicht so, wie ich es vorgeschlagen habe? zu einfach? immerhin halte ich den geraden und kurzen weg fuer den weniger fehleranfaelligen (sieht mal mal von den huerden sauberer listenverschachtelung in html-sturkturcodes ab ).
also warum ewig viel code fuer eine sache schreiben, die in wenigen zeilen geschichte sein koennte?!
__________________
/b{2}|[^(bb)]/

[Workshop] Nested sets
webdevelopment + visualisierung
theo ist offline   Mit Zitat antworten


Alt 25.04.2008, 18:37   #77
TP-Moderator
 
Benutzerbild von Cybergreek
 
Registriert seit: Nov 2005
Ort: Köln
Cybergreek ist ein richtiges Arbeitstier - DANKECybergreek ist ein richtiges Arbeitstier - DANKECybergreek ist ein richtiges Arbeitstier - DANKECybergreek ist ein richtiges Arbeitstier - DANKECybergreek ist ein richtiges Arbeitstier - DANKECybergreek ist ein richtiges Arbeitstier - DANKE
Zitat:
Zitat von theo Beitrag anzeigen
...also warum ewig viel code fuer eine sache schreiben, die in wenigen zeilen geschichte sein koennte?!
Sehe ich das richtig, dass bei Deiner Lösung immer der komplette Baum geladen wird? Das könnte genau der Grund sein, warum eine SQL-Lösung zu bevorzugen wäre (vor allem, wenn wir uns das Beispiel des Explorers vor Augen führen).
__________________
Grüße vom Griechen,
Cybergreek!

WikiDict.de - Das Wiki-Wörterbuch
Cybergreek ist offline   Mit Zitat antworten
Alt 25.04.2008, 18:56   #78
TP-Specialist
 
Benutzerbild von theo
 
Registriert seit: Apr 2002
Ort: 743, evergreen terrace
theo bringt sich richtig ein
Zitat:
Zitat von Cybergreek Beitrag anzeigen
Sehe ich das richtig, dass bei Deiner Lösung immer der komplette Baum geladen wird? Das könnte genau der Grund sein, warum eine SQL-Lösung zu bevorzugen wäre (vor allem, wenn wir uns das Beispiel des Explorers vor Augen führen).
also da fragst du mich ehrlich gesagt zu viel. soweit bin ich gedanklich noch lange nicht.
vor einiger zeit habe ich mal mit einer oop-loesung des gesamten "nested-set-objekts" gedacht. und auch trotz sergejs kritik an dem gedanken kann ich ihn nicht so recht loslassen ... den gedanken, nicht sergej
aber um hier eine wirklich durchdachte antwort geben zu koennen braeuchte ich eines von zwei dingen: genuegend zeit, um mich mit der sache mal in ruhe auseinander setzen zu koennen oder einen lukrativen auftrag, in dessen umsetzung dieses problem teil des projekts waere. vielleicht kann man mal jemanden fragen, bei dem so ein modul schon teil einer loesung ist (iframe z.b.).

kleiner nachtrag:
iframe hat seine erste loesung (phpope) noch mit php4 umgesetzt. also nix oop. ueber den nachfolger snode konnte ich auf die schnelle nichts in erfahrung bringen.
__________________
/b{2}|[^(bb)]/

[Workshop] Nested sets
webdevelopment + visualisierung

Geändert von theo (25.04.2008 um 19:02 Uhr).
theo ist offline   Mit Zitat antworten
Alt 25.04.2008, 19:29   #79
TP-Senior
 
Benutzerbild von Schneemann
 
Registriert seit: Jan 2006
Schneemann macht alles soweit korrekt
@theo:
Deine Lösung mit CSS ist ja keine Lösung für das darstellen eines aufgeklappten Baumes an x Knoten. Im Code sind dann immer alle Knoten und Links enthalten, die ein User gar nicht sehen soll.

Der komplexe Baum hat in der Regel ja mehrmals eine Ebene 2 oder Ebene 4 etc.

Es muss schon serverseitig das zugeklappte klar sein. Und da tue ich mich schwer ein solches Array zu erstellen bzw. weiß nicht wie performant und clever das ist?
__________________
Gruß,
Peter
Schneemann ist offline   Mit Zitat antworten
Alt 27.04.2008, 19:37   #80
TP-Specialist
 
Benutzerbild von theo
 
Registriert seit: Apr 2002
Ort: 743, evergreen terrace
theo bringt sich richtig ein
Zitat:
Zitat von Schneemann Beitrag anzeigen
@theo:
Deine Lösung mit CSS ist ja keine Lösung für das darstellen eines aufgeklappten Baumes an x Knoten. Im Code sind dann immer alle Knoten und Links enthalten, die ein User gar nicht sehen soll.
den letzten satz hab ich jetzt nicht verstanden. geht es dir darum, dass im code nicht alle knoten vorhanden sein sollen, obwohl man sie nicht sieht? weil letztlich kann man mit der css-variante jeden x-beliebigen baum darstellen.

@cybergreek: der einwand ist natuerlich berechtigt. wenn man den code sauber kapselt, dann koennte man unnoetige db-abfragen umgehen. wobei ich nicht so richtig glaube, dass es das war, worum es sich hier die ganze zeit drehte.
__________________
/b{2}|[^(bb)]/

[Workshop] Nested sets
webdevelopment + visualisierung
theo ist offline   Mit Zitat antworten
Alt 27.04.2008, 19:45   #81
TP-Senior
 
Benutzerbild von Schneemann
 
Registriert seit: Jan 2006
Schneemann macht alles soweit korrekt
Naja du würdest mit CSS nicht geöffnete Knoten ausblenden. Da ein User aber ggf. im Quelltext gar nicht sehen soll, dass es überhaupt noch andere Knoten gibt, soll auch der Code wirklich nur darstellen was auch vorhanden ist.

Und wenn wir ein Beispiel mit einem sehr langen Baum nehmen würden, dann hätten wir sehr viel Code der gar nicht ausgegeben werden müsste, weil die Knoten zugeklappt sind.

Der Baum soll im Quellcode einfach das stehen haben was auch zu sehen ist und nicht alles was in der Datenbank steht.
__________________
Gruß,
Peter
Schneemann ist offline   Mit Zitat antworten
Alt 29.04.2008, 10:14   #82
TP-Specialist
 
Benutzerbild von theo
 
Registriert seit: Apr 2002
Ort: 743, evergreen terrace
theo bringt sich richtig ein
also so richtig verstehe ich dein problem nicht. was ist so geheimnisvoll an deiner navi, dass user sie nicht mal im code sehen duerfen? wenn sie die punkte anklicken und sie sich ausklappen, dann werden sie doch trotzdem angezeigt.
was den code angeht, so brauchst du dir keine gedanken um die menge zu machen. wegen den paar zeichen wird die seite sicher nicht langsamer.

ich versuche einfach nur zu verstehen, ob es fuer den aufwand, den du anstrebst, einen nachvollziehbaren grund gibt. normal ist es doch so, dass man eine seite entweder aus "spass" macht oder aber fuer einen kunden. bei zweiterem ist es wichtig, dass aufwand und nutzen in einem gesunden verhaeltnis stehen, denn zeit muss zum schluss bezahlt werden. und daher frage ich mich, ob dein vorhaben einen vertretbaren hintergrund hat. machbar ist letztlich alles ...
__________________
/b{2}|[^(bb)]/

[Workshop] Nested sets
webdevelopment + visualisierung
theo ist offline   Mit Zitat antworten
Alt 29.04.2008, 10:45   #83
TP-Senior
 
Benutzerbild von Schneemann
 
Registriert seit: Jan 2006
Schneemann macht alles soweit korrekt
Die Sache ist einfach die. Ich baue für meinen Sportverein eine Internetseite. Es gibt einen Baum mit Kategorien, dabei sollen verschiedene Knoten nur von bestimmten Leuten gesehen werden können. Wer keine Berechtigung hat, soll und darf auch andere Knoten nicht sehen.
Die Knoten die nicht gesehen werden dürfen, will ich vorher in eine ID-Kette lesen und danach per unset() aus dem hierarchischen Array entfernen. Da man auch Kinderknoten ausblenden muss, erscheint mir ein hierarchischer Baum als die einfachste Lösung, weil man dann mit einem unset() die Kinder gleich mit entfernt.

Klickt man dann auf ein Plus um einen Knoten zu öffnen wird die ID des Knotens übergeben, die Kinder werden geladen und das ganze per AJAX an der Stelle eingefügt, wo der Baum aufgeklappt wird.
__________________
Gruß,
Peter
Schneemann ist offline   Mit Zitat antworten
Alt 29.04.2008, 11:11   #84
TP-Specialist
 
Benutzerbild von theo
 
Registriert seit: Apr 2002
Ort: 743, evergreen terrace
theo bringt sich richtig ein
aaalso ... wenn du eine geschichte mit rechten loesen willst, und sowas hatte ich irgendwie schon vermutet, dann fang doch die sachen gleich bei dem statement ab. die user muessen sich identifizieren. dann kannst du auch gleich sagen, welche knoten ueberhaupt von der db-abfrage zurueckgegeben werden sollen. damit sparst du dir noch mehr arbeit und noch mehr code.

und warum auf einmal ajax? am anfang waren wir doch mal auf eine js-freie loesung aus?! und jetzt kommt es wieder rein ... ?

an deiner stelle wuerde ich mir als erstes ueber ein system der rechte gedanken machen, das in deiner db abgebildet wird. welcher user darf welche knoten sehen usw.
dann wuerde ich den einzelnen knoten versuchen, einen wert mitzugeben, der deren zugriffe regelt. wobei hier immer der hierarchische aufbau zu beachten ist. darf ein user den letzten knoten im zweig sehen, aber nicht die uebergeordneten, so wird er da nie rankommen.
und dann wuerde ich mir die statements so zurecht schreiben, dass nach einem erfolgreichen login der gesamte baum, den der user sehen darf, einmal ausgelesen wird und dann meinetwegen in einer session landet. und ab da kannst du mit ihm machen was du willst. vielleicht liesse sich auch ne nette xml-geschichte draus machen. lass deiner phantasie freien lauf ...
__________________
/b{2}|[^(bb)]/

[Workshop] Nested sets
webdevelopment + visualisierung
theo ist offline   Mit Zitat antworten
Alt 29.04.2008, 14:13   #85
TP-Senior
 
Benutzerbild von Schneemann
 
Registriert seit: Jan 2006
Schneemann macht alles soweit korrekt
Auch wenn ich im SQL-Statement die Knoten ausschliessen könnte, die ein User nicht sehen darf, wäre das Problem, den Baum zu erstellen aus dem ich die Liste baue, das selbe.

Zitat:
Zitat von theo Beitrag anzeigen
und warum auf einmal ajax? am anfang waren wir doch mal auf eine js-freie loesung aus?! und jetzt kommt es wieder rein ... ?
Das ist nur ein Optimierungsschritt 2, für das Problem selbst aber nicht relevant.
__________________
Gruß,
Peter
Schneemann ist offline   Mit Zitat antworten
Alt 29.04.2008, 14:20   #86
TP-Specialist
 
Benutzerbild von theo
 
Registriert seit: Apr 2002
Ort: 743, evergreen terrace
theo bringt sich richtig ein
Zitat:
Zitat von Schneemann Beitrag anzeigen
Auch wenn ich im SQL-Statement die Knoten ausschliessen könnte, die ein User nicht sehen darf, wäre das Problem, den Baum zu erstellen aus dem ich die Liste baue, das selbe.
mehr oder weniger. wenn du alle daten entgegen nimmst, also auch die, die du zum schluss nicht brauchen wirst, dann machst du dir das handling unnoetig schwer. zumal du bei einem array ja auch mit unset() nicht weiterkommst. du muesstest dir dann eine loesung mit array_splice() oder array_slice() einfallen lassen.
__________________
/b{2}|[^(bb)]/

[Workshop] Nested sets
webdevelopment + visualisierung
theo ist offline   Mit Zitat antworten
Alt 29.04.2008, 15:45   #87
TP-Senior
 
Benutzerbild von Schneemann
 
Registriert seit: Jan 2006
Schneemann macht alles soweit korrekt
Wieso geht unset() nicht? Bei mir klappt das.

PHP-Code:
<?php

$data 
= array(
    array(
        
'id'    => 7,
        
'name'  => 'Lebewesen',
        
'level' => 0,
    ),
    array(
        
'id'    => 10,
        
'name'  => 'Saeugetiere',
        
'level' => 1,
    )
);

unset( 
$data['0']['id'] );

echo
"<pre>";print_r($data);echo"</pre>";

?>
__________________
Gruß,
Peter
Schneemann ist offline   Mit Zitat antworten
Alt 29.04.2008, 15:51   #88
TP-Specialist
 
Benutzerbild von theo
 
Registriert seit: Apr 2002
Ort: 743, evergreen terrace
theo bringt sich richtig ein
ich weiss nicht, ob wir den sauberen umgang mit arrays hier im rahmen dieses workshops besprechen muessen. denk einfach mal darueber nach, wie du nachher mit dem array weiter umgehen willst, um einen sauberen baum aufzubauen ...
__________________
/b{2}|[^(bb)]/

[Workshop] Nested sets
webdevelopment + visualisierung
theo ist offline   Mit Zitat antworten
Alt 26.05.2008, 11:52   #89
TP-Newbie
 
Registriert seit: May 2008
horizons macht alles soweit korrekt
Hallo Forum,
ich benutze auch eine nested Set Struktur in einer Tabelle und habe nun ein Problem mit einem Query.
Meine nested set Struktur besitzt eine id, rgt, lft wert (aber keine level/depth spalte) in der datenbank, dazu natürlich noch einige weitere Text Spalten.

Jetzt bräuchte ich ein Select Query, dass mir die Spalten ausgibt und die dazugehörigen Eltern einträge in der Ebene 1 und 2. Die Einträge die ich Selektieren will befinden sich z.b. in Ebene 3 können aber auch darüber sein oder tiefer liegen, aber als beispiel belasse ich es bei max 3 Ebenen.

Meine tabellen sehen z.b. so aus:

Tabelle "tree"
NodeId | NodeRootId | NodeName | NodeLeft | NodeRight

Code:
+-----------------+--------------+------+-----+-------------------+----------------+
| Field           | Type         | Null | Key | Default           | Extra          |
+-----------------+--------------+------+-----+-------------------+----------------+
| NodeId          | int(11)      |      | PRI | NULL              | auto_increment |
| NodeName        | varchar(100) | YES  | MUL | NULL              |                |
| NodeRootId      | int(11)      |      | MUL | 0                 |                |
| NodeRight       | int(11)      |      | MUL | 0                 |                |
| NodeLeft        | int(11)      |      | MUL | 0                 |                |
+-----------------+--------------+------+-----+-------------------+----------------+
Tabelle "info"
info_id | NodeId | text wobei info_id = primary key ist.

Hier http://www.traum-projekt.com/forum/7...tml#post563098
wurde schonmal auf die Vater ID in einem Select eingegangen. Nur leider dauert mir dieser Select bei der Masse meines Trees zu lange (15sek Laufzeit bei 120 einträgen im Baum ohne index auf rootid, right und left mit index wesentlich schneller 2 sek und weniger).
Der Select bestimmt aber nur die direkte Vater ID des selektierten Eintrages.

Was ich bräuchte als Ergebnis ist
info.info_id | info.NodeId | info.text | vater_id_level1 | vater_id_level2

Ich habe mir jetzt Gedanken gemacht wie ich den Select am besten machen könnte (es muß leider in einem Query erledigt werden)
Und kam auf folgendes Query um die Eltern Id auf level 2 des Eintrages zu bekommen:

Code:
SELECT this.*	,A.father as father_level2
	FROM info AS this
	LEFT OUTER JOIN (
		SELECT v.NodeId AS father, s.NodeId AS child, parent_LEVEL
		FROM tree v, tree s
		LEFT OUTER JOIN (
			SELECT o.NodeId,
				    count(*)+(o.NodeLeft>1) AS parent_LEVEL
				    FROM tree p, tree o
				   WHERE o.NodeLeft BETWEEN p.NodeLeft AND p.NodeRight
				     AND (p.NodeId != o.NodeId OR o.NodeLeft = 1)
					   AND (p.NodeRootId = 2 AND o.NodeRootId = 2) GROUP BY o.NodeId
				    ORDER BY o.NodeLeft
		    
		) AS B ON ( v.NodeId = B.NodeId )
			WHERE s.NodeLeft
			BETWEEN v.NodeLeft
			AND v.NodeRight
			AND (
				v.NodeRootId =2
				AND s.NodeRootId =2
			)
			AND parent_LEVEL = 2
			ORDER BY v.NodeLeft
	) AS A ON ( this.NodeId = A.child)
WHERE 1
ORDER BY this.text DESC
LIMIT 0 , 100
Nur bestimmt es mir derzeit nur den Vater auf Level 2 (NodeRootId war in dem Fall auch 2) und ich müsste für jede Spalte die ich hinzufuegen will nochmal den Kompletten Join mit geänderter Zeile AND parent_LEVEL = 2
hinzufuegen. Also wenn ich level 1 haben will AND parent_LEVEL = 1.
Hat jemand vllt eine Idee wie ich das ganze in einem Aufwasch machen kann (also mehrere levels auf einmal)?

Erklärung des obigen Selects:
Selectiert nodeid einträge des baumes mit den level wo sich der eintrag im baum befindet.
Code:
	SELECT o.NodeId,
  count(*)+(o.NodeLeft>1) AS parent_LEVEL
  FROM tree p, tree o
 WHERE o.NodeLeft BETWEEN p.NodeLeft AND p.NodeRight
   AND (p.NodeId != o.NodeId OR o.NodeLeft = 1)
   AND (p.NodeRootId = 2 AND o.NodeRootId = 2) GROUP BY o.NodeId
  ORDER BY o.NodeLeft
der select darüber
Code:
SELECT v.NodeId AS father, s.NodeId AS child, parent_LEVEL
FROM tree v, tree s
LEFT OUTER JOIN (

SELECT o.NodeId, count( * ) + ( o.NodeLeft >1 ) AS parent_LEVEL
FROM tree p, tree o
WHERE o.NodeLeft
BETWEEN p.NodeLeft
AND p.NodeRight
AND (
p.NodeId != o.NodeId
OR o.NodeLeft =1
)
AND (
p.NodeRootId =2
AND o.NodeRootId =2
)
GROUP BY o.NodeId
ORDER BY o.NodeLeft
) AS B ON ( v.NodeId = B.NodeId )
WHERE s.NodeLeft
BETWEEN v.NodeLeft
AND v.NodeRight
AND (
v.NodeRootId =2
AND s.NodeRootId =2
)
AND parent_LEVEL =2
ORDER BY v.NodeLeft
LIMIT 0 , 30
Selektiert daraus dann die einträge des levels die ich brauche (z.b. where parent_LEVEL = 2 ) und gibt eine "father | child | parent_LEVEL" Tabelle zurück.
Würde ich "AND parent_LEVEL =2" weglassen würde ich die father child kombinationen jeglicher levels bekommen die ich eigentlich ja nur irgendwie selektieren müsste.
Nur weiß ich nicht wie ich am einfachsten das ergebis bekomme ohne jedesmal den ganzen subselect zu machen.

Vielen Dank schonmal im Vorraus für die Hilfe.

mfg Horizons

Geändert von horizons (26.05.2008 um 16:08 Uhr).
horizons ist offline   Mit Zitat antworten
Alt 18.07.2008, 16:56   #90
TP-Newbie
 
Benutzerbild von pfump
 
Registriert seit: Jul 2008
pfump macht alles soweit korrekt
Exclamation

Ganz wichtige Frage!


Hallo Leute,

erst mal super Workshop.
Das mit dem Tree funzt echt super.
Jetz hab ich aber ein kleines Porblem.
Ich wollte das man den Baum aufklappen bzw. wieder
zuklappen kann. Also das nicht gleich der ganze Tree zu sehen ist.

Auch wollte ich das man die ganzen Punkte (Edit,Löschen, Neu) hinter
jedem Eintrag im Baum hat.

Das klappt ja auch. Aber leider krieg ich das mit dem Auf- und
Zuklappen einfach nicht hin.


Hat von euch vielleicht einer ne Idee?

Wär echt super gut und wichtig, wenn mir jemand helfen könnte.


Mfg
pfump ist offline   Mit Zitat antworten
Antwort

  Aktuelles Thema
  TP Hilfe Forum > Web-Editoren & Coding > Traum-Dynamik > Workshops und Tutorials
[Workshop] Nested Sets [Fortgeschrittene] [Workshop] Nested Sets
« Videostream mit SWF-Object | [Tutorial] Einführung in die MySQLi-Erweiterung von PHP 5 »

Stichworte
datenbank, mysql

LinkBacks (?)
LinkBack to this Thread: http://www.traum-projekt.com/forum/73-workshops-und-tutorials/58359-workshop-nested-sets.html
Erstellt von For Type Datum
Nested Set - Forum: phpforum.de This thread Refback 29.06.2009 08:54
Theorie zu Nested Sets :: Blackflash This thread Refback 03.04.2009 17:43
Blackflash - Blogeintrag This thread Refback 08.11.2008 23:45
hilfe nested sets - php.de This thread Refback 12.08.2008 17:41
Adobe UserGroup Dreamworker.de - FOR Schleife ordnen?! This thread Refback 26.05.2008 13:34
Ertse Versuche mit Baumstruktur,erstes Problem! - Inspire-World Forum This thread Refback 20.05.2008 09:18
Nested Sets ? Wikipedia This thread Refback 23.03.2008 18:57
PHP script resource DYNAMISCHES MENÜ ->rekursive funktion -> hilfe This thread Refback 15.10.2007 11:34
Pop Out and Drop Down Menu mit MYSQL - Forum: phpforum.de This thread Refback 19.08.2007 21:47
e-techniker.info - Blog Archive - Baumstrukturen This thread Pingback 16.02.2007 18:38

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
[Anfänger] [Workshop] Formmailer mike Workshops und Tutorials 93 29.01.2009 11:34
[Fortgeschrittene] [Workshop] Objektorientierte Programmierung in PHP Lars Workshops und Tutorials 114 29.05.2007 16:55
Nested Sets und SQL-Querys martinR Traum-Dynamik 0 17.11.2004 10:15
Nested Templates bei DW MX Haretürk Dreamweaver 3 19.01.2003 21:29


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:11 Uhr.

Powered by: vBulletin Version 3.7 (Deutsch)
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd. / Search Engine Friendly URLs by vBSEO 3.2.0 ©2008, Crawlability, Inc.
Traum-Projekt.com | Suchen | Archiv | Impressum | Kontakt | | | Nach oben |



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67