Κάμερες σε προσαρμοσμένες ROM: Πώς οι προγραμματιστές κάνουν το υλικό να λειτουργεί χωρίς πηγαίο κώδικα

click fraud protection

Χωρίς πηγαίο κώδικα, πώς οι προγραμματιστές αποκτούν στοιχεία υλικού, όπως κάμερες που λειτουργούν σε προσαρμοσμένες ROM; Η απάντηση είναι ένα BLOB, shim, και πολλά debugging.

Με την κυκλοφορία του Android Oreo και πολλών συσκευών όπως η Xiaomi Redmi Note 3, Google Nexus 5 και άλλοι το λαμβάνουν ανεπίσημα, είναι πιθανώς δίκαιο να αναρωτιόμαστε γιατί τα ίδια χαρακτηριστικά (κυρίως η κάμερα) τείνουν να σπάνε όταν οι προγραμματιστές μεταφέρουν μια ROM που βασίζεται στο Android Open Source Project (AOSP). Πιθανότατα έχετε δει νήματα ROM στο φόρουμ XDA με μια μακρά λίστα με σπασμένα χαρακτηριστικά στην κορυφή. Το "What works" ακολουθούμενο από μια λίστα λειτουργικών λειτουργιών και, στη συνέχεια, κάτω από αυτό το εμβληματικό "What does not works? Εσύ πες μου!" είναι δύο δημοφιλή ρεφρέν στα φόρουμ μας που έχουν γίνει πρακτικά μιμίδιο σε μέρη όπως το Reddit και το Twitter.

Γιατί διακόπτεται τόση πολλή λειτουργικότητα κάθε φορά που ένας προγραμματιστής προσπαθεί να μεταφέρει μια AOSP ROM στη συσκευή του; Η βασική απάντηση είναι ότι επειδή οι λειτουργίες αλλάζουν σε διαφορετικές εκδόσεις του Android, τα παλιά προγράμματα οδήγησης συσκευών που είναι συσκευασμένα ως BLOB δεν θα λειτουργούν με νεότερες εκδόσεις του Android ή ακόμα και μόνο με stock AOSP. Για να το ξεπεράσουν αυτό, οι προγραμματιστές χρησιμοποιούν αυτό που ονομάζεται "shim", αλλά η διαδικασία που εμπλέκεται είναι δύσκολη, χρονοβόρα και μερικές φορές πολύ δύσκολη στον εντοπισμό σφαλμάτων.

Σε αυτό το άρθρο, θα περιγράψουμε πώς λειτουργούν τα shims, ειδικά όσον αφορά τη σωστή λειτουργία της κάμερας σε ROM που βασίζονται σε AOSP. Θα χρησιμοποιήσουμε το OnePlus 3T ως παράδειγμα. Σημειώστε ότι η δυσκολία που συνεπάγεται η λειτουργία αυτών των λειτουργιών είναι ιδιαίτερα συγκεκριμένη για τη συσκευή.

OnePlus 3T Running OxygenOS. Αν και τα τηλέφωνα OnePlus είναι γνωστά για την προσαρμοσμένη φιλικότητα προς την ανάπτυξη, υπάρχει πολλή δουλειά που κάνουν οι προγραμματιστές στα παρασκήνια για να δημιουργήσουν σταθερές θύρες του AOSP.


Τι είναι ένα shim ή ένα BLOB;

Για να αρχίσουμε να καταλαβαίνουμε μέρος του τι κάνουν οι προγραμματιστές, πρέπει πρώτα να εξηγήσουμε μερικά πράγματα. Αν και το λειτουργικό σύστημα Android είναι ανοιχτού κώδικα (για κάποιο λόγο ονομάζεται Android Open Source Project), το λογισμικό (χωρίς τον πυρήνα) που αποστέλλεται σε χιλιάδες συσκευές Android δεν είναι. Οι προγραμματιστές δεν έχουν πρόσβαση στον πηγαίο κώδικα του Samsung εμπειρία, EMUI, OxygenOS, ή οποιαδήποτε από τις άλλες γεύσεις τρίτων κατασκευαστών του Android.

