Riga duplicata Xcode


128

V'è un Duplicatecomando nel menu Edit (con un collegamento di default di D), ma è (come Halley ha sottolineato) significava per la duplicazione nella parte Interface Builder di Xcode.

Quindi, come si duplica ( facilmente ) una riga in Xcode 4?


Domanda correlata (con una risposta funzionante) per Xcode 3 ... e che non funziona per Xcode 4.


Perché non solo copia e incolla?

Perché è noioso e comporta troppe acrobazie manuali:

o (1) : spostarsi all'inizio della riga e quindi premere ⇧^E, quindi copiare con ⌘C, spostarsi su una nuova riga, allineare il cursore e infine incollare con ⌘V;

o (2) : ^A(imposta il cursore all'inizio della riga), ^SPACE(imposta il segno), ^E(imposta il cursore alla fine della riga), ⇧^W( Select to Mark; personalizzato), copia, nuova riga, ecc.

Come ha detto Frank Schröder (nella domanda correlata ):

Il punto è NON usare le scorciatoie Cmd-C / Cmd-V.


1
Seleziona la riga e copia incolla?
Dani

1
@Dani, CP è semplicemente troppo lavoro (e la duplicazione della linea non è qualcosa per cui la necessità si presenta solo raramente). :) Ho aggiornato la domanda.
Blaz

1
Command-D serve per la duplicazione dei controlli in Interface Builder.
Hailei

@ Halley, buono a sapersi. Ed è l'equivalente di ⌥-mouse-drag (che copia anche gli elementi dell'interfaccia)?
Blaz

@courteous Penso di sì. La sezione Modifier Keys in disanji.net/iOS_Doc/#documentation/DeveloperTools/Conceptual/… dice che "premendo il tasto Opzione durante le operazioni di trascinamento copia gli oggetti selezionati invece di spostarli."
Hailei

Risposte:


173
  1. Vai a questa cartella che contiene il lato oscuro della forza:

    • Xcode 4.2 o precedente: /Developer/Library/PrivateFrameworks/IDEKit.framework/Resources
    • Xcode 4.3 o versioni successive: /Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Resources.
  2. Apri IDETextKeyBindingSet.plist.

  3. Aggiungi un nuovo dizionario e un nuovo elemento di comando come screenshot qui sotto (chiamali come vuoi): Modifica del plist

    Quello è: selectLine:, copy:, moveToEndOfLine:, insertNewline:, paste:, deleteBackward:

  4. Riavvia Xcode e vai su Preferenze - Associazioni di tasti, cerca il tuo comando.

  5. Imposta una combinazione di tasti per il comando: Associazioni dei tasti

  6. Finalmente scatenato il potere delle associazioni di tasti su Xcode ... Buon divertimento!


3
@MichalStefanow, la posizione che hai scritto è in realtà la stessa posizione a cui /Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Resourcespunta l'alias. Altrimenti, ho seguito con successo i passaggi di Halley nella versione 4.3.2 ... ti suggerisco di eseguire il backup del file originale e quindi aprirlo in Xcode stesso (e non in TextEdit). Inoltre, per quanto riguarda i permessi: cambiarli (solo per il file stesso; nessuna ricorsione necessaria) nel Finder ha funzionato bene.
Blaz

29
Grazie mille! Per utenti pigri - selectLine :, copy :, moveToEndOfLine :, insertNewline :, paste :, deleteBackward:
Vlad Tsepelev

15
Se il tuo xCode si blocca! Chiudi xCode, apri il file con qualsiasi editor di testo e aggiungi il tuo dizionario: <key>Custom</key> <dict> <key>Duplicate Current Line</key> <string>selectLine:, copy:, moveToEndOfLine:, insertNewline:, paste:, deleteBackward:</string> </dict>
Vlad Tsepelev,

2
Funziona per me in XCode 4.4.1! Ho avuto qualche problema a modificare le autorizzazioni (finder o chmod 777 e l'avvio con sudo dal terminale non funzionavano, per qualche motivo). Ho copiato il file da qualche altra parte, l'ho modificato e ho sovrascritto quello originale, che ha funzionato.
Ixx

2
Sono android dev e quando ho iniziato a provare ios dev mi sono reso conto di quanto Android studio (o idea di intellij) sia buono.
IlyaEremin

91

Aggiorna 2020

Funziona anche con le versioni Xcode: 11.3.1

Funziona nelle versioni Xcode: 7.1, 7.3, 7.3.1, 8.0, 8.1, 8.2, 8.3, 9.0, 9.1, 9.2, 10.0, 10.1, 10.2.1

istruzione

  1. Concedi le autorizzazioni per modificare i seguenti file. Il più delle volte il sistema operativo non ti consentirà di modificare i file.

per la versione 11.3.1

sudo chmod 666 /Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/A/Resources//IDETextKeyBindingSet.plist

sudo chmod 777 /Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/A/Resources/

versioni precedenti alla 11.3


sudo chmod 666 /Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Resources/IDETextKeyBindingSet.plist

sudo chmod 777 /Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Resources/
  1. Modifica il file, scrivendo il seguente comando: (aprilo in sublime o in un editor di testo se puoi)

per 11.3.1

open  

/Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/A/Resources/

per le versioni seguenti

open /Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/A/Resources/IDETextKeyBindingSet.plist
  1. Aggiungi i seguenti snippet xml:
<key>custom</key>
<dict>
    <key>Duplicate Current Line</key>
    <string>moveToBeginningOfLine:, deleteToEndOfLine:, yank:, insertNewline:, moveToBeginningOfLine:, yank:</string>
    <key>Duplicate Lines</key>
    <string>selectLine:, copy:, moveToEndOfLine:, insertNewline:, paste:, deleteBackward:</string>
    <key>Delete Line</key>
    <string>selectLine:, deleteBackward:</string>
</dict>

Screenshots

inserisci qui la descrizione dell'immagine

e Riavvia Xcode e vai a Preferences - Key Bindings, cerca il comando che abbiamo digitato (Duplica linee e Duplica linea corrente).

inserisci qui la descrizione dell'immagine

Questo è tutto.

Per le persone unix da notare: -

sudo chmod 755 /Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/A/Resources/ 

Esso funziona magicamente! Ho modificato IDETextKeyBindingSet.pliste aggiunto il dizionario sopra, quindi ho mappato le chiavi in ​​Preferenze di XCode.
Randika Vishman

3
Queste sono le risposte nerd di cui hanno bisogno gli utenti Mac!
Luca Davanzo

1
Per XCode 10.1, ho dovuto utilizzare la seguente stringa: moveToBeginningOfLine :, deleteToEndOfLine :, strattone :, insertNewline :, contrassegno di gruppo :, moveToBeginningOfLine :, selectToMark :, Yank: . Un grande grazie a @tmsimont
marcelosalloum

1
questa è la prima cosa che cerco su Google ogni volta che Xcode viene aggiornato.
newDeveloper

1
Questa soluzione funziona per me piuttosto che per la risposta accettata
khalid

18

Ok, ho pensato a questo:

Versione per XCode 11:

selectParagraph:, delete:, undo:, moveRight:, yankAndSelect:
  • non tocca gli appunti
  • funziona con più linee
  • seleziona le righe aggiunte, quindi può essere utilizzato più volte senza riselezionare
  • selezione fissa in XCode 11
  • funziona meglio con undo

Dato che applico questa modifica dopo ogni aggiornamento di XCode, ho creato uno script per questo. Forse può causare qualche danno, ma ho cercato di renderlo relativamente sicuro. Crea una copia del file, quindi sostituisce la riga con la sua copia e il comando aggiuntivo usando perl. Richiede l'installazione di XCode in/Applications/Xcode.app

cp /Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Resources/IDETextKeyBindingSet.plist ~/Desktop/IDETextKeyBindingSet.plist; sudo perl -pi -e 's/\<string\>selectWord:\<\/string>/'$'\<string\>selectWord:\<\/string\>\n\t\t\<key\>Duplicate Selection\<\/key\>\n\t\t\<string\>selectParagraph:, delete:, undo:, moveRight:, yankAndSelect:\<\/string>/g' /Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Resources/IDETextKeyBindingSet.plist

Versione precedente (non sono sicuro che la nuova sia compatibile con le versioni precedenti, quindi la terrò qui):

selectParagraph:, delete:, yank:, moveToBeginningOfLine:, setMark:, yank:, moveToBeginningOfLine:, moveLeft:, selectToMark:

e script per la versione precedente per evitare la modifica manuale dei file:

cp /Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Resources/IDETextKeyBindingSet.plist ~/Desktop/IDETextKeyBindingSet.plist; sudo perl -pi -e 's/\<string\>selectWord:\<\/string>/'$'\<string\>selectWord:\<\/string\>\n\t\t\<key\>Duplicate Selection\<\/key\>\n\t\t\<string\>selectParagraph:, delete:, yank:, moveToBeginningOfLine:, setMark:, yank:, moveToBeginningOfLine:, moveLeft:, selectToMark:\<\/string>/g' /Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Resources/IDETextKeyBindingSet.plist

edit: correzione minore edit2: cambiato in selezione paragrafo edit3: aggiunta versione per XCode 11


Grazie davvero per questo, cercando questa combinazione. Questo può duplicare una o più righe senza aggiungere newLines indesiderate e anche ctrl-z funziona bene.
mkeremkeskin

Grazie, questo è ciò che è più vicino al comportamento di IntelliJ IMHO
OxyFlax

17

Oggi ho scritto un plugin molto piccolo per Xcode 5 che elimina e duplica linee e selezioni.

Puoi scaricarlo dal mio repository GitHub: XcodeKit Plugin - https://github.com/ptfly/XcodeKit


L'ho appena scaricato e installato: puoi utilizzare le preferenze di sistema per impostare anche le scorciatoie da tastiera per i comandi. Molto bella!
Orion Edwards,

La migliore soluzione è perché questo non ti romperà gli appunti correnti. Per aggiungere combinazioni di tasti: Preferenze di sistema -> tastiera -> scorciatoie -> scorciatoie app -> "+". Lì scegli Xcode e il titolo del menu ad esempio 'Elimina selezione / linea'
Sjoerd Perfors

L'ho appena installato. FANTASTICO, per qualche motivo, il mio menu "Duplica" in modifica è disattivato. Anche se ho selezionato una riga nell'editor, il cursore e ho provato a selezionare l'intera riga.
John Ballinger

Questo è più che fantastico. Grazie!
0x6A75616E

non funziona per me. "Duplica" è disattivato e anche la scorciatoia da tastiera non funzionerà.
SquareBox

13

La risposta di @ Hailei è stata piuttosto buona, ma ha avuto lo sfortunato effetto collaterale di rovinare il contenuto degli appunti (lasciandolo popolato con il contenuto della riga duplicata), che è precisamente la parte dell'approccio manuale di copia / incolla che stavo cercando di evitare .

Quindi, ho cambiato la sequenza di comandi in questa:

moveToBeginningOfLine:,
deleteToEndOfLine:,
yank:,
insertNewline:,
moveToBeginningOfLine:,
yank:

I 2 yank:potrebbero non funzionare come previsto se hai NSTextKillRingSizeimpostato qualcosa a parte 1, ma sono abbastanza sicuro che 1sia l'impostazione predefinita e devi fare un lavoro non banale per cambiarlo (richiede l'aggiunta di una voce a ~/Library/Preferences/.GlobalPreferences.plist).