Τώρα, οι προγραμματιστές που μεταφέρουν το απόθεμα AOSP σε μια συσκευή που δεν ανήκει στην Google πιθανότατα δεν ενδιαφέρονται για τον πηγαίο κώδικα αυτών των skins Android, καθώς δεν πρόκειται να είναι τροποποίηση και κατασκευή αυτών των ROM. Αυτό θα ήταν αλήθεια, αν όχι για έναν μεγάλο, μεγάλο λόγο: τα εξαρτήματα που είναι απαραίτητα για να λειτουργήσει σωστά η κάμερα, κυρίως ο κάμερα HAL (Hardware Abstraction Layer), είναι επίσης κλειστή πηγή.

Το πρόβλημα με την ύπαρξη όχι μόνο της κάμερας HAL αλλά και της ROM κλειστού κώδικα είναι ότι οι προγραμματιστές που εργάζονται για τη μεταφορά του AOSP στη συσκευή τους θα είναι δουλεύοντας τυφλά. Η κλειστή πηγή OEM ROM είναι σε θέση να συνδεθεί με την κάμερα HAL μια χαρά, επειδή η OEM έχει πρόσβαση στην πηγή HAL της κάμερας. Το HAL της κάμερας είναι αυτό που επιτρέπει στη ROM να «μιλήσει» με το υλικό της κάμερας — χωρίς αυτό, η κάμερα θα ήταν μη λειτουργική. Σκεφτείτε την κάμερα HAL ως το τιμόνι και τα πεντάλ του αυτοκινήτου. Το τιμόνι/τα πεντάλ επιτρέπουν τον έλεγχο των εσωτερικών εξαρτημάτων του οχήματος παρέχοντας μια εξωτερική διεπαφή για τον οδηγό (το ROM) για να κάνει χρήση των εσωτερικών εξαρτημάτων.

Γραφικό που δείχνει την αρχιτεκτονική της κάμερας. Πηγή: Google

Καθώς το υλικό της κάμερας γίνεται όλο και πιο περίπλοκο (το εμφάνιση διπλών καμερών, για παράδειγμα), η πρόσβαση στην πηγή HAL της κάμερας θα έκανε τη μεταφορά μιας ROM AOSP με μια λειτουργική κάμερα πολύ πιο εύκολη.

Ωστόσο, οι OEM δεν παρέχουν πρόσβαση στην πηγή HAL της κάμερας για διάφορους λόγους. Πρώτον, εάν δεν έχουν όλα τα δικαιώματα ιδιοκτησίας της κάμερας HAL (όπως όταν ενσωματώνουν πνευματική ιδιοκτησία από άλλες εταιρείες), τότε δεν μπορούν να διανείμουν την πηγή. Δεύτερον, η απελευθέρωση της πηγής HAL της κάμερας μπορεί να θέσει σε κίνδυνο τη δική τους πνευματική ιδιοκτησία. Τέλος, οι εταιρείες δεν έχουν καμία νομική υποχρέωση να παρέχουν αυτόν τον πηγαίο κώδικα (σε αντίθεση με τον πηγαίο κώδικα του πυρήνα που είναι υποχρεούται να αποδεσμεύσει σύμφωνα με την GPL), επομένως δεν έχουν κίνητρο να το κυκλοφορήσουν. Έτσι, χωρίς πρόσβαση στην πηγή HAL της κάμερας, πώς ακριβώς οι προγραμματιστές κάνουν την κάμερα να λειτουργεί σε AOSP ROM; Η απάντηση είναι ένα BLOB, shim, και πολλά, πολλά debugging.

Μια συσκευή ΑΜΟΡΦΗ ΜΑΖΑ Το (Binary Large OBject) περιέχει προσυσκευασμένα δυαδικά αρχεία που είναι η μεταγλωττισμένη μορφή λογισμικού. Σε αυτήν την περίπτωση, η πηγή HAL της κάμερας μεταγλωττίζεται από τον OEM και αποστέλλεται σε συσκευές ως δυαδικά. Όταν οι προγραμματιστές μιλούν για BLOB, αναφέρονται σε εκείνα τα δυαδικά που αποστέλλονται σε ζωντανές συσκευές που μπορούν να εξαγάγουν. Τώρα, το θέμα των «ΣΚΗΜΑΤΩΝ κάμερας» έχει μαστίζει εδώ και καιρό το OnePlus για πολλούς μήνες, αλλά η αλήθεια του θέματος είναι ότι οι προγραμματιστές είχαν πάντα πρόσβαση στα BLOB της κάμερας. ο Ο πηγαίος κώδικας της κάμερας HAL είναι το χρυσό εισιτήριο για προγραμματιστές εδώ, όμως, αλλά αυτό θα γίνει ποτέ μα ποτέ να απελευθερωθεί λόγω του νομικού κινδύνου θα έβαζε εταιρείες όπως η OnePlus.

Έτσι, οι προγραμματιστές που θέλουν να φέρουν το AOSP σε μια συσκευή μένουν μόνο με BLOB της κάμερας HAL για τις οποίες δεν έχουν πρόσβαση στον πηγαίο κώδικα. Σπάνια, αν ποτέ, ένας προγραμματιστής μπορεί να συνδυάσει τον κώδικα AOSP ROM του με την κάμερα HAL BLOB και να περιμένει ότι θα λειτουργήσει, έτσι ώστε να γεφυρώσουν το χάσμα μεταξύ των δύο, οι προγραμματιστές δημιουργούν αυτό που ονομάζεται "σφήνα.”

Το "shim" σημαίνει "σφήνα (κάτι) ή γεμίζει ένα χώρο." Αυτό είναι ουσιαστικά αυτό που κάνει ένας προγραμματιστής όταν γράφοντας ένα shim—προσθέτουν κώδικα για να επιτρέψουν στο BLOB να διασυνδέεται με τον πηγαίο κώδικα AOSP που δουλεύουν με. Τα shims χρησιμοποιούνται για να κάνουν BLOB όλων των διαφορετικών ειδών να λειτουργούν με το AOSP, αλλά συνήθως, η κάμερα BLOB είναι αυτή που απαιτεί τη μεγαλύτερη λάμψη. Όπως αναφέραμε προηγουμένως, το shimming απαιτείται όχι μόνο για τη μεταφορά νεότερων εκδόσεων Android σε μια συσκευή (όπως π.χ. όλες αυτές οι ανεπίσημες ROM Android Oreo), αλλά χρειάζονται επίσης κατά τη μεταφορά του AOSP της ίδιας έκδοσης Android σε αυτό συσκευή.

Προτεινόμενη ανάγνωση: Από το κατάστημα στο ράφι: Μια σε βάθος περιγραφή του γιατί οι συσκευές MSM8974 εξαιρούνται από το Nougat

Το OnePlus 2, για παράδειγμα, το έλαβε τελευταία επίσημη ενημέρωση λειτουργικού συστήματος με τη μορφή Android 6.0 Marshmallow. Η συσκευή, ωστόσο, στην πραγματικότητα έχει πλήρως λειτουργικές προσαρμοσμένες ROM που βασίζονται σε AOSP βασίζεται στο Android Nougat, και αυτό χάρη στη σκληρή δουλειά των προγραμματιστών και των κομματιών τους. Θα αναλύσουμε μερικά παραδείγματα ανταλλακτικών, αλλά πρώτα, πρέπει να μιλήσουμε για το πώς ακριβώς λειτουργούν τα μοτέρ.


Πώς λειτουργεί το shimming;

Εφόσον οι προγραμματιστές δεν έχουν πρόσβαση στην πηγή HAL της κάμερας ή στην πηγή OEM ROM (και μόνο στα προμεταγλωττισμένα δυαδικά αρχεία), δεν μπορούν να γνωρίζουν ποιες λειτουργίες αναμένει η κάμερα HAL. Εξαιτίας αυτού, συχνά υπάρχει αναντιστοιχία μεταξύ του ονόματος της λειτουργίας που αναζητά η κάμερα HAL και του πραγματικού ονόματος της συνάρτησης στον κώδικα AOSP με τον οποίο εργάζεται ο προγραμματιστής.

Για να λύσει αυτό το ζήτημα, ο προγραμματιστής δημιουργεί απλώς μια νέα συνάρτηση που χρησιμοποιεί το ίδιο όνομα του λειτουργία που περιμένει η κάμερα HAL BLOB, αλλά αυτή η νέα λειτουργία απλώς εκτελεί αυτό που θέλει ο προγραμματιστής αυτό να. Αυτή η νέα λειτουργία που λειτουργεί ως μεσάζων μεταξύ του BLOB και του AOSP είναι το shim. Αυτό το συγκεκριμένο σενάριο όπου το BLOB αποτυγχάνει να βρει τη λειτουργία που αναζητά είναι ένα από τα πιο συνηθισμένα όπου χρειάζεται ένα παρέμβυσμα.