Suggerisco di usare il comando defaults write -g NSTextKillRingSize 1invece di giocare con GlobalPreferences.plist. ;)
dbernard

@amas È probabile che tu debba copiare il file da qualche altra parte prima di modificarlo, quindi sovrascrivere il file originale, a meno che tu non voglia rischiare di modificare i permessi sulle cartelle principali.
nipponese

questo quasi funziona, ma per qualche motivo viene aggiunto un mucchio di spazi bianchi alla fine della riga duplicata .. qualche idea del perché?
tmsimont

5
se risolto con questa modifica:moveToBeginningOfLine:, deleteToEndOfLine:, yank:, insertNewline:, setMark:, moveToBeginningOfLine:, selectToMark:, yank:
tmsimont

Questa dovrebbe essere la risposta suggerita (seguendo la guida di @ Hailei). Grazie!
brkeyal

9

Perché duplicare una singola riga? È meglio duplicare l'intero paragrafo. La mia sequenza:

Duplica paragrafo corrente

selectParagraph:,
delete:,
yank:,
moveToBeginningOfParagraph:,
yank:,
moveUp:,
moveToEndOfParagraph:

Elimina paragrafo corrente

selectParagraph:,
delete:,
moveUp:,
moveToEndOfParagraph:

Funziona bene in Xcode 4.6


D'accordo, manipolare i paragrafi è superiore alle righe. Tutti, rendi il tuo editor abbastanza stretto da avvolgere il testo e prova a usare i comandi di linea.
Logan Moseley

Quanto è piccola la finestra che avvolge il codice. Considera l'idea di suddividere il codice in righe più piccole se ciò accade così spesso.
simpatico

9

Mi chiedo perché nessuno abbia menzionato l'uso insieme ai tasti freccia ( ) sia per spostare il cursore che per selezionare intere righe (aggiungendo ).

Copio regolarmente intere righe (duplicate) spostando il cursore all'inizio di una riga usando + (invece di ctrl+ A) e quindi uso + + (invece di ctrl+ + E) per selezionare l'intera riga fino alla fine e quindi copia / incolla.

Mi sono imbattuto in altri thread in cui nessuno sembra utilizzare queste scorciatoie da tastiera. Sono globali in OS X e li uso sempre! Molto meno acrobazie manuali;)


Ciò richiede molte più "acrobazie manuali" rispetto alla duplicazione con una sola combinazione di azione / tasto ... è il modo in cui duplico il testo in un editor di testo o browser web, sì, ma mi aspetto un po 'di più dall'IDE.
Ixx

1
Inoltre, con la scorciatoia di riga duplicata non sovrascrivi il contenuto degli appunti. Molte volte copio qualcosa, duplica codice e voglio incollarlo - con il tuo metodo devi copiarlo di nuovo.
Ixx

Beh si. Ma meno del modo suggerito dall'OP. Sono d'accordo che un singolo comando sarebbe il migliore. Ho solo pensato di indicare un'alternativa.
Baldur

1
questo è ancora meglio di niente fuori dagli schemi. spero che cmd + C / X senza selezione copi / tagli l'intera riga come fanno gli altri editori ...
manroe

@Baldur Questo è quello che faccio anch'io. cmd + cmd sinistro + maiusc + cmd destro + c cmd + destro invio cmd + cmd sinistro + p. Con 7 sequenze di tasti può essere facilmente eseguito in meno di 3 secondi, tuttavia, è ancora piuttosto noioso rispetto a ctrl + d come in molti editor di testo. È un peccato che questo non sia integrato in xcode o che in generale i Mac e il software Apple non abbiano tasti di scelta rapida migliori.
csga5000

9

EDIT: 12 luglio 2020 Dopo l'aggiornamento a Xcode 11.5, la mia duplicate linevoce chiave dal plistfile era sparita. Ho dovuto aggiungerlo di nuovo. La rilegatura dei tasti era ancora lì, però.

EDIT: 17 settembre 2019 Dopo l'aggiornamento a Xcode 10.3, la mia duplicate linevoce chiave dal plistfile era sparita. Ho dovuto aggiungerlo di nuovo. Tuttavia, la rilegatura dei tasti era ancora lì.

EDIT: 28 maggio 2019 Dopo l'aggiornamento a Xcode 10.2 di nuovo la mia duplicate linevoce chiave dal plistfile era sparita. Ho dovuto aggiungerlo di nuovo. Tuttavia, la rilegatura dei tasti era ancora lì.

EDIT: 23 dicembre 2018 Dopo l'aggiornamento a Xcode 10.1 tutte le mie scorciatoie si sono nuovamente interrotte. Ma qualcosa di diverso era che dopo aver aggiornato il file plist per la duplicazione di riga, non dovevo definire le mie associazioni di tasti, erano già lì. Strano.