Πολύ απλό διάγραμμα βαφής MS που δείχνει πού χρειάζεται μια στεφάνη.

Ίσως τα πράγματα να έχουν λίγο πιο νόημα με ένα υποθετικό παράδειγμα που αφορά το OnePlus 3T. Θα δημιουργήσουμε ένα παράδειγμα χρησιμοποιώντας το OxygenOS και την κάμερα OnePlus. Εάν χρησιμοποιήσουμε BLOBs κάμερας που λαμβάνονται από το OxygenOS Nougat για το OnePlus 3T για τη δημιουργία μιας Nougat ROM με βάση το AOSP, ενδέχεται να αντιμετωπίσουμε προβλήματα. Αυτό συμβαίνει επειδή τα BLOBs της κάμερας (τα οποία είχαν αρχικά μεταγλωττιστεί από τον OEM) θα μπορούν να αναφέρουν όλες τις λειτουργίες που χρειάζεται στο OxygenOS, αλλά δεδομένου ότι η μεταγλωττισμένη AOSP ROM μπορεί να μην έχει αυτές τις συναρτήσεις ή να τις έχει μεταγλωττίσει με διαφορετικό όνομα (που οδηγεί σε αναντιστοιχία μεταξύ των συμβόλων συνάρτησης), θα υπάρχει λάθος. Αυτό μπορεί να διορθωθεί δημιουργώντας μια νέα συνάρτηση εντός της AOSP ROM με το όνομα που αναμένει το BLOB—το δικό μας shim.

Τα σύμβολα σε ένα πλαίσιο προγραμματισμού χρησιμοποιούνται για να αναφέρονται σε συγκεκριμένες συναρτήσεις στον κώδικα. Τα σύμβολα είναι απαραίτητα επειδή η θέση μιας συνάρτησης μπορεί να αλλάξει κατά την επεξεργασία του κώδικα και έτσι για να αποφευχθεί ο σκληρός κώδικας αναφορές σε συναρτήσεις, ο μεταγλωττιστής δημιουργεί έναν πίνακα συμβόλων που μπορούν να χρησιμοποιήσουν άλλες συναρτήσεις για να αναφέρονται πάντα στα δεξιά λειτουργία. Όταν αλλάζετε το όνομα μιας συνάρτησης πριν από τη μεταγλώττιση, αλλάζει και το σύμβολό της, επομένως ουσιαστικά αλλάζουν τυχόν αλλαγές που ο OEM κάνει στην κάμερα HAL πηγή πριν από τη μεταγλώττιση θα απαιτήσει από τους προγραμματιστές να δημιουργήσουν μια νέα σφήνα.

Προβολή πίνακα συμβόλων με χοάνη. Πηγή: Apriorit

Η εξήγηση που προσφέραμε μέχρι στιγμής κάνει να ακούγεται σαν να είναι εύκολη η δημιουργία φλιτζανιών. Η αλλαγή μερικών ονομάτων συναρτήσεων εδώ και εκεί δεν ακούγεται πολύ δύσκολη, σωστά; Μακάρι να ήταν τόσο εύκολο. Η πραγματικότητα των shims περιλαμβάνει περισσότερα από απλά μετονομασίες συναρτήσεων. Μιλήσαμε με τον Αναγνωρισμένο προγραμματιστή του XDA Sultanxda, ο οποίος μπόρεσε να μας δώσει ένα παράδειγμα ενός από τα πιο δύσκολα εξαρτήματα που έχει δουλέψει.


Shimming - Όχι τόσο εύκολο όσο ακούγεται

Για όσους δεν είναι εξοικειωμένοι με το OnePlus 3T, η μπροστινή κάμερα ήταν μάλλον σπασμένη αρχικά Προσαρμοσμένες ROM που βασίζονται σε AOSP. Αρχικά, η προσπάθεια λήψης οποιασδήποτε φωτογραφίας άνω των 8 MP θα είχε ως αποτέλεσμα συντριβή. Στην προσπάθειά του να λύσει αυτό το ζήτημα, ο Sultanxda έκανε αρκετά ροδέλες για να επιτρέψει στην μπροστινή κάμερα OnePlus 3T να λειτουργεί σωστά.