EDIT: 14 OTTOBRE 2018 OTTOBRE Xcode 10: Qualcuno in alto in Apple ama davvero copiare / incollare e si assicura che con ogni versione dell'aggiornamento di Xcode, la duplicazione della linea venga rimossa dall'installazione di tutti. Noi sviluppatori siamo stati estremamente frustrati da queste sciocchezze in Xcode da sempre, l'unico IDE senza opzione di duplicazione di riga. Ho appena aggiornato a Xcode 10 e, come hai intuito, tutti i miei tasti di scelta rapida vengono rimossi insieme alla funzionalità di duplicazione della linea. Tuttavia, è risolvibile come nella risposta originale. Una leggera differenza questa volta è che avrai bisogno della seguente riga:

<key>Duplicate Current Line</key>
<string>selectLine:, copy:, moveToBeginningOfLine:, paste:, moveToEndOfLine:</string>

MODIFICARE: Xcode 9: ho dovuto rifare le scorciatoie e la duplicazione e la cancellazione della linea, ma la cosa buona è che ora puoi modificare di nuovo IDETextKeyBindingSet.plist. Questo tizio Apple in alto deve essere in vacanza quando hanno rilasciato questa versione.

MODIFICARE: Xcode 8: Buggy, non puoi modificare affatto il file IDETextKeyBindingSet.plist. Xcode lo reimposta all'avvio. Questo ragazzo di alto livello in Apple è davvero determinato a farci usare copia / incolla invece della semplice duplicazione di riga come in tutti gli altri IDE là fuori.

MODIFICARE: Xcode 7.1 e ancora non ci sono scorciatoie per la duplicazione e la cancellazione della linea. Questo è l'unico IDE con cui abbia mai lavorato senza tali scorciatoie. E non riesco a immaginare la vita di uno sviluppatore senza queste due scorciatoie critiche.

Ecco come si può fare:

Per prima cosa dobbiamo modificare un file plist che risiede all'interno del bundle Xcode.app (necessita di sudo per essere modificato)

/Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Resources/IDETextKeyBindingSet.plist

Quindi cerca <key>Insertions and Indentations</key>e sotto il <dict>tag aggiungi quanto segue:

<key>Insert New Line Below</key>
<string>moveToEndOfLine:, insertNewline:</string>
<key>Insert New Line Above</key>
<string>moveUp:, moveToEndOfLine:, insertNewline:</string>
<key>Duplicate Current Line</key>
<string>selectLine:, copy:, moveToEndOfLine:, insertNewline:, paste:, deleteBackward:</string>

Quindi trova i e questi all'interno della sezione <key>Deletions</key>sotto il <dict>tag:

<key>Delete Current Line</key>
<string>selectLine:, delete:</string>
<string>selectLine:, delete:</string>

inserisci qui la descrizione dell'immagine

Ora apri / riavvia Xcode, vai su Preferenze e vai alla scheda "Associazioni tasti". Usa la barra di ricerca per filtrare e cercare le nuove scorciatoie. Quindi fai clic davanti alla descrizione del collegamento per assegnargli un collegamento di tuo gradimento. Assicurati che il tuo collegamento non sia in conflitto con i collegamenti esistenti.

inserisci qui la descrizione dell'immagine


3

Considererei di rivedere la sequenza di comandi per:

selectLine:,
copy:,
moveToEndOfLine:,
insertNewline:,
deleteToBeginningOfLine:,
paste:,
moveToBeginningOfLine:, 
deleteBackward:

L'aggiunta deleteToBeginningOfLinemantiene il rientro della riga duplicata.


Ha funzionato benissimo una volta che mi sono reso conto che dovevo scambiare le nuove righe (belle) con uno spazio dopo la virgola.
McUsr

2

insertLineBreak aveva bisogno almeno di me per fare una copia su una nuova riga, senza di essa avevo la copia sulla stessa riga


2

Ho avuto grossi problemi a sbloccare il file .plist su MacOS Sierra e Xcode 9, anche la decisione di @Tim non ha funzionato per me. Se hai lo stesso problema, vai al terminale e fai questo:

cd /Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/A/Resources/
sudo chmod -R 777 *
nano IDETextKeyBindingSet.plist

Qui vengono descritti anche alcuni altri modi possibili per farlo .

Quindi, nell'editor nano, fare clic ^We digitare "inserimenti" per passare alla parte "Inserimenti e rientri". Appena sotto il <dict>tag incolla questo snippet xml:

<key>Duplicate line</key>
<string>selectLine:, copy:, moveToEndOfLine:, insertNewLine:, paste:, deleteBackward:</string>

Premere control + X, quindi Y, quindi Enterper salvare il file nell'editor nano.

UPD: Ho trovato una decisione migliore, che aggiunge una riga aggiuntiva prima della duplicazione (utile quando si desidera duplicare una riga che ha un'altra riga appena sotto):

<key>Duplicate line</key>
<string>selectLine:, copy:, moveToEndOfLine:, insertLineBreak:, moveUp:, paste:, moveToBeginningOfLine:</string>

1

Ecco le mie voci Delete ( CTRL+ D) e Duplicate ( CMD+ SHIFT+ D) dal mio IDETextKeyBindingSet.plist. (in /Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/A/Resources)

Li ho appena impostati in Xcode 4.6.1 (in base alla risposta dell'utente570753 sopra e altrove)

    <key>Custimozed</key>
<dict>
    <key>Delete Current Line</key>
    <string>deleteToBeginningOfLine:, moveToEndOfLine:, deleteToBeginningOfLine:, deleteBackward:, moveDown:, moveToBeginningOfLine:</string>
    <key>Duplicate Current Line</key>
    <string>selectLine:, copy:, moveToEndOfLine:, insertNewline:, deleteToBeginningOfLine:, paste:, moveToBeginningOfLine:, deleteBackward:</string>
</dict>

0

Qualsiasi utente di testo sublime che desideri abbinare duplicateLineUp e duplicateLineDown di sublime in XCode, aggiungi quanto segue al tuo file IDETextKeyBindingSet.plist

<key>Line Duplications</key>
<dict>
    <key>Duplicate Current Line Above</key>
    <string>selectLine:, copy:, moveToEndOfLine:, insertNewline:, paste:, deleteBackward:, moveUp:</string>
    <key>Duplicate Current Line Below</key>
    <string>selectLine:, copy:, moveToEndOfLine:, insertNewline:, paste:, deleteBackward:</string>
</dict>

0

Nel caso in cui a qualcun altro venga negato l'accesso per modificare IDETextKeyBindingSet.plist, puoi concederti i permessi di lettura / scrittura:

sudo chmod 777 /Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/A/Resources/IDETextKeyBindingSet.plist

0

Solo per completare la risposta di Hailei, i comandi che hanno funzionato meglio per me sono stati:

selectLine:, copy:, moveRight:, moveLeft:, insertNewline:, paste:, deleteBackward:

I suoi comandi suggeriti stavano copiando la riga desiderata due righe sotto, per me.


0
<key>Duplicate Lines</key>    
<string>selectLine:, copy:, moveToBeginningOfLine:, paste:</string>

Linee duplicate supportate. (Funziona in Xcode 9.2)


0

Per quanto riguarda Xcode 11, nessuno dei precedenti ha funzionato per me. La prima risposta ha avuto un comportamento strano poiché inseriva la riga dopo la riga successiva. La seguente risposta, tuttavia, ha funzionato per me.

<key>Duplication</key>
<dict>
    <key>Duplicate Current Line</key>
    <string>moveToBeginningOfLine:, deleteToEndOfLine:, yank:, insertNewline:, moveToBeginningOfLine:, yank:</string>
    <key>Duplicate Lines</key>
    <string>selectLine:, copy:, moveToEndOfLine:, insertNewline:, paste:, deleteBackward:</string>
    <key>Delete Line</key>
    <string>selectLine:, deleteBackward:</string>
</dict>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.