Shim #1 - Αλλαγή του ονόματος πακέτου κάμερας

Για να αποτρέψει τη συντριβή της μπροστινής κάμερας κάθε φορά που ο χρήστης τραβούσε μια φωτογραφία άνω των 8MP, η Sultanxda ανάγκασε την κάμερα HAL να αναγνωρίσει όλες τις κάμερες ως κάμερα OnePlus. Αυτό γίνεται επειδή η OnePlus αποφάσισε να αφιερώσει μια βοηθητική λειτουργία σε ορισμένες εφαρμογές (isOnePlusCamera, isFacebookCameraκ.λπ.) για κάποιο λόγο. Το Sultanxda το διόρθωσε μετατοπίζοντας την κάμερα HAL έτσι ώστε να δείχνει μια νέα λειτουργία που επιστρέφει πάντα "true" σαν ο χρήστης να χρησιμοποιεί την κάμερα OnePlus —ακόμα και όταν δεν τη χρησιμοποιεί.

Shim #2 - Απενεργοποιήστε το QuadraCfa

Για την επόμενη παρέλασή του, έπρεπε να απενεργοποιήσει το QuadraCfa, το οποίο είναι πιθανώς μια αποκλειστική τεχνολογία της Qualcomm που σχετίζεται με την κάμερα. Λέμε πιθανώς επειδή ούτε εγώ ούτε η Sultanxda είμαστε ακριβώς σίγουροι για το τι είναι το QuadraCfa, αλλά η Sultanxda γνωρίζει ότι έσπασε την μπροστινή κάμερα όποτε ήταν ενεργοποιημένη.

Παρατήρησε ότι το QuadraCfa με κάποιο τρόπο θα ενεργοποιούσε τον εαυτό του, αλλά δεν ήταν σίγουρος γιατί ή πώς το έκανε. Η επίλυση αυτού απαιτούσε μια μάλλον αντισυμβατική τροποποίηση από την πλευρά του. Σε ένα συμβατικό shim, η συνάρτηση shim, όταν συντάσσεται, παρέχει το σύμβολο που λείπει που αναζητά το BLOB. Σε αυτήν την περίπτωση, το BLOB είχε ήδη τα σύμβολα που χρειαζόταν—αυτά που υποτίθεται ότι αντιπροσώπευαν τις συναρτήσεις που ξεκινούσαν το QuadraCfa.

Bless Hex Editor. Το πρόγραμμα που χρησιμοποιούσε το Sultanxda.

Έτσι, έπρεπε να παρακάμψει τα σύμβολα που χρησιμοποιεί η κάμερα HAL και στην ουσία να τα κάνει να «λείπουν» έτσι του Το shims θα παρείχε αυτά τα σύμβολα "που λείπουν". Ο μόνος τρόπος για να γίνει αυτό είναι μέσω εξάγωνη επεξεργασία της ίδιας της κάμερας HAL. Η δεκαεξαδική επεξεργασία είναι βασικά η αναζήτηση μέσα από ένα σωρό μη οργανωμένες ασυναρτησίες με τη μορφή δυαδικών δεδομένων, προκειμένου να βρεθεί μια βελόνα στη θημωνιά - είτε μια συνάρτηση είτε μια συμβολοσειρά που θέλετε να επεξεργαστείτε.

Η δεκαεξαδική επεξεργασία μιας συνάρτησης είναι πολύ πιο δύσκολη από την επεξεργασία μιας συμβολοσειράς σε δεκαεξαδική μορφή, αλλά ευτυχώς, η Sultanxda κατάφερε να αποφύγει να χρειαστεί να επεξεργαστεί τις συναρτήσεις πίσω από το QuadraCfa εξαγωνική επεξεργασία των ονομάτων των συμβόλων για να ακυρωθούν αυτά τα σύμβολα.

Παράρτημα #3 - Διόρθωση σύγκρουσης με φωτεινό φως

Στη συνέχεια, ο Sultanxda εντόπισε ότι η λήψη μιας φωτογραφίας από την μπροστινή κάμερα υπό συνθήκες έντονου φωτισμού θα προκαλούσε συντριβή της κάμερας. Για να αναπαράγει αυτό το σφάλμα στη δική του συσκευή, ο Sultanxda στην πραγματικότητα άνοιξε τη λειτουργία φακού του OnePlus One του και άναψε το φως μπροστά από την μπροστινή κάμερα του OnePlus 3T για να καταρρεύσει και να παράγει χρησιμοποιήσιμους κορμούς! Μόλις ανακάλυψε ποια λειτουργία προκαλούσε τη συντριβή, δημιούργησε ένα παρέμβυσμα για να αναγκάσει τη συσκευή να χρησιμοποιεί τη λειτουργία χαμηλού φωτισμού όλη την ώρα για την μπροστινή κάμερα.

Shim #4 - Εικόνες με μπροστινή κάμερα χαμηλής ανάλυσης

Αφού διόρθωσε τη σύγκρουση του έντονου φωτός με την προηγούμενη στεφάνη, η Sultanxda ανακάλυψε ένα άλλο σφάλμα που στην πραγματικότητα προέκυψε ως άμεσο αποτέλεσμα αυτής της λάμψης: εικόνες χαμηλής ανάλυσης μπροστά από την κάμερα. Αντί να τραβήξετε φωτογραφίες στην ανάλυση που ζήτησε ο χρήστης (π.χ. 16MP), η προκύπτουσα εικόνα θα τραβήχτηκε στα 4MP.

Για να λυθεί αυτό απαιτούσε να μετατοπίσει τις συναρτήσεις handleSuperResolution και isSuperResolution για να επιστρέφετε πάντα true, αλλά ΜΟΝΟ όταν η μπροστινή κάμερα είναι ενεργή (γιατί διαφορετικά, η κάμερα θα κολλούσε κατά τη λήψη φωτογραφιών από τον πίσω αισθητήρα).


Μάθημα που αντλήθηκε - Η λάμψη μπορεί να είναι δύσκολη

Ο Sultanxda παραδέχεται ότι τα μοτίβα που έπρεπε να δημιουργήσει για να λειτουργήσει η μπροστινή κάμερα OnePlus 3T δεν αντιπροσωπεύουν το τυπικό σας παράδειγμα μολυβιού. Είναι μάλλον περήφανος για το στιλ του, δεδομένης της πολυπλοκότητάς του και της σπάνιας ανάγκης να επεξεργαστεί το ίδιο το BLOB. Αλλά αυτό το παράδειγμα απλώς δείχνει πόσο δύσκολο μπορεί να είναι να δουλέψει το υλικό της κάμερας σε ορισμένες συσκευές.

Μακάρι οι περιπέτειες με τη φωτογραφική μηχανή σας να είναι λιγότερο επώδυνες από τις δικές μου. -Σουλτάνξντα

Αρχεία καταγραφής, αρχεία καταγραφής και άλλα αρχεία καταγραφής. Χωρίς έναν συνεπή τρόπο αναπαραγωγής ενός σφάλματος και χωρίς αρχεία καταγραφής, οι προγραμματιστές έχουν ελάχιστη ελπίδα να βρουν την πηγή του προβλήματος. Ακόμα κι αν βρουν τι προκαλεί το πρόβλημα, δεν είναι πάντα μια απλή λύση. Η όλη διαδικασία εύρεσης και εξάλειψης αυτών των σφαλμάτων μπορεί να διαρκέσει μέρες ή εβδομάδες και είναι ο λόγος για τον οποίο η επιδιόρθωση της κάμερας σε ROM AOSP είναι μία από τις πιο δύσκολες εργασίες.

Εάν η συσκευή σας έχει μεταφερθεί μια ROM AOSP με πλήρως λειτουργικό υλικό, ελπίζουμε ότι μπορείτε να αρχίσετε να εκτιμήστε τον αγώνα που μπορεί να έχουν περάσει αυτοί οι προγραμματιστές για να σας τα φέρουν χαρακτηριστικά. Εκτιμήστε τους για τη δουλειά τους, γιατί δεν είναι εύκολο. Είναι πολλή δουλειά που η συντριπτική πλειοψηφία των χρηστών δεν θα προσέξει καν, καθώς ταλαντούχοι προγραμματιστές στα φόρουμ μας φροντίζουν για τα πολλά αόρατα μέρη του Android.

Θα θέλαμε να ευχαριστήσουμε ιδιαίτερα τον Sultanxda για τις πολλές συνεισφορές που πρότεινε στη δημιουργία αυτού του άρθρου.