mirror of https://github.com/gogits/gogs.git
Michael Boke
10 years ago
289 changed files with 129308 additions and 2869 deletions
@ -1,12 +0,0 @@
|
||||
{ |
||||
"paths": ["."], |
||||
"depth": 2, |
||||
"exclude": [], |
||||
"include": ["\\.go$", "\\.ini$"], |
||||
"command": [ |
||||
"bash", "-c", "go build && ./gogs web" |
||||
], |
||||
"env": { |
||||
"POWERED_BY": "github.com/shxsun/fswatch" |
||||
} |
||||
} |
@ -0,0 +1,15 @@
|
||||
targets: |
||||
ubuntu-14.04: |
||||
ubuntu-12.04: |
||||
debian-7: |
||||
build_dependencies: |
||||
- mercurial |
||||
- bzr |
||||
dependencies: |
||||
- git |
||||
before: |
||||
- mv packager/Procfile . |
||||
- mv packager/.godir . |
||||
after: |
||||
- mv bin/main gogs |
||||
after_install: ./packager/debian/postinst |
@ -0,0 +1,158 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package cmd |
||||
|
||||
import ( |
||||
"crypto/ecdsa" |
||||
"crypto/elliptic" |
||||
"crypto/rand" |
||||
"crypto/rsa" |
||||
"crypto/x509" |
||||
"crypto/x509/pkix" |
||||
"encoding/pem" |
||||
"log" |
||||
"math/big" |
||||
"net" |
||||
"os" |
||||
"strings" |
||||
"time" |
||||
|
||||
"github.com/codegangsta/cli" |
||||
) |
||||
|
||||
var CmdCert = cli.Command{ |
||||
Name: "cert", |
||||
Usage: "Generate self-signed certificate", |
||||
Description: `Generate a self-signed X.509 certificate for a TLS server.
|
||||
Outputs to 'cert.pem' and 'key.pem' and will overwrite existing files.`, |
||||
Action: runCert, |
||||
Flags: []cli.Flag{ |
||||
cli.StringFlag{"host", "", "Comma-separated hostnames and IPs to generate a certificate for", ""}, |
||||
cli.StringFlag{"ecdsa-curve", "", "ECDSA curve to use to generate a key. Valid values are P224, P256, P384, P521", ""}, |
||||
cli.IntFlag{"rsa-bits", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set", ""}, |
||||
cli.StringFlag{"start-date", "", "Creation date formatted as Jan 1 15:04:05 2011", ""}, |
||||
cli.DurationFlag{"duration", 365 * 24 * time.Hour, "Duration that certificate is valid for", ""}, |
||||
cli.BoolFlag{"ca", "whether this cert should be its own Certificate Authority", ""}, |
||||
}, |
||||
} |
||||
|
||||
func publicKey(priv interface{}) interface{} { |
||||
switch k := priv.(type) { |
||||
case *rsa.PrivateKey: |
||||
return &k.PublicKey |
||||
case *ecdsa.PrivateKey: |
||||
return &k.PublicKey |
||||
default: |
||||
return nil |
||||
} |
||||
} |
||||
|
||||
func pemBlockForKey(priv interface{}) *pem.Block { |
||||
switch k := priv.(type) { |
||||
case *rsa.PrivateKey: |
||||
return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)} |
||||
case *ecdsa.PrivateKey: |
||||
b, err := x509.MarshalECPrivateKey(k) |
||||
if err != nil { |
||||
log.Fatal("unable to marshal ECDSA private key: %v", err) |
||||
} |
||||
return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b} |
||||
default: |
||||
return nil |
||||
} |
||||
} |
||||
|
||||
func runCert(ctx *cli.Context) { |
||||
if len(ctx.String("host")) == 0 { |
||||
log.Fatal("Missing required --host parameter") |
||||
} |
||||
|
||||
var priv interface{} |
||||
var err error |
||||
switch ctx.String("ecdsa-curve") { |
||||
case "": |
||||
priv, err = rsa.GenerateKey(rand.Reader, ctx.Int("rsa-bits")) |
||||
case "P224": |
||||
priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader) |
||||
case "P256": |
||||
priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader) |
||||
case "P384": |
||||
priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader) |
||||
case "P521": |
||||
priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader) |
||||
default: |
||||
log.Fatalf("Unrecognized elliptic curve: %q", ctx.String("ecdsa-curve")) |
||||
} |
||||
if err != nil { |
||||
log.Fatalf("Failed to generate private key: %s", err) |
||||
} |
||||
|
||||
var notBefore time.Time |
||||
if len(ctx.String("start-date")) == 0 { |
||||
notBefore = time.Now() |
||||
} else { |
||||
notBefore, err = time.Parse("Jan 2 15:04:05 2006", ctx.String("start-date")) |
||||
if err != nil { |
||||
log.Fatalf("Failed to parse creation date: %s", err) |
||||
} |
||||
} |
||||
|
||||
notAfter := notBefore.Add(ctx.Duration("duration")) |
||||
|
||||
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) |
||||
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) |
||||
if err != nil { |
||||
log.Fatalf("Failed to generate serial number: %s", err) |
||||
} |
||||
|
||||
template := x509.Certificate{ |
||||
SerialNumber: serialNumber, |
||||
Subject: pkix.Name{ |
||||
Organization: []string{"Acme Co"}, |
||||
}, |
||||
NotBefore: notBefore, |
||||
NotAfter: notAfter, |
||||
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, |
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, |
||||
BasicConstraintsValid: true, |
||||
} |
||||
|
||||
hosts := strings.Split(ctx.String("host"), ",") |
||||
for _, h := range hosts { |
||||
if ip := net.ParseIP(h); ip != nil { |
||||
template.IPAddresses = append(template.IPAddresses, ip) |
||||
} else { |
||||
template.DNSNames = append(template.DNSNames, h) |
||||
} |
||||
} |
||||
|
||||
if ctx.Bool("ca") { |
||||
template.IsCA = true |
||||
template.KeyUsage |= x509.KeyUsageCertSign |
||||
} |
||||
|
||||
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv) |
||||
if err != nil { |
||||
log.Fatalf("Failed to create certificate: %s", err) |
||||
} |
||||
|
||||
certOut, err := os.Create("cert.pem") |
||||
if err != nil { |
||||
log.Fatalf("Failed to open cert.pem for writing: %s", err) |
||||
} |
||||
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) |
||||
certOut.Close() |
||||
log.Println("Written cert.pem") |
||||
|
||||
keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) |
||||
if err != nil { |
||||
log.Fatal("failed to open key.pem for writing: %v", err) |
||||
} |
||||
pem.Encode(keyOut, pemBlockForKey(priv)) |
||||
keyOut.Close() |
||||
log.Println("Written key.pem") |
||||
} |
@ -0,0 +1,516 @@
|
||||
app_desc = Un service Git écrit en Go auto-hébergé |
||||
|
||||
home = Accueil |
||||
dashboard = Tableau de bord |
||||
explore = Explorer |
||||
help = Aide |
||||
sign_in = Connexion |
||||
social_sign_in = Authentification via Internet: 2ème étape <small>associé le compte</small> |
||||
sign_out = Déconnexion |
||||
sign_up = Créer un compte |
||||
register = S'inscrire |
||||
website = Site web |
||||
version = Version |
||||
page = Page |
||||
template = Gabarit |
||||
language = Langage |
||||
|
||||
username = Usager |
||||
email = Courriel |
||||
password = Mot de passe |
||||
re_type = Saisir à nouveau |
||||
captcha = Captcha |
||||
|
||||
repository = Dépôt |
||||
organization = Organisation |
||||
mirror = Mirroir |
||||
new_repo = Nouveau dépôt |
||||
new_migrate = Nouvelle migration |
||||
new_org = Nouvel organisation |
||||
manage_org = Gestion des organisations |
||||
admin_panel = Gestion |
||||
account_settings = Profil usager |
||||
settings = Configuration |
||||
|
||||
news_feed = Fil de nouvelles |
||||
pull_requests = Demandes de fusion (pull requests) |
||||
issues = Suivi de problèmes |
||||
|
||||
cancel = Annuler |
||||
|
||||
[home] |
||||
uname_holder = Nom d'usager ou courriel |
||||
password_holder = Mot de passe |
||||
switch_dashboard_context = Changer de tableau de bord |
||||
my_repos = Mes dépôts |
||||
collaborative_repos = Dépôts partagés |
||||
my_orgs = Mes organisations |
||||
my_mirrors = Mes mirroirs |
||||
|
||||
[auth] |
||||
create_new_account = Créer un nouveau compte |
||||
register_hepler_msg = Déjà inscrits? Connectez-vous maintenant! |
||||
social_register_hepler_msg = Déjà inscrits? Branchez-vous! |
||||
disable_register_prompt = Désolé, l'auto-inscription n'est pas activée. Contactez l'admnistrateur du site. |
||||
disable_register_mail = Désolé, la confirmation d'inscription par courriel est désactivée. Contactez l'administrateur du site. |
||||
remember_me = Se souvenir de moi |
||||
forgot_password= Mot de passe oublié |
||||
forget_password = Mot de passe oublié? |
||||
sign_up_now = Besoin d'un compte? Inscrivez-vous maintenant. |
||||
confirmation_mail_sent_prompt = Un courriel de confirmation à été envoyé à <b>%s</b>, consultez vos courriels d'ici %d heures pour terminer l'inscription. |
||||
sign_in_email = Connexion avec votre courriel |
||||
active_your_account = Activez votre compte |
||||
resent_limit_prompt = Désolé vous demandez trop souvent un courriel de confirmation. S.v.p. patientez 3 minutes. |
||||
has_unconfirmed_mail = Bonjour %s, votre adresse courriel n'est pas vérifiée(<b>%s</b>). Si vous n'avez pas reçu de courriel de confirmation ou si vous avez besoin d'en envoyer un maintenant, appuyez sur le bouton ci-dessous. |
||||
resend_mail = Appuyez ici pour envoyer de nouveau un courriel de confirmation. |
||||
email_not_associate = Ce courriel ne correspond à aucun compte. |
||||
send_reset_mail = Appuyez ici pour (ré)envoyer un courriel pour réinitialiser le mot de passe. |
||||
reset_password = Réinitialiser votre mot de passe |
||||
invalid_code = Désolé, ce code de confirmation est périmé ou non-valide. |
||||
reset_password_helper = Appuyez ici pour réinitialiser votre mot de passe |
||||
password_too_short = La longueur du mot de passe doit être d'au moins 6 caractères. |
||||
|
||||
[form] |
||||
UserName = Nom d'usager |
||||
RepoName = Nom du dépôt |
||||
Email = Adresse de courriel |
||||
Password = Mot de passe |
||||
Retype = Mot de passe (confirmation) |
||||
SSHTitle = Nom de la clé SSH |
||||
HttpsUrl = URL HTTPS |
||||
PayloadUrl = URL cible |
||||
TeamName = Nom de l'équipe |
||||
AuthName = Nom d'usager |
||||
|
||||
require_error = ` ne peut être vide.` |
||||
alpha_dash_error = ` doit être composé de caractères alpha-numériques et/ou d'un tiret(-_).` |
||||
alpha_dash_dot_error = ` doit être composé de caractères alpha-numérique, un point(.) et/ou tiret(-_).` |
||||
min_size_error = ` doit être composé d'au moins %s caractères.` |
||||
max_size_error = ` doit être conposé d'au plus %s caractères.` |
||||
email_error = ` n'est pas une adresse de courriel bien formée.` |
||||
url_error = ` n'est pas un URL valide.` |
||||
unknown_error = Erreur inconnue: |
||||
captcha_incorrect = Le captcha ne concorde pas. |
||||
password_not_match = Les deux mots de passe diffèrent. |
||||
|
||||
username_been_taken = `Nom d'usager dèjà utilisé.` |
||||
repo_name_been_taken = Nom de dépôt déjà utilisé. |
||||
org_name_been_taken = Nom d'organisation déjà utilisé. |
||||
team_name_been_taken = Nom d'équipe déjà utilisé. |
||||
email_been_used = Adresse de courriel déjà utilisée. |
||||
ssh_key_been_used = Nom de clé publique déjà utilisé. |
||||
illegal_username = Votre nom d'usager contient des caractères interdits. |
||||
illegal_repo_name = Le nom du dépôt contient des caractères interdits. |
||||
illegal_org_name = Le nom de l'organisation contient des caractères interdits. |
||||
illegal_team_name = Le nom de l'équipe contient des caractères interdits. |
||||
username_password_incorrect = Nom d'usager ou mot de passe erroné. |
||||
enterred_invalid_repo_name = Nom de dépôt inexistant. |
||||
enterred_invalid_owner_name = Responsable de dépôt inexistant. |
||||
enterred_invalid_password = Mot de passe erroné. |
||||
user_not_exist = Nom d'usager inexistant. |
||||
last_org_owner = Ceci est le dernier responsable du dépôt. Il doit y avoir obligatoirement au moins un usager responsable. |
||||
|
||||
invalid_ssh_key = Désolé, impossible de vérifier votre clé SSH: % |
||||
auth_failed = Erreur d'authentification : %v |
||||
|
||||
still_own_repo = Votre compte est responsable d'au moins un dépôt. Vous devez soit détruire ces dépôts, soit transférer la responsabilité à un autre usager. |
||||
org_still_own_repo = Cette organisation est responsable d'au moins un dépôt. Vous devez soit détruire ces dépôts, soit transférer la responsabilité à un autre usager ou organisation. |
||||
|
||||
still_own_user = Cette authentification est utilisée par un usager. |
||||
|
||||
[settings] |
||||
profile = Profil |
||||
password = Mot de passe |
||||
ssh_keys = Clés SSH |
||||
social = Comptes Internet |
||||
orgs = Organisations |
||||
delete = Supprimer votre compte |
||||
|
||||
public_profile = Profil public |
||||
profile_desc = Votre adresse de courriel est publique et sera utilisée pour les avis produits par le site. |
||||
full_name = Nom complet |
||||
website = Site web |
||||
location = Endroit |
||||
update_profile = Mettre à jour le profil |
||||
update_profile_success = Mise à jour du profil réussie. |
||||
|
||||
change_password = Changer le mot de passe |
||||
old_password = Mot de passe actuel |
||||
new_password = Nouveau mot de passe |
||||
password_incorrect = Mot de passe actuel erroné. |
||||
change_password_success = Modification du mot de passe effectuée. Vous pouvez dorénavant vous connecter avec le nouveau mot de passe. |
||||
|
||||
manage_ssh_keys = Gestion des clés SSH |
||||
add_key = Ajouter une clé |
||||
ssh_desc = Voici la liste de clés SSH associées à votre profil. Retirez les clés que vous ne reconnaissez pas. |
||||
ssh_helper = <strong>Beson d'aide?</strong> Consultez le guide au <a href="https://help.github.com/articles/generating-ssh-keys">generating SSH keys</a> ou vérifiez <a href="https://help.github.com/ssh-issues/">les problèmes SSH fréquents</a>. |
||||
add_new_key = Ajouter une clé SSH |
||||
key_name = Nom de la clé |
||||
key_content = Contenu |
||||
add_key_success = Clé SSH ajoutée! |
||||
delete_key = Détruire |
||||
add_on = Ajoutée le |
||||
last_used = Dernière utilisation le |
||||
no_activity = Pas d'activité récente |
||||
|
||||
manage_social = Gestion des comptes Internets associés |
||||
social_desc = Ceci est une liste de comptes Internet associés. Retirez les comptes que vous ne reconnaissez pas. |
||||
unbind = Désassocier |
||||
unbind_success = Compte Internet déassocié. |
||||
|
||||
delete_account = Detruire votre compte |
||||
delete_prompt = Cette opération détruira votre compte et <strong>ne pourra être annulée</strong>! |
||||
confirm_delete_account = Confirmez la suppression |
||||
|
||||
[repo] |
||||
owner = Responsable |
||||
repo_name = Nom du dépôt |
||||
repo_name_helper = Les bons noms de dépôts sont courts, mémorables et <strong>uniques</strong>. |
||||
visibility = Visibilité |
||||
visiblity_helper = Ce dépôt est <span class="label label-red label-radius">privé</span> |
||||
repo_desc = Description |
||||
repo_lang = Langue |
||||
repo_lang_helper = Choisir un fichier .gitignore |
||||
license = License |
||||
license_helper = Choisir un fichier de licence |
||||
init_readme = Initialiser le dépôt avec un fichier README.md |
||||
create_repo = Créer le dépôt |
||||
default_branch = Branche par défaut |
||||
mirror_interval = Intervale de synchronisation (heures) |
||||
goget_meta = Métadonnées Go-Get |
||||
goget_meta_helper = Ce dépôt sera <span class="label label-blue label-radius">Go-Getable</span> |
||||
|
||||
need_auth = Authorisation requise |
||||
migrate_type = Type de migration |
||||
migrate_type_helper = Ce dépôt sera un <span class="label label-blue label-radius">mirroir</span> |
||||
migrate_repo = Migrer le dépôt |
||||
|
||||
copy_link = Copier |
||||
clone_helper = Besoin d'aide pour cloner? Obtenez de l' <a target="_blank" href="http://git-scm.com/book/fr/Les-bases-de-Git-Démarrer-un-dépôt-Git">aide</a>! |
||||
unwatch = Ne plus suivre |
||||
watch = Suivre |
||||
unstar = Retirer étoile |
||||
star = Étoile |
||||
fork = Fork |
||||
|
||||
quick_guide = Guide rapide |
||||
clone_this_repo = Cloner ce dépôt |
||||
create_new_repo_command = Créer un nouveau dépôt à la ligne de commande |
||||
push_exist_repo = Pousser un dépôt existant depuis la ligne de commande |
||||
|
||||
settings = Réglages |
||||
settings.options = Réglages de base |
||||
settings.collaboration = Collaboration |
||||
settings.hooks = Webhooks |
||||
settings.deploy_keys = Clé de déploiement |
||||
settings.basic_settings = réglages de base |
||||
settings.danger_zone = Danger! |
||||
settings.site = Site officiel |
||||
settings.update_settings = Réglage des mises à jour |
||||
settings.transfer = Transférer la responsabilité |
||||
settings.transfer_desc = Transférer ce dépôt à un autre usager ou organisation si vous en avez la responsabilité. |
||||
settings.delete = Détruire ce dépôt |
||||
settings.delete_desc = La destruction est irrémédiable, impossible d'annuler. Soyez sûr de votre décision. |
||||
settings.update_settings_success = Réglages modifiés |
||||
settings.transfer_owner = Nouveau responsable |
||||
settings.make_transfer = Faire le transfert |
||||
settings.confirm_delete = Confirmer la destruction |
||||
settings.add_collaborator = Ajouter un nouveau collaborateur |
||||
settings.add_collaborator_success = Nouveau collaborateur ajouté. |
||||
settings.remove_collaborator_success = Collaborateur supprimé. |
||||
settings.add_webhook = Ajouter un Webhook |
||||
settings.hooks_desc = Les Webhooks permettent à des services externes d'être avertis de certains changements sur Gogs. Lorque qu'un changement se produit, Gogs envoie une requête POST à chacun des URLs spécifiés. Plus d'info disponible sur notre <a target="_blank" href="http://gogs.io/docs/features/webhook.html">guide Webhooks'</a>. |
||||
settings.remove_hook_success = Webhook supprimé. |
||||
settings.add_webhook_desc = Gogs envoiera un POST à l'URL ci-dessous avec le détail de l'événement souscrit. Vous pouvez aussi spécifier dans quel format vous désirez recevoir les données (JSON,<code>x-www-form-urlencoded</code>, <em>etc</em>). Plus d'info disponible sur notre <a target="_blank" href="http://gogs.io/docs/features/webhook.html">guide Webhooks'</a>. |
||||
settings.payload_url = URL cible |
||||
settings.content_type = Content Type |
||||
settings.secret = Secret |
||||
settings.event_desc = Quels changements déclencheront le webhook? |
||||
settings.event_push_only = Uniquement les <code>push</code>. |
||||
settings.active = Activé |
||||
settings.active_helper = Gogs fournira le détail de l'événement lorsque ce webhook sera déclenché. |
||||
settings.add_hook_success = Nouveau webhook ajouté. |
||||
settings.update_webhook = Mettre à jour le webhook |
||||
settings.update_hook_success = Webhook mis à jour. |
||||
settings.delete_webhook = Détruire le webhook |
||||
settings.recent_deliveries = Livraisons récentes |
||||
settings.hook_type = Type de déclencheur |
||||
settings.add_slack_hook_desc = Ajouter la compatibilité <a href="http://slack.com">Slack</a> à ce dépôt. |
||||
settings.slack_token = Jeton (token) |
||||
settings.slack_domain = Domaine |
||||
settings.slack_channel = Canal |
||||
|
||||
[org] |
||||
org_name_holder = Nom de l'organisation |
||||
org_name_helper = Les bons noms d'organisations sont courts, mémorables et uniques |
||||
org_email_helper = Le courriel de l'organisation recevra toutes les notifications et les confirmations. |
||||
create_org = Créer une organisation |
||||
repo_updated = Changement effectué |
||||
people = Personne |
||||
invite_someone = Inviter quelqu'un |
||||
teams = Équipes |
||||
lower_members = Membres |
||||
lower_repositories = Dépôts |
||||
create_new_team = Créer une nouvelle équipe |
||||
org_desc = Description |
||||
team_name = Nom de l'équipe |
||||
team_desc = Description |
||||
team_name_helper = Le nom qui sera utilisé pour mentionner cette équipe dans les conversations. |
||||
team_desc_helper = Quel est la raison d'être de cette équipe? |
||||
team_permission_desc = Quel niveau de permission attribuer à cette équipe? |
||||
|
||||
settings = Réglages |
||||
settings.options = Paramètres |
||||
settings.full_name = Nom complet |
||||
settings.website = Site web |
||||
settings.location = Endroit |
||||
settings.update_settings = Mettre à jour les paramètres |
||||
settings.update_setting_success = Paramètres mis à jour. |
||||
settings.delete = Détruire l'organisation |
||||
settings.delete_account = Détruire cette organisation |
||||
settings.delete_prompt = La destruction de l'organisation est irrémédiable, impossible d'annuler. Soyez sûr de votre décision. |
||||
settings.confirm_delete_account = Confirmer la destruction |
||||
|
||||
members.public = Publique |
||||
members.public_helper = Rendre privé |
||||
members.private = Privé |
||||
members.private_helper = Rendre publique |
||||
members.owner = Responsable |
||||
members.member = Membre |
||||
members.conceal = Caché |
||||
members.remove = Retirer |
||||
members.leave = Quitter |
||||
members.invite_desc = Commencez à saisir un nom d'usager pour l'inviter à %s: |
||||
members.invite_now = Inviter |
||||
|
||||
teams.join = Rejoindre |
||||
teams.leave = Quitter |
||||
teams.read_access = Droits de lecture |
||||
teams.read_access_helper = Cette équipe pourra voir et cloner ses dépôts. |
||||
teams.write_access = Droits d'écriture |
||||
teams.write_access_helper = Cette équipe pourra voir et cloner ses dépôts ainsi que pousser vers ceux-ci. |
||||
teams.admin_access = Droits de gestion |
||||
teams.admin_access_helper = En plus des droits d'écriture, cette équipe pourra gérer les collaborateurs. |
||||
teams.no_desc = Cette équipe ne posséde pas de description |
||||
teams.settings = Réglages |
||||
teams.owners_permission_desc = Les responsables ont accès à <strong>tous</strong> les dépôts et en possédent les droits de gestion. |
||||
teams.members = Membre de l'équipe |
||||
teams.update_settings = Mettre à jour |
||||
teams.delete_team = Détruire cette équipe |
||||
teams.add_team_member = Ajouter un membre à l'équipe |
||||
teams.delete_team_success = Équipe détruite |
||||
teams.read_permission_desc = La participation à cette équipe confère les droits de lecture. Ses membres peuvent voir et cloner ses dépôts. |
||||
teams.write_permission_desc = La participation à cette équipe confère les droits d'écriture en plus des droits de lecture. Ses membres peuvent pousser vers les dépôts de l'équipe. |
||||
teams.admin_permission_desc = La participation à cette équire confère les droits de gestion. Ses membres peuvent voir, cloner, pousser et gérer les collaborateurs des dépôts. |
||||
teams.repositories = Dépôts de l'équipe |
||||
teams.add_team_repository = Ajouer un dépôt à l'équipe |
||||
teams.remove_repo = Enlever |
||||
|
||||
[admin] |
||||
dashboard = Tableau de bord |
||||
users = Usagers |
||||
organizations = Organisations |
||||
repositories = Dépôts |
||||
authentication = Sources d'authentifications |
||||
config = Configuration |
||||
monitor = Monitoring |
||||
prev = Préc. |
||||
next = Suiv. |
||||
|
||||
dashboard.statistic = Statistiques |
||||
dashboard.operations = Opérations |
||||
dashboard.system_status = État du monitoring système |
||||
dashboard.statistic_info = La BD Gogs compte <b>%d</b> usagers, <b>%d</b> organisations, <b>%d</b> clé SSH, <b>%d</b> dépôts, <b>%d</b> suivis, <b>%d</b> étoiles, <b>%d</b> actions, <b>%d</b> accès, <b>%d</b> tickets, <b>%d</b> commentaires, <b>%d</b> comptes Internet, <b>%d</b> suivis, <b>%d</b> mirroirs, <b>%d</b> publications, <b>%d</b> sources d'authentification, <b>%d</b> webhooks, <b>%d</b> jalons, <b>%d</b> tags, <b>%d</b> tâches hook, <b>%d</b> équipes, <b>%d</b> tâches de mise à jours, <b>%d</b> fichiers joints. |
||||
dashboard.operation_name = Nom de l'opération |
||||
dashboard.operation_switch = Commande |
||||
dashboard.operation_run = Lancer |
||||
dashboard.clean_unbind_oauth = Nettoyer les OAuths orphelins |
||||
dashboard.delete_inactivate_accounts = Détruire les comptes inactifs |
||||
dashboard.server_uptime = Démarré depuis |
||||
dashboard.current_goroutine = Nombre de Goroutines |
||||
dashboard.current_memory_usage = Usage mémoire actuel |
||||
dashboard.total_memory_allocated = Mémoire allouée totale |
||||
dashboard.memory_obtained = Memoire obtenue |
||||
dashboard.pointer_lookup_times = Accès pointeur |
||||
dashboard.memory_allocate_times = Allocation mémoire |
||||
dashboard.memory_free_times = Désallocation mémoire |
||||
dashboard.current_heap_usage = Taille du heap actuelle |
||||
dashboard.heap_memory_obtained = Mémoire heap obtenue |
||||
dashboard.heap_memory_idle = Mémoire heap inactive |
||||
dashboard.heap_memory_in_use = Mémoire heap utilisée |
||||
dashboard.heap_memory_released = Mémoire heap relachée |
||||
dashboard.heap_objects = Objets dans le heap |
||||
dashboard.bootstrap_stack_usage = Bootstrap Stack Usage |
||||
dashboard.stack_memory_obtained = Stack Memory Obtained |
||||
dashboard.mspan_structures_usage = MSpan Structures Usage |
||||
dashboard.mspan_structures_obtained = MSpan Structures Obtained |
||||
dashboard.mcache_structures_usage = MCache Structures Usage |
||||
dashboard.mcache_structures_obtained = MCache Structures Obtained |
||||
dashboard.profiling_bucket_hash_table_obtained = Profiling Bucket Hash Table Obtained |
||||
dashboard.gc_metadata_obtained = GC Metadada Obtained |
||||
dashboard.other_system_allocation_obtained = Other System Allocation Obtained |
||||
dashboard.next_gc_recycle = Next GC Recycle |
||||
dashboard.last_gc_time = Since Last GC Time |
||||
dashboard.total_gc_time = Total GC Pause |
||||
dashboard.total_gc_pause = Total GC Pause |
||||
dashboard.last_gc_pause = Last GC Pause |
||||
dashboard.gc_times = GC Times |
||||
|
||||
users.user_manage_panel = Gestion des usager |
||||
users.new_account = Creér un nouveau compte |
||||
users.name = Nom |
||||
users.activated = Activé |
||||
users.admin = Gestionnaire |
||||
users.repos = Dépôts |
||||
users.created = Créé |
||||
users.edit = Editer |
||||
users.auth_source = Source d'authentification |
||||
users.local = Locale |
||||
users.auth_login_name = Identifiant d'authentification |
||||
users.update_profile_success = Compte crée. |
||||
users.edit_account = Éditer compte |
||||
users.is_activated = Ce compte est activé |
||||
users.is_admin = Ce compte a les droits de gestionnaire |
||||
users.update_profile = Mettre à jour le compte |
||||
users.delete_account = Détruire ce compte |
||||
users.still_own_repo = Ce compte est responsables d'un dépôt. I faut détruire le dépôt ou transférer la responsabilité avant de détruire ce compte. |
||||
|
||||
orgs.org_manage_panel = Gestion des organisations |
||||
orgs.name = Nom |
||||
orgs.teams = Équipes |
||||
orgs.members = Membres |
||||
|
||||
repos.repo_manage_panel = Gestion des dépôts |
||||
repos.owner = Responsable |
||||
repos.name = Nom |
||||
repos.private = Privé |
||||
repos.watches = Suivis |
||||
repos.stars = Étoiles |
||||
repos.issues = Ticket |
||||
|
||||
auths.auth_manage_panel = Gestion des sources d'authentification |
||||
auths.new = Ajouter une nouvelle source d'authentification |
||||
auths.name = Nom |
||||
auths.type = Type |
||||
auths.enabled = Activé |
||||
auths.updated = Mis à jour |
||||
auths.auth_type = Type d'authentification |
||||
auths.auth_name = Nom de l'authentification |
||||
auths.domain = Domaine |
||||
auths.host = Serveur |
||||
auths.port = Port |
||||
auths.base_dn = DN de base |
||||
auths.attributes = Attributs de recherche |
||||
auths.filter = Filtre de recherche |
||||
auths.ms_ad_sa = Microsoft Active Directory |
||||
auths.smtp_auth = Authentification SMTP |
||||
auths.smtphost = Serveur SMTP |
||||
auths.smtpport = Port SMTP |
||||
auths.enable_tls = Chiffrement TLS |
||||
auths.enable_auto_register = Activer auto-abonnement |
||||
auths.tips = Trucs |
||||
auths.edit = Éditer réglages d'authentification |
||||
auths.activated = Source d'authentification activée |
||||
auths.update_success = Réglages mis à jour. |
||||
auths.update = Mettre à jour réglages |
||||
auths.delete = Détruire cette source |
||||
|
||||
config.server_config = Configuration du serveur |
||||
config.app_name = Nom de l'applicaiton |
||||
config.app_ver = Version de l'application |
||||
config.app_url = URL de l'application |
||||
config.domain = Domaine |
||||
config.offline_mode = Mode hors-ligne |
||||
config.disable_router_log = Journal du routeur désactivé |
||||
config.run_user = Éxécuté en tant que |
||||
config.run_mode = Mode de fonctionnement |
||||
config.repo_root_path = Dossier contenant les dépôts |
||||
config.static_file_root_path = Dossier contenant les fichiers statiques |
||||
config.log_file_root_path = Dossier contenant les journaux |
||||
config.script_type = Type de script |
||||
config.reverse_auth_user = Usager d'authentification inversée |
||||
config.db_config = Configuration de la BD |
||||
config.db_type = Type |
||||
config.db_host = Serveur |
||||
config.db_name = Nom |
||||
config.db_user = Usager |
||||
config.db_ssl_mode = Mode SSL |
||||
config.db_ssl_mode_helper = (pour "postgres" seulement) |
||||
config.db_path = Path |
||||
config.db_path_helper = (pour "sqlite3" seulement) |
||||
config.service_config = Configuration du service |
||||
config.register_email_confirm = Confirmation d'abonnement par courriel |
||||
config.disable_register = Auto-inscription désactivée |
||||
config.require_sign_in_view = Connexion requise pour visualiser |
||||
config.mail_notify = Notifications par courriel |
||||
config.enable_cache_avatar = Cache avatar activée |
||||
config.active_code_lives = Jeton d'activation |
||||
config.reset_password_code_lives = Jeton de modification mot-de-passe |
||||
config.webhook_config = Configuration Webhook |
||||
config.task_interval = Intervalle |
||||
config.deliver_timeout = Expiration des appels |
||||
config.mailer_config = Configuration expédition de courriels |
||||
config.mailer_enabled = Activé |
||||
config.mailer_name = Nom |
||||
config.mailer_host = Serveur |
||||
config.mailer_user = Usager |
||||
config.oauth_config = Configuration OAuth |
||||
config.oauth_enabled = Activé |
||||
config.cache_config = Configuration du cache |
||||
config.cache_adapter = Mécanisme de cache |
||||
config.cache_interval = Intervalle |
||||
config.cache_conn = Chaîne de connexion |
||||
config.session_config = Configuration des session |
||||
config.session_provider = Mécanisme |
||||
config.provider_config = Configuration du mécanisme |
||||
config.cookie_name = Nom du fichier témoin |
||||
config.enable_set_cookie = Fichier témoin actvité |
||||
config.gc_interval_time = Intervalle GC |
||||
config.session_life_time = Durée de la session |
||||
config.https_only = HTTPS exigé |
||||
config.cookie_life_time = Expiration du fichier témoin |
||||
config.session_hash_function = Fonction de hashage ID de session |
||||
config.session_hash_key = Clé de hashage ID de session |
||||
config.picture_config = Configuration des avatars |
||||
config.picture_service = Service image |
||||
config.disable_gravatar = Désactivé Gravatar |
||||
config.log_config = Configuration du journal |
||||
config.log_mode = Mode de journal |
||||
|
||||
monitor.cron = Cron Tasks |
||||
monitor.name = Name |
||||
monitor.schedule = Schedule |
||||
monitor.next = Next Time |
||||
monitor.previous = Previous Time |
||||
monitor.execute_times = Execute Times |
||||
monitor.process = Running Processes |
||||
monitor.desc = Description |
||||
monitor.start = Start Time |
||||
monitor.execute_time = Execution Time |
||||
|
||||
[action] |
||||
create_repo = a créé le dépôt <a href="/%s">%s</a> |
||||
commit_repo = a poussé sur <a href="/%s/src/%s">%s</a> à <a href="/%s">%s</a> |
||||
create_issue = a ouvert le ticket <a href="/%s/issues/%s">%s#%s</a> |
||||
comment_issue = a commenté sur le ticket <a href="/%s/issues/%s">%s#%s</a> |
||||
|
||||
[tool] |
||||
ago = auparavant |
||||
from_now = depuis |
||||
now = maintenant |
||||
1s = 1 seconde %s |
||||
1m = 1 minute %s |
||||
1h = 1 heure %s |
||||
1d = 1 jour %s |
||||
1w = 1 semaine %s |
||||
1mon = 1 mos %s |
||||
1y = 1 an %s |
||||
seconds = %d secondes %s |
||||
minutes = %d minutes %s |
||||
hours = %d heures %s |
||||
days = %d jours %s |
||||
weeks = %d semaines %s |
||||
months = %d mois %s |
||||
years = %d années %s |
||||
raw_seconds = secondes |
||||
raw_minutes = minutes |
@ -0,0 +1,89 @@
|
||||
Docker |
||||
====== |
||||
|
||||
TOOLS ARE WRITTEN FOR TESTING AND TO SEE WHAT IT IS! |
||||
|
||||
For this to work you will need the nifty docker tool [fig]. |
||||
|
||||
The most simple setup will look like this: |
||||
|
||||
```sh |
||||
./assemble_blocks.sh docker_gogs w_db option_db_mysql |
||||
fig up |
||||
|
||||
``` |
||||
|
||||
That's it. You have GoGS running in docker linked to a MySQL docker container. |
||||
|
||||
Now visit http://localhost:3000/ and give details for the admin account an you're up and running. |
||||
|
||||
|
||||
How does it work |
||||
---------------- |
||||
|
||||
`./assemble_blocks.sh` will look in `blocks` for subdirectories. |
||||
In the subdirectories there are three relevant files: `Dockerfile`, `config` and `fig`. |
||||
|
||||
`Dockerfile` will be copied to `docker/` (also means last `Dockerfile` wins). |
||||
|
||||
The `config` file contains lines which will in the gogs docker container end up in `$GOGS_PATH/custom/config/app.ini` and by this gogs will be configured. |
||||
Here you can define things like the MySQL server for your database block. |
||||
|
||||
The `fig` file will just be added to `fig.yml`, which is used by fig to manage your containers. |
||||
This inculdes container linking! |
||||
|
||||
Just have a look at them and it will be clear how to write your own blocks. |
||||
|
||||
Just some things |
||||
|
||||
- all files (`Dockerfile`, `fig` and `config`) are optional |
||||
- the gogs block should always be the first block |
||||
|
||||
Currently the blocks are designed that, the blocks that start with `docker` pull in the base docker image. |
||||
Then one block starting with `w` defines, what containers should be linked to the gogs container. |
||||
For every option in the `w` block you need to add an `option` container. |
||||
|
||||
Example: |
||||
|
||||
```sh |
||||
./assemble_blocks.sh docker_gogs w_db_cache option_db_mysql option_cache_redis |
||||
``` |
||||
|
||||
|
||||
More sophisticated Example |
||||
-------------------------- |
||||
|
||||
Her is a more elaborated example |
||||
|
||||
```sh |
||||
./assemble_blocks.sh docker_gogs w_db_cache_session option_db_postgresql option_cache_redis option_session_mysql |
||||
fig up |
||||
``` |
||||
|
||||
This will set up four containters and link them proberly. One for each of |
||||
|
||||
- gogs |
||||
- database (postgresql) |
||||
- cache (redis) |
||||
- session (mysql) |
||||
|
||||
WARNING: This will not work at the Moment! MySQL session is broken! |
||||
|
||||
|
||||
Remark |
||||
------ |
||||
|
||||
After you execute `assemble_blocks.sh` you should always trigger `fig build` to inculde the the new init script `init_gogs.sh` in the docker image. |
||||
|
||||
If you want to use another GoGS docker file, but keep everything else the same, you can create a block, e.g. `docker_gogs_custom`, with only a `Dockerfile` and call |
||||
|
||||
```sh |
||||
./assemble_blocks.sh docker_gogs_custom w_db option_database_mysql |
||||
``` |
||||
|
||||
This will pull in the `Dockerfile` from `docker_gogs` instead of the one from `docker_gogs`. |
||||
|
||||
`Dockerfile`s for the `master` and `dev` branch are provided as `docker_gogs` and `docker_gogs_dev` |
||||
|
||||
|
||||
[fig]:http://www.fig.sh/ |
@ -0,0 +1,72 @@
|
||||
#!/bin/bash |
||||
|
||||
blocks_dir=blocks |
||||
docker_dir=docker |
||||
template_dir=templates |
||||
|
||||
docker_file=Dockerfile |
||||
|
||||
gogs_config_file=conf.tmp |
||||
gogs_config=config |
||||
gogs_init_file=$docker_dir/init_gogs.sh |
||||
|
||||
fig_file=fig.yml |
||||
fig_config=fig |
||||
|
||||
gogs_init_template=$template_dir/init_gogs.sh.tpl |
||||
|
||||
if [ "$#" == 0 ]; then |
||||
blocks=`ls $blocks_dir` |
||||
if [ -z "$blocks" ]; then |
||||
echo "No Blocks available in $blocks_dir" |
||||
else |
||||
echo "Available Blocks:" |
||||
for block in $blocks; do |
||||
echo " $block" |
||||
done |
||||
fi |
||||
exit 0 |
||||
fi |
||||
|
||||
for file in $gogs_config_file $fig_file; do |
||||
if [ -e $file ]; then |
||||
echo "Deleting $file" |
||||
rm $file |
||||
fi |
||||
done |
||||
|
||||
for dir in $@; do |
||||
current_dir=$blocks_dir/$dir |
||||
if [ ! -d "$current_dir" ]; then |
||||
echo "$current_dir is not a directory" |
||||
exit 1 |
||||
fi |
||||
|
||||
if [ -e $current_dir/$docker_file ]; then |
||||
echo "Copying $current_dir/$docker_file to $docker_dir/$docker_file" |
||||
cp $current_dir/$docker_file $docker_dir/$docker_file |
||||
fi |
||||
|
||||
if [ -e $current_dir/$gogs_config ]; then |
||||
echo "Adding $current_dir/$gogs_config to $gogs_config_file" |
||||
cat $current_dir/$gogs_config >> $gogs_config_file |
||||
echo "" >> $gogs_config_file |
||||
fi |
||||
|
||||
if [ -e $current_dir/$fig_config ]; then |
||||
echo "Adding $current_dir/$fig_config to $fig_file" |
||||
cat $current_dir/fig >> $fig_file |
||||
echo "" >> $fig_file |
||||
fi |
||||
done |
||||
|
||||
echo "Creating $gogs_init_file" |
||||
sed "/{{ CONFIG }}/{ |
||||
r $gogs_config_file |
||||
d |
||||
}" $gogs_init_template > $gogs_init_file |
||||
|
||||
if [ -e $gogs_config_file ]; then |
||||
echo "Removing temporary GoGS config" |
||||
rm $gogs_config_file |
||||
fi |
@ -0,0 +1,52 @@
|
||||
FROM ubuntu:14.04 |
||||
|
||||
# This part is taken from the official docker image -------------------- |
||||
|
||||
RUN apt-get update && apt-get install -y \ |
||||
build-essential ca-certificates curl \ |
||||
bzr git mercurial \ |
||||
--no-install-recommends |
||||
|
||||
ENV GOLANG_VERSION 1.3 |
||||
|
||||
RUN curl -sSL http://golang.org/dl/go$GOLANG_VERSION.src.tar.gz \ |
||||
| tar -v -C /usr/src -xz |
||||
WORKDIR /usr/src/go |
||||
|
||||
RUN cd src && ./make.bash --no-clean 2>&1 |
||||
|
||||
ENV PATH /usr/src/go/bin:$PATH |
||||
|
||||
RUN mkdir -p /go/src |
||||
ENV GOPATH /go |
||||
ENV PATH /go/bin:$PATH |
||||
WORKDIR /go |
||||
|
||||
# ---------------------------------------------------------------------- |
||||
|
||||
|
||||
RUN useradd -m git |
||||
|
||||
ENV GOGS_PATH $GOPATH/src/github.com/gogits/gogs |
||||
ENV GOGS_CUSTOM_CONF_PATH $GOGS_PATH/custom/conf |
||||
ENV GOGS_CUSTOM_CONF $GOGS_CUSTOM_CONF_PATH/app.ini |
||||
|
||||
RUN go get -u -d github.com/gogits/gogs |
||||
# WORKDIR $GOGS_PATH |
||||
WORKDIR /go/src/github.com/gogits/gogs |
||||
RUN go build github.com/gogits/gogs |
||||
RUN chown -R git $GOGS_PATH |
||||
|
||||
ADD init_gogs.sh /tmp/ |
||||
RUN chown git /tmp/init_gogs.sh |
||||
RUN chmod +x /tmp/init_gogs.sh |
||||
|
||||
USER git |
||||
ENV HOME /home/git |
||||
ENV USER git |
||||
ENV PATH $GOGS_PATH:$PATH |
||||
|
||||
RUN git config --global user.name "GoGS" |
||||
|
||||
ENTRYPOINT ["/tmp/init_gogs.sh"] |
||||
CMD ["gogs", "web"] |
@ -0,0 +1,53 @@
|
||||
FROM ubuntu:14.04 |
||||
|
||||
# This part is derived from the official docker image ------------------ |
||||
|
||||
RUN DEBIAN_FRONTEND=noninteractive apt-get update && \ |
||||
apt-get install -qy \ |
||||
build-essential ca-certificates curl \ |
||||
bzr git mercurial \ |
||||
--no-install-recommends |
||||
|
||||
ENV GOLANG_VERSION 1.3 |
||||
|
||||
RUN curl -sSL http://golang.org/dl/go$GOLANG_VERSION.src.tar.gz \ |
||||
| tar -v -C /usr/src -xz |
||||
WORKDIR /usr/src/go |
||||
|
||||
RUN cd src && ./make.bash --no-clean 2>&1 |
||||
|
||||
ENV PATH /usr/src/go/bin:$PATH |
||||
|
||||
RUN mkdir -p /go/src |
||||
ENV GOPATH /go |
||||
ENV PATH /go/bin:$PATH |
||||
WORKDIR /go |
||||
|
||||
# ---------------------------------------------------------------------- |
||||
|
||||
|
||||
RUN useradd -m git |
||||
|
||||
ENV GOGS_PATH $GOPATH/src/github.com/gogits/gogs |
||||
ENV GOGS_CUSTOM_CONF_PATH $GOGS_PATH/custom/conf |
||||
ENV GOGS_CUSTOM_CONF $GOGS_CUSTOM_CONF_PATH/app.ini |
||||
|
||||
RUN git clone -b dev https://github.com/gogits/gogs.git $GOGS_PATH |
||||
# WORKDIR $GOGS_PATH |
||||
WORKDIR /go/src/github.com/gogits/gogs |
||||
RUN go get -d && go build |
||||
RUN chown -R git $GOGS_PATH |
||||
|
||||
ADD init_gogs.sh /tmp/ |
||||
RUN chown git /tmp/init_gogs.sh |
||||
RUN chmod +x /tmp/init_gogs.sh |
||||
|
||||
USER git |
||||
ENV HOME /home/git |
||||
ENV USER git |
||||
ENV PATH $GOGS_PATH:$PATH |
||||
|
||||
RUN git config --global user.name "GoGS" |
||||
|
||||
ENTRYPOINT ["/tmp/init_gogs.sh"] |
||||
CMD ["gogs", "web"] |
@ -0,0 +1,3 @@
|
||||
[cache] |
||||
DB_TYPE = memcache |
||||
HOST = HOST = ${CACHE_1_PORT_11211_TCP_ADDR}:${CACHE_1_PORT_11211_TCP_PORT} |
@ -0,0 +1,2 @@
|
||||
cache: |
||||
image: sylvainlasnier/memcached:latest |
@ -0,0 +1,3 @@
|
||||
[cache] |
||||
DB_TYPE = redis |
||||
HOST = ${CACHE_1_PORT_6379_TCP_ADDR}:${CACHE_1_PORT_6379_TCP_PORT} |
@ -0,0 +1,6 @@
|
||||
[database] |
||||
DB_TYPE = mysql |
||||
HOST = ${DB_1_PORT_3306_TCP_ADDR}:${DB_1_PORT_3306_TCP_PORT} |
||||
NAME = ${DB_1_ENV_MYSQL_DATABASE} |
||||
USER = ${DB_1_ENV_MYSQL_USER} |
||||
PASSWD = ${DB_1_ENV_MYSQL_PASSWORD} |
@ -0,0 +1,7 @@
|
||||
db: |
||||
image: mysql:latest |
||||
environment: |
||||
MYSQL_ROOT_PASSWORD: rootpass |
||||
MYSQL_DATABASE: gogs |
||||
MYSQL_USER: gogs |
||||
MYSQL_PASSWORD: password |
@ -0,0 +1,6 @@
|
||||
[database] |
||||
DB_TYPE = postgres |
||||
HOST = ${DB_1_PORT_5432_TCP_ADDR}:${DB_1_PORT_5432_TCP_PORT} |
||||
NAME = ${DB_1_ENV_POSTGRESQL_DB} |
||||
USER = ${DB_1_ENV_POSTGRESQL_USER} |
||||
PASSWD = ${DB_1_ENV_POSTGRESQL_PASS} |
@ -0,0 +1,6 @@
|
||||
db: |
||||
image: wyaeld/postgres:9.3 |
||||
environment: |
||||
POSTGRESQL_DB: gogs |
||||
POSTGRESQL_USER: gogs |
||||
POSTGRESQL_PASS: password |
@ -0,0 +1,3 @@
|
||||
[session] |
||||
PROVIDER = mysql |
||||
PROVIDER_CONFIG = ${SESSION_1_ENV_MYSQL_USER}:${SESSION_1_ENV_MYSQL_PASSWORD}@SESSION_1_PORT_3306_TCP_PROTO(${SESSION_1_PORT_3306_TCP_ADDR}:${SESSION_1_PORT_3306_TCP_PORT})/${SESSION_1_ENV_MYSQL_DATABASE} |
@ -0,0 +1,7 @@
|
||||
session: |
||||
image: mysql:latest |
||||
environment: |
||||
MYSQL_ROOT_PASSWORD: rootpass |
||||
MYSQL_DATABASE: gogs_session |
||||
MYSQL_USER: gogs |
||||
MYSQL_PASSWORD: password |
@ -0,0 +1,6 @@
|
||||
gogs: |
||||
build: docker |
||||
links: |
||||
- cache |
||||
ports: |
||||
- "3000:3000" |
@ -0,0 +1,7 @@
|
||||
gogs: |
||||
build: docker |
||||
links: |
||||
- cache |
||||
- session |
||||
ports: |
||||
- "3000:3000" |
@ -0,0 +1,6 @@
|
||||
gogs: |
||||
build: docker |
||||
links: |
||||
- db |
||||
ports: |
||||
- "3000:3000" |
@ -0,0 +1,7 @@
|
||||
gogs: |
||||
build: docker |
||||
links: |
||||
- db |
||||
- cache |
||||
ports: |
||||
- "3000:3000" |
@ -0,0 +1,8 @@
|
||||
gogs: |
||||
build: docker |
||||
links: |
||||
- db |
||||
- cache |
||||
- session |
||||
ports: |
||||
- "3000:3000" |
@ -0,0 +1,7 @@
|
||||
gogs: |
||||
build: docker |
||||
links: |
||||
- db |
||||
- session |
||||
ports: |
||||
- "3000:3000" |
@ -0,0 +1,4 @@
|
||||
gogs: |
||||
build: docker |
||||
ports: |
||||
- "3000:3000" |
@ -0,0 +1,6 @@
|
||||
gogs: |
||||
build: docker |
||||
links: |
||||
- session |
||||
ports: |
||||
- "3000:3000" |
@ -0,0 +1,12 @@
|
||||
#!/bin/sh |
||||
|
||||
if [ ! -d "$DIRECTORY" ]; then |
||||
mkdir -p $GOGS_CUSTOM_CONF_PATH |
||||
|
||||
echo " |
||||
{{ CONFIG }} |
||||
" >> $GOGS_CUSTOM_CONF |
||||
|
||||
fi |
||||
|
||||
exec "$@" |
@ -1,40 +0,0 @@
|
||||
### Install Gogs With Docker |
||||
|
||||
Deploying gogs in [Docker](http://www.docker.io/) is just as easy as eating a pie, what you do is just open the `dockerfiles/build.sh` file, replace the configs: |
||||
|
||||
``` |
||||
DB_TYPE="YOUR_DB_TYPE" # type of database, support 'mysql' and 'postgres' |
||||
MEM_TYPE="YOUR_MEM_TYPE" # type of memory database, support 'redis' and 'memcache' |
||||
DB_PASSWORD="YOUR_DB_PASSWORD" # The database password. |
||||
DB_RUN_NAME="YOUR_DB_RUN_NAME" # The --name option value when run the database image. |
||||
MEM_RUN_NAME="YOUR_MEM_RUN_NAME" # The --name option value when run the mem database image. |
||||
HOST_PORT="YOUR_HOST_PORT" # The port on host, which will be redirected to the port 3000 inside gogs container. |
||||
``` |
||||
|
||||
And run: |
||||
``` |
||||
cd dockerfiles |
||||
./build.sh |
||||
``` |
||||
|
||||
The build might take some time, just be patient. After it finishes, you will receive the message: |
||||
|
||||
``` |
||||
Now we have the MySQL image(running) and gogs image, use the follow command to start gogs service( the content might be different, according to your own configs): |
||||
docker run -i -t --link YOUR_DB_RUN_NAME:db --link YOUR_MEM_RUN_NAME:mem -p YOUR_HOST_PORT:3000 gogits/gogs |
||||
``` |
||||
|
||||
Just follow the message, run: |
||||
|
||||
``` |
||||
docker run -i -t --link YOUR_DB_RUN_NAME:db --link YOUR_MEM_RUN_NAME:mem -p YOUR_HOST_PORT:3000 gogits/gogs |
||||
``` |
||||
|
||||
Now we have gogs running! Open the browser and navigate to: |
||||
|
||||
``` |
||||
http://YOUR_HOST_IP:YOUR_HOST_PORT |
||||
``` |
||||
|
||||
Let's 'gogs'! |
||||
Ouya~ |
@ -0,0 +1,125 @@
|
||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package models |
||||
|
||||
import ( |
||||
"encoding/json" |
||||
"errors" |
||||
"fmt" |
||||
"strings" |
||||
) |
||||
|
||||
const ( |
||||
SLACK_COLOR string = "#dd4b39" |
||||
) |
||||
|
||||
type Slack struct { |
||||
Domain string `json:"domain"` |
||||
Token string `json:"token"` |
||||
Channel string `json:"channel"` |
||||
} |
||||
|
||||
type SlackPayload struct { |
||||
Channel string `json:"channel"` |
||||
Text string `json:"text"` |
||||
Username string `json:"username"` |
||||
IconUrl string `json:"icon_url"` |
||||
UnfurlLinks int `json:"unfurl_links"` |
||||
LinkNames int `json:"link_names"` |
||||
Attachments []SlackAttachment `json:"attachments"` |
||||
} |
||||
|
||||
type SlackAttachment struct { |
||||
Color string `json:"color"` |
||||
Text string `json:"text"` |
||||
} |
||||
|
||||
func GetSlackURL(domain string, token string) string { |
||||
return fmt.Sprintf( |
||||
"https://%s.slack.com/services/hooks/incoming-webhook?token=%s", |
||||
domain, |
||||
token, |
||||
) |
||||
} |
||||
|
||||
func (p SlackPayload) GetJSONPayload() ([]byte, error) { |
||||
data, err := json.Marshal(p) |
||||
if err != nil { |
||||
return []byte{}, err |
||||
} |
||||
return data, nil |
||||
} |
||||
|
||||
func GetSlackPayload(p *Payload, meta string) (*SlackPayload, error) { |
||||
slack := &Slack{} |
||||
slackPayload := &SlackPayload{} |
||||
if err := json.Unmarshal([]byte(meta), &slack); err != nil { |
||||
return slackPayload, errors.New("GetSlackPayload meta json:" + err.Error()) |
||||
} |
||||
|
||||
// TODO: handle different payload types: push, new branch, delete branch etc.
|
||||
// when they are added to gogs. Only handles push now
|
||||
return getSlackPushPayload(p, slack) |
||||
} |
||||
|
||||
func getSlackPushPayload(p *Payload, slack *Slack) (*SlackPayload, error) { |
||||
// n new commits
|
||||
refSplit := strings.Split(p.Ref, "/") |
||||
branchName := refSplit[len(refSplit)-1] |
||||
var commitString string |
||||
|
||||
if len(p.Commits) == 1 { |
||||
commitString = "1 new commit" |
||||
if p.CompareUrl != "" { |
||||
commitString = SlackLinkFormatter(p.CompareUrl, commitString) |
||||
} |
||||
} else { |
||||
commitString = fmt.Sprintf("%d new commits", len(p.Commits)) |
||||
if p.CompareUrl != "" { |
||||
commitString = SlackLinkFormatter(p.CompareUrl, commitString) |
||||
} |
||||
} |
||||
|
||||
repoLink := SlackLinkFormatter(p.Repo.Url, p.Repo.Name) |
||||
branchLink := SlackLinkFormatter(p.Repo.Url+"/src/"+branchName, branchName) |
||||
text := fmt.Sprintf("[%s:%s] %s pushed by %s", repoLink, branchLink, commitString, p.Pusher.Name) |
||||
var attachmentText string |
||||
|
||||
// for each commit, generate attachment text
|
||||
for i, commit := range p.Commits { |
||||
attachmentText += fmt.Sprintf("%s: %s - %s", SlackLinkFormatter(commit.Url, commit.Id[:7]), SlackTextFormatter(commit.Message), SlackTextFormatter(commit.Author.Name)) |
||||
// add linebreak to each commit but the last
|
||||
if i < len(p.Commits)-1 { |
||||
attachmentText += "\n" |
||||
} |
||||
} |
||||
|
||||
slackAttachments := []SlackAttachment{{Color: SLACK_COLOR, Text: attachmentText}} |
||||
|
||||
return &SlackPayload{ |
||||
Channel: slack.Channel, |
||||
Text: text, |
||||
Username: "gogs", |
||||
IconUrl: "https://raw.githubusercontent.com/gogits/gogs/master/public/img/favicon.png", |
||||
UnfurlLinks: 0, |
||||
LinkNames: 0, |
||||
Attachments: slackAttachments, |
||||
}, nil |
||||
} |
||||
|
||||
// see: https://api.slack.com/docs/formatting
|
||||
func SlackTextFormatter(s string) string { |
||||
// take only first line of commit
|
||||
first := strings.Split(s, "\n")[0] |
||||
// replace & < >
|
||||
first = strings.Replace(first, "&", "&", -1) |
||||
first = strings.Replace(first, "<", "<", -1) |
||||
first = strings.Replace(first, ">", ">", -1) |
||||
return first |
||||
} |
||||
|
||||
func SlackLinkFormatter(url string, text string) string { |
||||
return fmt.Sprintf("<%s|%s>", url, SlackTextFormatter(text)) |
||||
} |
@ -0,0 +1,27 @@
|
||||
Copyright (c) 2012 The Go Authors. All rights reserved. |
||||
|
||||
Redistribution and use in source and binary forms, with or without |
||||
modification, are permitted provided that the following conditions are |
||||
met: |
||||
|
||||
* Redistributions of source code must retain the above copyright |
||||
notice, this list of conditions and the following disclaimer. |
||||
* Redistributions in binary form must reproduce the above |
||||
copyright notice, this list of conditions and the following disclaimer |
||||
in the documentation and/or other materials provided with the |
||||
distribution. |
||||
* Neither the name of Google Inc. nor the names of its |
||||
contributors may be used to endorse or promote products derived from |
||||
this software without specific prior written permission. |
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
@ -0,0 +1,11 @@
|
||||
# Copyright 2009 The Go Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
include $(GOROOT)/src/Make.inc |
||||
|
||||
TARG=github.com/mmitton/asn1-ber
|
||||
GOFILES=\
|
||||
ber.go\
|
||||
|
||||
include $(GOROOT)/src/Make.pkg |
@ -0,0 +1,14 @@
|
||||
ASN1 BER Encoding / Decoding Library for the GO programming language. |
||||
|
||||
Required Librarys: |
||||
None |
||||
|
||||
Working: |
||||
Very basic encoding / decoding needed for LDAP protocol |
||||
|
||||
Tests Implemented: |
||||
None |
||||
|
||||
TODO: |
||||
Fix all encoding / decoding to conform to ASN1 BER spec |
||||
Implement Tests / Benchmarks |
@ -0,0 +1,492 @@
|
||||
package ber |
||||
|
||||
import ( |
||||
"bytes" |
||||
"fmt" |
||||
"io" |
||||
"reflect" |
||||
) |
||||
|
||||
type Packet struct { |
||||
ClassType uint8 |
||||
TagType uint8 |
||||
Tag uint8 |
||||
Value interface{} |
||||
ByteValue []byte |
||||
Data *bytes.Buffer |
||||
Children []*Packet |
||||
Description string |
||||
} |
||||
|
||||
const ( |
||||
TagEOC = 0x00 |
||||
TagBoolean = 0x01 |
||||
TagInteger = 0x02 |
||||
TagBitString = 0x03 |
||||
TagOctetString = 0x04 |
||||
TagNULL = 0x05 |
||||
TagObjectIdentifier = 0x06 |
||||
TagObjectDescriptor = 0x07 |
||||
TagExternal = 0x08 |
||||
TagRealFloat = 0x09 |
||||
TagEnumerated = 0x0a |
||||
TagEmbeddedPDV = 0x0b |
||||
TagUTF8String = 0x0c |
||||
TagRelativeOID = 0x0d |
||||
TagSequence = 0x10 |
||||
TagSet = 0x11 |
||||
TagNumericString = 0x12 |
||||
TagPrintableString = 0x13 |
||||
TagT61String = 0x14 |
||||
TagVideotexString = 0x15 |
||||
TagIA5String = 0x16 |
||||
TagUTCTime = 0x17 |
||||
TagGeneralizedTime = 0x18 |
||||
TagGraphicString = 0x19 |
||||
TagVisibleString = 0x1a |
||||
TagGeneralString = 0x1b |
||||
TagUniversalString = 0x1c |
||||
TagCharacterString = 0x1d |
||||
TagBMPString = 0x1e |
||||
TagBitmask = 0x1f // xxx11111b
|
||||
) |
||||
|
||||
var TagMap = map[uint8]string{ |
||||
TagEOC: "EOC (End-of-Content)", |
||||
TagBoolean: "Boolean", |
||||
TagInteger: "Integer", |
||||
TagBitString: "Bit String", |
||||
TagOctetString: "Octet String", |
||||
TagNULL: "NULL", |
||||
TagObjectIdentifier: "Object Identifier", |
||||
TagObjectDescriptor: "Object Descriptor", |
||||
TagExternal: "External", |
||||
TagRealFloat: "Real (float)", |
||||
TagEnumerated: "Enumerated", |
||||
TagEmbeddedPDV: "Embedded PDV", |
||||
TagUTF8String: "UTF8 String", |
||||
TagRelativeOID: "Relative-OID", |
||||
TagSequence: "Sequence and Sequence of", |
||||
TagSet: "Set and Set OF", |
||||
TagNumericString: "Numeric String", |
||||
TagPrintableString: "Printable String", |
||||
TagT61String: "T61 String", |
||||
TagVideotexString: "Videotex String", |
||||
TagIA5String: "IA5 String", |
||||
TagUTCTime: "UTC Time", |
||||
TagGeneralizedTime: "Generalized Time", |
||||
TagGraphicString: "Graphic String", |
||||
TagVisibleString: "Visible String", |
||||
TagGeneralString: "General String", |
||||
TagUniversalString: "Universal String", |
||||
TagCharacterString: "Character String", |
||||
TagBMPString: "BMP String", |
||||
} |
||||
|
||||
const ( |
||||
ClassUniversal = 0 // 00xxxxxxb
|
||||
ClassApplication = 64 // 01xxxxxxb
|
||||
ClassContext = 128 // 10xxxxxxb
|
||||
ClassPrivate = 192 // 11xxxxxxb
|
||||
ClassBitmask = 192 // 11xxxxxxb
|
||||
) |
||||
|
||||
var ClassMap = map[uint8]string{ |
||||
ClassUniversal: "Universal", |
||||
ClassApplication: "Application", |
||||
ClassContext: "Context", |
||||
ClassPrivate: "Private", |
||||
} |
||||
|
||||
const ( |
||||
TypePrimitive = 0 // xx0xxxxxb
|
||||
TypeConstructed = 32 // xx1xxxxxb
|
||||
TypeBitmask = 32 // xx1xxxxxb
|
||||
) |
||||
|
||||
var TypeMap = map[uint8]string{ |
||||
TypePrimitive: "Primative", |
||||
TypeConstructed: "Constructed", |
||||
} |
||||
|
||||
var Debug bool = false |
||||
|
||||
func PrintBytes(buf []byte, indent string) { |
||||
data_lines := make([]string, (len(buf)/30)+1) |
||||
num_lines := make([]string, (len(buf)/30)+1) |
||||
|
||||
for i, b := range buf { |
||||
data_lines[i/30] += fmt.Sprintf("%02x ", b) |
||||
num_lines[i/30] += fmt.Sprintf("%02d ", (i+1)%100) |
||||
} |
||||
|
||||
for i := 0; i < len(data_lines); i++ { |
||||
fmt.Print(indent + data_lines[i] + "\n") |
||||
fmt.Print(indent + num_lines[i] + "\n\n") |
||||
} |
||||
} |
||||
|
||||
func PrintPacket(p *Packet) { |
||||
printPacket(p, 0, false) |
||||
} |
||||
|
||||
func printPacket(p *Packet, indent int, printBytes bool) { |
||||
indent_str := "" |
||||
|
||||
for len(indent_str) != indent { |
||||
indent_str += " " |
||||
} |
||||
|
||||
class_str := ClassMap[p.ClassType] |
||||
|
||||
tagtype_str := TypeMap[p.TagType] |
||||
|
||||
tag_str := fmt.Sprintf("0x%02X", p.Tag) |
||||
|
||||
if p.ClassType == ClassUniversal { |
||||
tag_str = TagMap[p.Tag] |
||||
} |
||||
|
||||
value := fmt.Sprint(p.Value) |
||||
description := "" |
||||
|
||||
if p.Description != "" { |
||||
description = p.Description + ": " |
||||
} |
||||
|
||||
fmt.Printf("%s%s(%s, %s, %s) Len=%d %q\n", indent_str, description, class_str, tagtype_str, tag_str, p.Data.Len(), value) |
||||
|
||||
if printBytes { |
||||
PrintBytes(p.Bytes(), indent_str) |
||||
} |
||||
|
||||
for _, child := range p.Children { |
||||
printPacket(child, indent+1, printBytes) |
||||
} |
||||
} |
||||
|
||||
func resizeBuffer(in []byte, new_size uint64) (out []byte) { |
||||
out = make([]byte, new_size) |
||||
|
||||
copy(out, in) |
||||
|
||||
return |
||||
} |
||||
|
||||
func readBytes(reader io.Reader, buf []byte) error { |
||||
idx := 0 |
||||
buflen := len(buf) |
||||
|
||||
for idx < buflen { |
||||
n, err := reader.Read(buf[idx:]) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
idx += n |
||||
} |
||||
|
||||
return nil |
||||
} |
||||
|
||||
func ReadPacket(reader io.Reader) (*Packet, error) { |
||||
buf := make([]byte, 2) |
||||
|
||||
err := readBytes(reader, buf) |
||||
|
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
idx := uint64(2) |
||||
datalen := uint64(buf[1]) |
||||
|
||||
if Debug { |
||||
fmt.Printf("Read: datalen = %d len(buf) = %d ", datalen, len(buf)) |
||||
|
||||
for _, b := range buf { |
||||
fmt.Printf("%02X ", b) |
||||
} |
||||
|
||||
fmt.Printf("\n") |
||||
} |
||||
|
||||
if datalen&128 != 0 { |
||||
a := datalen - 128 |
||||
|
||||
idx += a |
||||
buf = resizeBuffer(buf, 2+a) |
||||
|
||||
err := readBytes(reader, buf[2:]) |
||||
|
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
datalen = DecodeInteger(buf[2 : 2+a]) |
||||
|
||||
if Debug { |
||||
fmt.Printf("Read: a = %d idx = %d datalen = %d len(buf) = %d", a, idx, datalen, len(buf)) |
||||
|
||||
for _, b := range buf { |
||||
fmt.Printf("%02X ", b) |
||||
} |
||||
|
||||
fmt.Printf("\n") |
||||
} |
||||
} |
||||
|
||||
buf = resizeBuffer(buf, idx+datalen) |
||||
err = readBytes(reader, buf[idx:]) |
||||
|
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
if Debug { |
||||
fmt.Printf("Read: len( buf ) = %d idx=%d datalen=%d idx+datalen=%d\n", len(buf), idx, datalen, idx+datalen) |
||||
|
||||
for _, b := range buf { |
||||
fmt.Printf("%02X ", b) |
||||
} |
||||
} |
||||
|
||||
p := DecodePacket(buf) |
||||
|
||||
return p, nil |
||||
} |
||||
|
||||
func DecodeString(data []byte) (ret string) { |
||||
for _, c := range data { |
||||
ret += fmt.Sprintf("%c", c) |
||||
} |
||||
|
||||
return |
||||
} |
||||
|
||||
func DecodeInteger(data []byte) (ret uint64) { |
||||
for _, i := range data { |
||||
ret = ret * 256 |
||||
ret = ret + uint64(i) |
||||
} |
||||
|
||||
return |
||||
} |
||||
|
||||
func EncodeInteger(val uint64) []byte { |
||||
var out bytes.Buffer |
||||
|
||||
found := false |
||||
|
||||
shift := uint(56) |
||||
|
||||
mask := uint64(0xFF00000000000000) |
||||
|
||||
for mask > 0 { |
||||
if !found && (val&mask != 0) { |
||||
found = true |
||||
} |
||||
|
||||
if found || (shift == 0) { |
||||
out.Write([]byte{byte((val & mask) >> shift)}) |
||||
} |
||||
|
||||
shift -= 8 |
||||
mask = mask >> 8 |
||||
} |
||||
|
||||
return out.Bytes() |
||||
} |
||||
|
||||
func DecodePacket(data []byte) *Packet { |
||||
p, _ := decodePacket(data) |
||||
|
||||
return p |
||||
} |
||||
|
||||
func decodePacket(data []byte) (*Packet, []byte) { |
||||
if Debug { |
||||
fmt.Printf("decodePacket: enter %d\n", len(data)) |
||||
} |
||||
|
||||
p := new(Packet) |
||||
|
||||
p.ClassType = data[0] & ClassBitmask |
||||
p.TagType = data[0] & TypeBitmask |
||||
p.Tag = data[0] & TagBitmask |
||||
|
||||
datalen := DecodeInteger(data[1:2]) |
||||
datapos := uint64(2) |
||||
|
||||
if datalen&128 != 0 { |
||||
datalen -= 128 |
||||
datapos += datalen |
||||
datalen = DecodeInteger(data[2 : 2+datalen]) |
||||
} |
||||
|
||||
p.Data = new(bytes.Buffer) |
||||
|
||||
p.Children = make([]*Packet, 0, 2) |
||||
|
||||
p.Value = nil |
||||
|
||||
value_data := data[datapos : datapos+datalen] |
||||
|
||||
if p.TagType == TypeConstructed { |
||||
for len(value_data) != 0 { |
||||
var child *Packet |
||||
|
||||
child, value_data = decodePacket(value_data) |
||||
p.AppendChild(child) |
||||
} |
||||
} else if p.ClassType == ClassUniversal { |
||||
p.Data.Write(data[datapos : datapos+datalen]) |
||||
p.ByteValue = value_data |
||||
|
||||
switch p.Tag { |
||||
case TagEOC: |
||||
case TagBoolean: |
||||
val := DecodeInteger(value_data) |
||||
|
||||
p.Value = val != 0 |
||||
case TagInteger: |
||||
p.Value = DecodeInteger(value_data) |
||||
case TagBitString: |
||||
case TagOctetString: |
||||
p.Value = DecodeString(value_data) |
||||
case TagNULL: |
||||
case TagObjectIdentifier: |
||||
case TagObjectDescriptor: |
||||
case TagExternal: |
||||
case TagRealFloat: |
||||
case TagEnumerated: |
||||
p.Value = DecodeInteger(value_data) |
||||
case TagEmbeddedPDV: |
||||
case TagUTF8String: |
||||
case TagRelativeOID: |
||||
case TagSequence: |
||||
case TagSet: |
||||
case TagNumericString: |
||||
case TagPrintableString: |
||||
p.Value = DecodeString(value_data) |
||||
case TagT61String: |
||||
case TagVideotexString: |
||||
case TagIA5String: |
||||
case TagUTCTime: |
||||
case TagGeneralizedTime: |
||||
case TagGraphicString: |
||||
case TagVisibleString: |
||||
case TagGeneralString: |
||||
case TagUniversalString: |
||||
case TagCharacterString: |
||||
case TagBMPString: |
||||
} |
||||
} else { |
||||
p.Data.Write(data[datapos : datapos+datalen]) |
||||
} |
||||
|
||||
return p, data[datapos+datalen:] |
||||
} |
||||
|
||||
func (p *Packet) DataLength() uint64 { |
||||
return uint64(p.Data.Len()) |
||||
} |
||||
|
||||
func (p *Packet) Bytes() []byte { |
||||
var out bytes.Buffer |
||||
|
||||
out.Write([]byte{p.ClassType | p.TagType | p.Tag}) |
||||
packet_length := EncodeInteger(p.DataLength()) |
||||
|
||||
if p.DataLength() > 127 || len(packet_length) > 1 { |
||||
out.Write([]byte{byte(len(packet_length) | 128)}) |
||||
out.Write(packet_length) |
||||
} else { |
||||
out.Write(packet_length) |
||||
} |
||||
|
||||
out.Write(p.Data.Bytes()) |
||||
|
||||
return out.Bytes() |
||||
} |
||||
|
||||
func (p *Packet) AppendChild(child *Packet) { |
||||
p.Data.Write(child.Bytes()) |
||||
|
||||
if len(p.Children) == cap(p.Children) { |
||||
newChildren := make([]*Packet, cap(p.Children)*2) |
||||
|
||||
copy(newChildren, p.Children) |
||||
p.Children = newChildren[0:len(p.Children)] |
||||
} |
||||
|
||||
p.Children = p.Children[0 : len(p.Children)+1] |
||||
p.Children[len(p.Children)-1] = child |
||||
} |
||||
|
||||
func Encode(ClassType, TagType, Tag uint8, Value interface{}, Description string) *Packet { |
||||
p := new(Packet) |
||||
|
||||
p.ClassType = ClassType |
||||
p.TagType = TagType |
||||
p.Tag = Tag |
||||
p.Data = new(bytes.Buffer) |
||||
|
||||
p.Children = make([]*Packet, 0, 2) |
||||
|
||||
p.Value = Value |
||||
p.Description = Description |
||||
|
||||
if Value != nil { |
||||
v := reflect.ValueOf(Value) |
||||
|
||||
if ClassType == ClassUniversal { |
||||
switch Tag { |
||||
case TagOctetString: |
||||
sv, ok := v.Interface().(string) |
||||
|
||||
if ok { |
||||
p.Data.Write([]byte(sv)) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
return p |
||||
} |
||||
|
||||
func NewSequence(Description string) *Packet { |
||||
return Encode(ClassUniversal, TypePrimitive, TagSequence, nil, Description) |
||||
} |
||||
|
||||
func NewBoolean(ClassType, TagType, Tag uint8, Value bool, Description string) *Packet { |
||||
intValue := 0 |
||||
|
||||
if Value { |
||||
intValue = 1 |
||||
} |
||||
|
||||
p := Encode(ClassType, TagType, Tag, nil, Description) |
||||
|
||||
p.Value = Value |
||||
p.Data.Write(EncodeInteger(uint64(intValue))) |
||||
|
||||
return p |
||||
} |
||||
|
||||
func NewInteger(ClassType, TagType, Tag uint8, Value uint64, Description string) *Packet { |
||||
p := Encode(ClassType, TagType, Tag, nil, Description) |
||||
|
||||
p.Value = Value |
||||
p.Data.Write(EncodeInteger(Value)) |
||||
|
||||
return p |
||||
} |
||||
|
||||
func NewString(ClassType, TagType, Tag uint8, Value, Description string) *Packet { |
||||
p := Encode(ClassType, TagType, Tag, nil, Description) |
||||
|
||||
p.Value = Value |
||||
p.Data.Write([]byte(Value)) |
||||
|
||||
return p |
||||
} |
@ -0,0 +1,58 @@
|
||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package git |
||||
|
||||
import ( |
||||
"strings" |
||||
) |
||||
|
||||
type SubModule struct { |
||||
Name string |
||||
Url string |
||||
} |
||||
|
||||
// SubModuleFile represents a file with submodule type.
|
||||
type SubModuleFile struct { |
||||
*Commit |
||||
|
||||
refUrl string |
||||
refId string |
||||
} |
||||
|
||||
func NewSubModuleFile(c *Commit, refUrl, refId string) *SubModuleFile { |
||||
return &SubModuleFile{ |
||||
Commit: c, |
||||
refUrl: refUrl, |
||||
refId: refId, |
||||
} |
||||
} |
||||
|
||||
// RefUrl guesses and returns reference URL.
|
||||
func (sf *SubModuleFile) RefUrl() string { |
||||
url := strings.TrimSuffix(sf.refUrl, ".git") |
||||
|
||||
// git://xxx/user/repo
|
||||
if strings.HasPrefix(url, "git://") { |
||||
return "http://" + strings.TrimPrefix(url, "git://") |
||||
} |
||||
|
||||
// http[s]://xxx/user/repo
|
||||
if strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://") { |
||||
return url |
||||
} |
||||
|
||||
// sysuser@xxx:user/repo
|
||||
i := strings.Index(url, "@") |
||||
j := strings.LastIndex(url, ":") |
||||
if i > -1 && j > -1 { |
||||
return "http://" + url[i+1:j] + "/" + url[j+1:] |
||||
} |
||||
return url |
||||
} |
||||
|
||||
// RefId returns reference ID.
|
||||
func (sf *SubModuleFile) RefId() string { |
||||
return sf.refId |
||||
} |
@ -0,0 +1,27 @@
|
||||
Copyright (c) 2012 The Go Authors. All rights reserved. |
||||
|
||||
Redistribution and use in source and binary forms, with or without |
||||
modification, are permitted provided that the following conditions are |
||||
met: |
||||
|
||||
* Redistributions of source code must retain the above copyright |
||||
notice, this list of conditions and the following disclaimer. |
||||
* Redistributions in binary form must reproduce the above |
||||
copyright notice, this list of conditions and the following disclaimer |
||||
in the documentation and/or other materials provided with the |
||||
distribution. |
||||
* Neither the name of Google Inc. nor the names of its |
||||
contributors may be used to endorse or promote products derived from |
||||
this software without specific prior written permission. |
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
@ -0,0 +1,33 @@
|
||||
Basic LDAP v3 functionality for the GO programming language. |
||||
|
||||
Required Librarys: |
||||
github.com/johnweldon/asn1-ber |
||||
|
||||
Working: |
||||
Connecting to LDAP server |
||||
Binding to LDAP server |
||||
Searching for entries |
||||
Compiling string filters to LDAP filters |
||||
Paging Search Results |
||||
Modify Requests / Responses |
||||
|
||||
Examples: |
||||
search |
||||
modify |
||||
|
||||
Tests Implemented: |
||||
Filter Compile / Decompile |
||||
|
||||
TODO: |
||||
Add Requests / Responses |
||||
Delete Requests / Responses |
||||
Modify DN Requests / Responses |
||||
Compare Requests / Responses |
||||
Implement Tests / Benchmarks |
||||
|
||||
This feature is disabled at the moment, because in some cases the "Search Request Done" packet will be handled before the last "Search Request Entry": |
||||
Mulitple internal goroutines to handle network traffic |
||||
Makes library goroutine safe |
||||
Can perform multiple search requests at the same time and return |
||||
the results to the proper goroutine. All requests are blocking |
||||
requests, so the goroutine does not need special handling |
@ -0,0 +1,63 @@
|
||||
dn: dc=enterprise,dc=org |
||||
objectClass: dcObject |
||||
objectClass: organization |
||||
o: acme |
||||
|
||||
dn: cn=admin,dc=enterprise,dc=org |
||||
objectClass: person |
||||
cn: admin |
||||
sn: admin |
||||
description: "LDAP Admin" |
||||
|
||||
dn: ou=crew,dc=enterprise,dc=org |
||||
ou: crew |
||||
objectClass: organizationalUnit |
||||
|
||||
|
||||
dn: cn=kirkj,ou=crew,dc=enterprise,dc=org |
||||
cn: kirkj |
||||
sn: Kirk |
||||
gn: James Tiberius |
||||
mail: james.kirk@enterprise.org |
||||
objectClass: inetOrgPerson |
||||
|
||||
dn: cn=spock,ou=crew,dc=enterprise,dc=org |
||||
cn: spock |
||||
sn: Spock |
||||
mail: spock@enterprise.org |
||||
objectClass: inetOrgPerson |
||||
|
||||
dn: cn=mccoyl,ou=crew,dc=enterprise,dc=org |
||||
cn: mccoyl |
||||
sn: McCoy |
||||
gn: Leonard |
||||
mail: leonard.mccoy@enterprise.org |
||||
objectClass: inetOrgPerson |
||||
|
||||
dn: cn=scottm,ou=crew,dc=enterprise,dc=org |
||||
cn: scottm |
||||
sn: Scott |
||||
gn: Montgomery |
||||
mail: Montgomery.scott@enterprise.org |
||||
objectClass: inetOrgPerson |
||||
|
||||
dn: cn=uhuran,ou=crew,dc=enterprise,dc=org |
||||
cn: uhuran |
||||
sn: Uhura |
||||
gn: Nyota |
||||
mail: nyota.uhura@enterprise.org |
||||
objectClass: inetOrgPerson |
||||
|
||||
dn: cn=suluh,ou=crew,dc=enterprise,dc=org |
||||
cn: suluh |
||||
sn: Sulu |
||||
gn: Hikaru |
||||
mail: hikaru.sulu@enterprise.org |
||||
objectClass: inetOrgPerson |
||||
|
||||
dn: cn=chekovp,ou=crew,dc=enterprise,dc=org |
||||
cn: chekovp |
||||
sn: Chekov |
||||
gn: pavel |
||||
mail: pavel.chekov@enterprise.org |
||||
objectClass: inetOrgPerson |
@ -0,0 +1,89 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main |
||||
|
||||
import ( |
||||
"errors" |
||||
"fmt" |
||||
"log" |
||||
|
||||
"github.com/gogits/gogs/modules/ldap" |
||||
) |
||||
|
||||
var ( |
||||
LdapServer string = "localhost" |
||||
LdapPort uint16 = 389 |
||||
BaseDN string = "dc=enterprise,dc=org" |
||||
BindDN string = "cn=admin,dc=enterprise,dc=org" |
||||
BindPW string = "enterprise" |
||||
Filter string = "(cn=kirkj)" |
||||
) |
||||
|
||||
func search(l *ldap.Conn, filter string, attributes []string) (*ldap.Entry, *ldap.Error) { |
||||
search := ldap.NewSearchRequest( |
||||
BaseDN, |
||||
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, |
||||
filter, |
||||
attributes, |
||||
nil) |
||||
|
||||
sr, err := l.Search(search) |
||||
if err != nil { |
||||
log.Fatalf("ERROR: %s\n", err) |
||||
return nil, err |
||||
} |
||||
|
||||
log.Printf("Search: %s -> num of entries = %d\n", search.Filter, len(sr.Entries)) |
||||
if len(sr.Entries) == 0 { |
||||
return nil, ldap.NewError(ldap.ErrorDebugging, errors.New(fmt.Sprintf("no entries found for: %s", filter))) |
||||
} |
||||
return sr.Entries[0], nil |
||||
} |
||||
|
||||
func main() { |
||||
l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", LdapServer, LdapPort)) |
||||
if err != nil { |
||||
log.Fatalf("ERROR: %s\n", err.Error()) |
||||
} |
||||
defer l.Close() |
||||
// l.Debug = true
|
||||
|
||||
l.Bind(BindDN, BindPW) |
||||
|
||||
log.Printf("The Search for Kirk ... %s\n", Filter) |
||||
entry, err := search(l, Filter, []string{}) |
||||
if err != nil { |
||||
log.Fatal("could not get entry") |
||||
} |
||||
entry.PrettyPrint(0) |
||||
|
||||
log.Printf("modify the mail address and add a description ... \n") |
||||
modify := ldap.NewModifyRequest(entry.DN) |
||||
modify.Add("description", []string{"Captain of the USS Enterprise"}) |
||||
modify.Replace("mail", []string{"captain@enterprise.org"}) |
||||
if err := l.Modify(modify); err != nil { |
||||
log.Fatalf("ERROR: %s\n", err.Error()) |
||||
} |
||||
|
||||
entry, err = search(l, Filter, []string{}) |
||||
if err != nil { |
||||
log.Fatal("could not get entry") |
||||
} |
||||
entry.PrettyPrint(0) |
||||
|
||||
log.Printf("reset the entry ... \n") |
||||
modify = ldap.NewModifyRequest(entry.DN) |
||||
modify.Delete("description", []string{}) |
||||
modify.Replace("mail", []string{"james.kirk@enterprise.org"}) |
||||
if err := l.Modify(modify); err != nil { |
||||
log.Fatalf("ERROR: %s\n", err.Error()) |
||||
} |
||||
|
||||
entry, err = search(l, Filter, []string{}) |
||||
if err != nil { |
||||
log.Fatal("could not get entry") |
||||
} |
||||
entry.PrettyPrint(0) |
||||
} |
@ -0,0 +1,52 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main |
||||
|
||||
import ( |
||||
"fmt" |
||||
"log" |
||||
|
||||
"github.com/gogits/gogs/modules/ldap" |
||||
) |
||||
|
||||
var ( |
||||
ldapServer string = "adserver" |
||||
ldapPort uint16 = 3268 |
||||
baseDN string = "dc=*,dc=*" |
||||
filter string = "(&(objectClass=user)(sAMAccountName=*)(memberOf=CN=*,OU=*,DC=*,DC=*))" |
||||
Attributes []string = []string{"memberof"} |
||||
user string = "*" |
||||
passwd string = "*" |
||||
) |
||||
|
||||
func main() { |
||||
l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort)) |
||||
if err != nil { |
||||
log.Fatalf("ERROR: %s\n", err.Error()) |
||||
} |
||||
defer l.Close() |
||||
// l.Debug = true
|
||||
|
||||
err = l.Bind(user, passwd) |
||||
if err != nil { |
||||
log.Printf("ERROR: Cannot bind: %s\n", err.Error()) |
||||
return |
||||
} |
||||
search := ldap.NewSearchRequest( |
||||
baseDN, |
||||
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, |
||||
filter, |
||||
Attributes, |
||||
nil) |
||||
|
||||
sr, err := l.Search(search) |
||||
if err != nil { |
||||
log.Fatalf("ERROR: %s\n", err.Error()) |
||||
return |
||||
} |
||||
|
||||
log.Printf("Search: %s -> num of entries = %d\n", search.Filter, len(sr.Entries)) |
||||
sr.PrettyPrint(0) |
||||
} |
@ -0,0 +1,45 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main |
||||
|
||||
import ( |
||||
"fmt" |
||||
"log" |
||||
|
||||
"github.com/gogits/gogs/modules/ldap" |
||||
) |
||||
|
||||
var ( |
||||
LdapServer string = "localhost" |
||||
LdapPort uint16 = 636 |
||||
BaseDN string = "dc=enterprise,dc=org" |
||||
Filter string = "(cn=kirkj)" |
||||
Attributes []string = []string{"mail"} |
||||
) |
||||
|
||||
func main() { |
||||
l, err := ldap.DialSSL("tcp", fmt.Sprintf("%s:%d", LdapServer, LdapPort), nil) |
||||
if err != nil { |
||||
log.Fatalf("ERROR: %s\n", err.String()) |
||||
} |
||||
defer l.Close() |
||||
// l.Debug = true
|
||||
|
||||
search := ldap.NewSearchRequest( |
||||
BaseDN, |
||||
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, |
||||
Filter, |
||||
Attributes, |
||||
nil) |
||||
|
||||
sr, err := l.Search(search) |
||||
if err != nil { |
||||
log.Fatalf("ERROR: %s\n", err.String()) |
||||
return |
||||
} |
||||
|
||||
log.Printf("Search: %s -> num of entries = %d\n", search.Filter, len(sr.Entries)) |
||||
sr.PrettyPrint(0) |
||||
} |
@ -0,0 +1,45 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main |
||||
|
||||
import ( |
||||
"fmt" |
||||
"log" |
||||
|
||||
"github.com/gogits/gogs/modules/ldap" |
||||
) |
||||
|
||||
var ( |
||||
LdapServer string = "localhost" |
||||
LdapPort uint16 = 389 |
||||
BaseDN string = "dc=enterprise,dc=org" |
||||
Filter string = "(cn=kirkj)" |
||||
Attributes []string = []string{"mail"} |
||||
) |
||||
|
||||
func main() { |
||||
l, err := ldap.DialTLS("tcp", fmt.Sprintf("%s:%d", LdapServer, LdapPort), nil) |
||||
if err != nil { |
||||
log.Fatalf("ERROR: %s\n", err.Error()) |
||||
} |
||||
defer l.Close() |
||||
// l.Debug = true
|
||||
|
||||
search := ldap.NewSearchRequest( |
||||
BaseDN, |
||||
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, |
||||
Filter, |
||||
Attributes, |
||||
nil) |
||||
|
||||
sr, err := l.Search(search) |
||||
if err != nil { |
||||
log.Fatalf("ERROR: %s\n", err.Error()) |
||||
return |
||||
} |
||||
|
||||
log.Printf("Search: %s -> num of entries = %d\n", search.Filter, len(sr.Entries)) |
||||
sr.PrettyPrint(0) |
||||
} |
@ -0,0 +1,67 @@
|
||||
# |
||||
# See slapd.conf(5) for details on configuration options. |
||||
# This file should NOT be world readable. |
||||
# |
||||
include /private/etc/openldap/schema/core.schema |
||||
include /private/etc/openldap/schema/cosine.schema |
||||
include /private/etc/openldap/schema/inetorgperson.schema |
||||
|
||||
# Define global ACLs to disable default read access. |
||||
|
||||
# Do not enable referrals until AFTER you have a working directory |
||||
# service AND an understanding of referrals. |
||||
#referral ldap://root.openldap.org |
||||
|
||||
pidfile /private/var/db/openldap/run/slapd.pid |
||||
argsfile /private/var/db/openldap/run/slapd.args |
||||
|
||||
# Load dynamic backend modules: |
||||
# modulepath /usr/libexec/openldap |
||||
# moduleload back_bdb.la |
||||
# moduleload back_hdb.la |
||||
# moduleload back_ldap.la |
||||
|
||||
# Sample security restrictions |
||||
# Require integrity protection (prevent hijacking) |
||||
# Require 112-bit (3DES or better) encryption for updates |
||||
# Require 63-bit encryption for simple bind |
||||
# security ssf=1 update_ssf=112 simple_bind=64 |
||||
|
||||
# Sample access control policy: |
||||
# Root DSE: allow anyone to read it |
||||
# Subschema (sub)entry DSE: allow anyone to read it |
||||
# Other DSEs: |
||||
# Allow self write access |
||||
# Allow authenticated users read access |
||||
# Allow anonymous users to authenticate |
||||
# Directives needed to implement policy: |
||||
# access to dn.base="" by * read |
||||
# access to dn.base="cn=Subschema" by * read |
||||
# access to * |
||||
# by self write |
||||
# by users read |
||||
# by anonymous auth |
||||
# |
||||
# if no access controls are present, the default policy |
||||
# allows anyone and everyone to read anything but restricts |
||||
# updates to rootdn. (e.g., "access to * by * read") |
||||
# |
||||
# rootdn can always read and write EVERYTHING! |
||||
|
||||
####################################################################### |
||||
# BDB database definitions |
||||
####################################################################### |
||||
|
||||
database bdb |
||||
suffix "dc=enterprise,dc=org" |
||||
rootdn "cn=admin,dc=enterprise,dc=org" |
||||
# Cleartext passwords, especially for the rootdn, should |
||||
# be avoid. See slappasswd(8) and slapd.conf(5) for details. |
||||
# Use of strong authentication encouraged. |
||||
rootpw {SSHA}laO00HsgszhK1O0Z5qR0/i/US69Osfeu |
||||
# The database directory MUST exist prior to running slapd AND |
||||
# should only be accessible by the slapd and slap tools. |
||||
# Mode 700 recommended. |
||||
directory /private/var/db/openldap/openldap-data |
||||
# Indices to maintain |
||||
index objectClass eq |
@ -0,0 +1,55 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ldap |
||||
|
||||
import ( |
||||
"errors" |
||||
|
||||
"github.com/gogits/gogs/modules/asn1-ber" |
||||
) |
||||
|
||||
func (l *Conn) Bind(username, password string) error { |
||||
messageID := l.nextMessageID() |
||||
|
||||
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") |
||||
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, messageID, "MessageID")) |
||||
bindRequest := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request") |
||||
bindRequest.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version")) |
||||
bindRequest.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, username, "User Name")) |
||||
bindRequest.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, password, "Password")) |
||||
packet.AppendChild(bindRequest) |
||||
|
||||
if l.Debug { |
||||
ber.PrintPacket(packet) |
||||
} |
||||
|
||||
channel, err := l.sendMessage(packet) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
if channel == nil { |
||||
return NewError(ErrorNetwork, errors.New("ldap: could not send message")) |
||||
} |
||||
defer l.finishMessage(messageID) |
||||
|
||||
packet = <-channel |
||||
if packet == nil { |
||||
return NewError(ErrorNetwork, errors.New("ldap: could not retrieve response")) |
||||
} |
||||
|
||||
if l.Debug { |
||||
if err := addLDAPDescriptions(packet); err != nil { |
||||
return err |
||||
} |
||||
ber.PrintPacket(packet) |
||||
} |
||||
|
||||
resultCode, resultDescription := getLDAPResultCode(packet) |
||||
if resultCode != 0 { |
||||
return NewError(resultCode, errors.New(resultDescription)) |
||||
} |
||||
|
||||
return nil |
||||
} |
@ -0,0 +1,275 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ldap |
||||
|
||||
import ( |
||||
"crypto/tls" |
||||
"errors" |
||||
"log" |
||||
"net" |
||||
"sync" |
||||
|
||||
"github.com/gogits/gogs/modules/asn1-ber" |
||||
) |
||||
|
||||
const ( |
||||
MessageQuit = 0 |
||||
MessageRequest = 1 |
||||
MessageResponse = 2 |
||||
MessageFinish = 3 |
||||
) |
||||
|
||||
type messagePacket struct { |
||||
Op int |
||||
MessageID uint64 |
||||
Packet *ber.Packet |
||||
Channel chan *ber.Packet |
||||
} |
||||
|
||||
// Conn represents an LDAP Connection
|
||||
type Conn struct { |
||||
conn net.Conn |
||||
isTLS bool |
||||
isClosing bool |
||||
Debug debugging |
||||
chanConfirm chan bool |
||||
chanResults map[uint64]chan *ber.Packet |
||||
chanMessage chan *messagePacket |
||||
chanMessageID chan uint64 |
||||
wgSender sync.WaitGroup |
||||
wgClose sync.WaitGroup |
||||
once sync.Once |
||||
} |
||||
|
||||
// Dial connects to the given address on the given network using net.Dial
|
||||
// and then returns a new Conn for the connection.
|
||||
func Dial(network, addr string) (*Conn, error) { |
||||
c, err := net.Dial(network, addr) |
||||
if err != nil { |
||||
return nil, NewError(ErrorNetwork, err) |
||||
} |
||||
conn := NewConn(c) |
||||
conn.start() |
||||
return conn, nil |
||||
} |
||||
|
||||
// DialTLS connects to the given address on the given network using tls.Dial
|
||||
// and then returns a new Conn for the connection.
|
||||
func DialTLS(network, addr string, config *tls.Config) (*Conn, error) { |
||||
c, err := tls.Dial(network, addr, config) |
||||
if err != nil { |
||||
return nil, NewError(ErrorNetwork, err) |
||||
} |
||||
conn := NewConn(c) |
||||
conn.isTLS = true |
||||
conn.start() |
||||
return conn, nil |
||||
} |
||||
|
||||
// NewConn returns a new Conn using conn for network I/O.
|
||||
func NewConn(conn net.Conn) *Conn { |
||||
return &Conn{ |
||||
conn: conn, |
||||
chanConfirm: make(chan bool), |
||||
chanMessageID: make(chan uint64), |
||||
chanMessage: make(chan *messagePacket, 10), |
||||
chanResults: map[uint64]chan *ber.Packet{}, |
||||
} |
||||
} |
||||
|
||||
func (l *Conn) start() { |
||||
go l.reader() |
||||
go l.processMessages() |
||||
l.wgClose.Add(1) |
||||
} |
||||
|
||||
// Close closes the connection.
|
||||
func (l *Conn) Close() { |
||||
l.once.Do(func() { |
||||
l.isClosing = true |
||||
l.wgSender.Wait() |
||||
|
||||
l.Debug.Printf("Sending quit message and waiting for confirmation") |
||||
l.chanMessage <- &messagePacket{Op: MessageQuit} |
||||
<-l.chanConfirm |
||||
close(l.chanMessage) |
||||
|
||||
l.Debug.Printf("Closing network connection") |
||||
if err := l.conn.Close(); err != nil { |
||||
log.Print(err) |
||||
} |
||||
|
||||
l.conn = nil |
||||
l.wgClose.Done() |
||||
}) |
||||
l.wgClose.Wait() |
||||
} |
||||
|
||||
// Returns the next available messageID
|
||||
func (l *Conn) nextMessageID() uint64 { |
||||
if l.chanMessageID != nil { |
||||
if messageID, ok := <-l.chanMessageID; ok { |
||||
return messageID |
||||
} |
||||
} |
||||
return 0 |
||||
} |
||||
|
||||
// StartTLS sends the command to start a TLS session and then creates a new TLS Client
|
||||
func (l *Conn) StartTLS(config *tls.Config) error { |
||||
messageID := l.nextMessageID() |
||||
|
||||
if l.isTLS { |
||||
return NewError(ErrorNetwork, errors.New("ldap: already encrypted")) |
||||
} |
||||
|
||||
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") |
||||
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, messageID, "MessageID")) |
||||
request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationExtendedRequest, nil, "Start TLS") |
||||
request.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, "1.3.6.1.4.1.1466.20037", "TLS Extended Command")) |
||||
packet.AppendChild(request) |
||||
l.Debug.PrintPacket(packet) |
||||
|
||||
_, err := l.conn.Write(packet.Bytes()) |
||||
if err != nil { |
||||
return NewError(ErrorNetwork, err) |
||||
} |
||||
|
||||
packet, err = ber.ReadPacket(l.conn) |
||||
if err != nil { |
||||
return NewError(ErrorNetwork, err) |
||||
} |
||||
|
||||
if l.Debug { |
||||
if err := addLDAPDescriptions(packet); err != nil { |
||||
return err |
||||
} |
||||
ber.PrintPacket(packet) |
||||
} |
||||
|
||||
if packet.Children[1].Children[0].Value.(uint64) == 0 { |
||||
conn := tls.Client(l.conn, config) |
||||
l.isTLS = true |
||||
l.conn = conn |
||||
} |
||||
|
||||
return nil |
||||
} |
||||
|
||||
func (l *Conn) sendMessage(packet *ber.Packet) (chan *ber.Packet, error) { |
||||
if l.isClosing { |
||||
return nil, NewError(ErrorNetwork, errors.New("ldap: connection closed")) |
||||
} |
||||
out := make(chan *ber.Packet) |
||||
message := &messagePacket{ |
||||
Op: MessageRequest, |
||||
MessageID: packet.Children[0].Value.(uint64), |
||||
Packet: packet, |
||||
Channel: out, |
||||
} |
||||
l.sendProcessMessage(message) |
||||
return out, nil |
||||
} |
||||
|
||||
func (l *Conn) finishMessage(messageID uint64) { |
||||
if l.isClosing { |
||||
return |
||||
} |
||||
message := &messagePacket{ |
||||
Op: MessageFinish, |
||||
MessageID: messageID, |
||||
} |
||||
l.sendProcessMessage(message) |
||||
} |
||||
|
||||
func (l *Conn) sendProcessMessage(message *messagePacket) bool { |
||||
if l.isClosing { |
||||
return false |
||||
} |
||||
l.wgSender.Add(1) |
||||
l.chanMessage <- message |
||||
l.wgSender.Done() |
||||
return true |
||||
} |
||||
|
||||
func (l *Conn) processMessages() { |
||||
defer func() { |
||||
for messageID, channel := range l.chanResults { |
||||
l.Debug.Printf("Closing channel for MessageID %d", messageID) |
||||
close(channel) |
||||
delete(l.chanResults, messageID) |
||||
} |
||||
close(l.chanMessageID) |
||||
l.chanConfirm <- true |
||||
close(l.chanConfirm) |
||||
}() |
||||
|
||||
var messageID uint64 = 1 |
||||
for { |
||||
select { |
||||
case l.chanMessageID <- messageID: |
||||
messageID++ |
||||
case messagePacket, ok := <-l.chanMessage: |
||||
if !ok { |
||||
l.Debug.Printf("Shutting down - message channel is closed") |
||||
return |
||||
} |
||||
switch messagePacket.Op { |
||||
case MessageQuit: |
||||
l.Debug.Printf("Shutting down - quit message received") |
||||
return |
||||
case MessageRequest: |
||||
// Add to message list and write to network
|
||||
l.Debug.Printf("Sending message %d", messagePacket.MessageID) |
||||
l.chanResults[messagePacket.MessageID] = messagePacket.Channel |
||||
// go routine
|
||||
buf := messagePacket.Packet.Bytes() |
||||
|
||||
_, err := l.conn.Write(buf) |
||||
if err != nil { |
||||
l.Debug.Printf("Error Sending Message: %s", err.Error()) |
||||
break |
||||
} |
||||
case MessageResponse: |
||||
l.Debug.Printf("Receiving message %d", messagePacket.MessageID) |
||||
if chanResult, ok := l.chanResults[messagePacket.MessageID]; ok { |
||||
chanResult <- messagePacket.Packet |
||||
} else { |
||||
log.Printf("Received unexpected message %d", messagePacket.MessageID) |
||||
ber.PrintPacket(messagePacket.Packet) |
||||
} |
||||
case MessageFinish: |
||||
// Remove from message list
|
||||
l.Debug.Printf("Finished message %d", messagePacket.MessageID) |
||||
close(l.chanResults[messagePacket.MessageID]) |
||||
delete(l.chanResults, messagePacket.MessageID) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
func (l *Conn) reader() { |
||||
defer func() { |
||||
l.Close() |
||||
}() |
||||
|
||||
for { |
||||
packet, err := ber.ReadPacket(l.conn) |
||||
if err != nil { |
||||
l.Debug.Printf("reader: %s", err.Error()) |
||||
return |
||||
} |
||||
addLDAPDescriptions(packet) |
||||
message := &messagePacket{ |
||||
Op: MessageResponse, |
||||
MessageID: packet.Children[0].Value.(uint64), |
||||
Packet: packet, |
||||
} |
||||
if !l.sendProcessMessage(message) { |
||||
return |
||||
} |
||||
|
||||
} |
||||
} |
@ -0,0 +1,157 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ldap |
||||
|
||||
import ( |
||||
"fmt" |
||||
|
||||
"github.com/gogits/gogs/modules/asn1-ber" |
||||
) |
||||
|
||||
const ( |
||||
ControlTypePaging = "1.2.840.113556.1.4.319" |
||||
) |
||||
|
||||
var ControlTypeMap = map[string]string{ |
||||
ControlTypePaging: "Paging", |
||||
} |
||||
|
||||
type Control interface { |
||||
GetControlType() string |
||||
Encode() *ber.Packet |
||||
String() string |
||||
} |
||||
|
||||
type ControlString struct { |
||||
ControlType string |
||||
Criticality bool |
||||
ControlValue string |
||||
} |
||||
|
||||
func (c *ControlString) GetControlType() string { |
||||
return c.ControlType |
||||
} |
||||
|
||||
func (c *ControlString) Encode() *ber.Packet { |
||||
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control") |
||||
packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, c.ControlType, "Control Type ("+ControlTypeMap[c.ControlType]+")")) |
||||
if c.Criticality { |
||||
packet.AppendChild(ber.NewBoolean(ber.ClassUniversal, ber.TypePrimitive, ber.TagBoolean, c.Criticality, "Criticality")) |
||||
} |
||||
packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, c.ControlValue, "Control Value")) |
||||
return packet |
||||
} |
||||
|
||||
func (c *ControlString) String() string { |
||||
return fmt.Sprintf("Control Type: %s (%q) Criticality: %t Control Value: %s", ControlTypeMap[c.ControlType], c.ControlType, c.Criticality, c.ControlValue) |
||||
} |
||||
|
||||
type ControlPaging struct { |
||||
PagingSize uint32 |
||||
Cookie []byte |
||||
} |
||||
|
||||
func (c *ControlPaging) GetControlType() string { |
||||
return ControlTypePaging |
||||
} |
||||
|
||||
func (c *ControlPaging) Encode() *ber.Packet { |
||||
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control") |
||||
packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, ControlTypePaging, "Control Type ("+ControlTypeMap[ControlTypePaging]+")")) |
||||
|
||||
p2 := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Control Value (Paging)") |
||||
seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Search Control Value") |
||||
seq.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, uint64(c.PagingSize), "Paging Size")) |
||||
cookie := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Cookie") |
||||
cookie.Value = c.Cookie |
||||
cookie.Data.Write(c.Cookie) |
||||
seq.AppendChild(cookie) |
||||
p2.AppendChild(seq) |
||||
|
||||
packet.AppendChild(p2) |
||||
return packet |
||||
} |
||||
|
||||
func (c *ControlPaging) String() string { |
||||
return fmt.Sprintf( |
||||
"Control Type: %s (%q) Criticality: %t PagingSize: %d Cookie: %q", |
||||
ControlTypeMap[ControlTypePaging], |
||||
ControlTypePaging, |
||||
false, |
||||
c.PagingSize, |
||||
c.Cookie) |
||||
} |
||||
|
||||
func (c *ControlPaging) SetCookie(cookie []byte) { |
||||
c.Cookie = cookie |
||||
} |
||||
|
||||
func FindControl(controls []Control, controlType string) Control { |
||||
for _, c := range controls { |
||||
if c.GetControlType() == controlType { |
||||
return c |
||||
} |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
func DecodeControl(packet *ber.Packet) Control { |
||||
ControlType := packet.Children[0].Value.(string) |
||||
Criticality := false |
||||
|
||||
packet.Children[0].Description = "Control Type (" + ControlTypeMap[ControlType] + ")" |
||||
value := packet.Children[1] |
||||
if len(packet.Children) == 3 { |
||||
value = packet.Children[2] |
||||
packet.Children[1].Description = "Criticality" |
||||
Criticality = packet.Children[1].Value.(bool) |
||||
} |
||||
|
||||
value.Description = "Control Value" |
||||
switch ControlType { |
||||
case ControlTypePaging: |
||||
value.Description += " (Paging)" |
||||
c := new(ControlPaging) |
||||
if value.Value != nil { |
||||
valueChildren := ber.DecodePacket(value.Data.Bytes()) |
||||
value.Data.Truncate(0) |
||||
value.Value = nil |
||||
value.AppendChild(valueChildren) |
||||
} |
||||
value = value.Children[0] |
||||
value.Description = "Search Control Value" |
||||
value.Children[0].Description = "Paging Size" |
||||
value.Children[1].Description = "Cookie" |
||||
c.PagingSize = uint32(value.Children[0].Value.(uint64)) |
||||
c.Cookie = value.Children[1].Data.Bytes() |
||||
value.Children[1].Value = c.Cookie |
||||
return c |
||||
} |
||||
c := new(ControlString) |
||||
c.ControlType = ControlType |
||||
c.Criticality = Criticality |
||||
c.ControlValue = value.Value.(string) |
||||
return c |
||||
} |
||||
|
||||
func NewControlString(controlType string, criticality bool, controlValue string) *ControlString { |
||||
return &ControlString{ |
||||
ControlType: controlType, |
||||
Criticality: criticality, |
||||
ControlValue: controlValue, |
||||
} |
||||
} |
||||
|
||||
func NewControlPaging(pagingSize uint32) *ControlPaging { |
||||
return &ControlPaging{PagingSize: pagingSize} |
||||
} |
||||
|
||||
func encodeControls(controls []Control) *ber.Packet { |
||||
packet := ber.Encode(ber.ClassContext, ber.TypeConstructed, 0, nil, "Controls") |
||||
for _, control := range controls { |
||||
packet.AppendChild(control.Encode()) |
||||
} |
||||
return packet |
||||
} |
@ -0,0 +1,24 @@
|
||||
package ldap |
||||
|
||||
import ( |
||||
"log" |
||||
|
||||
"github.com/gogits/gogs/modules/asn1-ber" |
||||
) |
||||
|
||||
// debbuging type
|
||||
// - has a Printf method to write the debug output
|
||||
type debugging bool |
||||
|
||||
// write debug output
|
||||
func (debug debugging) Printf(format string, args ...interface{}) { |
||||
if debug { |
||||
log.Printf(format, args...) |
||||
} |
||||
} |
||||
|
||||
func (debug debugging) PrintPacket(packet *ber.Packet) { |
||||
if debug { |
||||
ber.PrintPacket(packet) |
||||
} |
||||
} |
@ -0,0 +1,248 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ldap |
||||
|
||||
import ( |
||||
"errors" |
||||
"fmt" |
||||
|
||||
"github.com/gogits/gogs/modules/asn1-ber" |
||||
) |
||||
|
||||
const ( |
||||
FilterAnd = 0 |
||||
FilterOr = 1 |
||||
FilterNot = 2 |
||||
FilterEqualityMatch = 3 |
||||
FilterSubstrings = 4 |
||||
FilterGreaterOrEqual = 5 |
||||
FilterLessOrEqual = 6 |
||||
FilterPresent = 7 |
||||
FilterApproxMatch = 8 |
||||
FilterExtensibleMatch = 9 |
||||
) |
||||
|
||||
var FilterMap = map[uint64]string{ |
||||
FilterAnd: "And", |
||||
FilterOr: "Or", |
||||
FilterNot: "Not", |
||||
FilterEqualityMatch: "Equality Match", |
||||
FilterSubstrings: "Substrings", |
||||
FilterGreaterOrEqual: "Greater Or Equal", |
||||
FilterLessOrEqual: "Less Or Equal", |
||||
FilterPresent: "Present", |
||||
FilterApproxMatch: "Approx Match", |
||||
FilterExtensibleMatch: "Extensible Match", |
||||
} |
||||
|
||||
const ( |
||||
FilterSubstringsInitial = 0 |
||||
FilterSubstringsAny = 1 |
||||
FilterSubstringsFinal = 2 |
||||
) |
||||
|
||||
var FilterSubstringsMap = map[uint64]string{ |
||||
FilterSubstringsInitial: "Substrings Initial", |
||||
FilterSubstringsAny: "Substrings Any", |
||||
FilterSubstringsFinal: "Substrings Final", |
||||
} |
||||
|
||||
func CompileFilter(filter string) (*ber.Packet, error) { |
||||
if len(filter) == 0 || filter[0] != '(' { |
||||
return nil, NewError(ErrorFilterCompile, errors.New("ldap: filter does not start with an '('")) |
||||
} |
||||
packet, pos, err := compileFilter(filter, 1) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
if pos != len(filter) { |
||||
return nil, NewError(ErrorFilterCompile, errors.New("ldap: finished compiling filter with extra at end: "+fmt.Sprint(filter[pos:]))) |
||||
} |
||||
return packet, nil |
||||
} |
||||
|
||||
func DecompileFilter(packet *ber.Packet) (ret string, err error) { |
||||
defer func() { |
||||
if r := recover(); r != nil { |
||||
err = NewError(ErrorFilterDecompile, errors.New("ldap: error decompiling filter")) |
||||
} |
||||
}() |
||||
ret = "(" |
||||
err = nil |
||||
childStr := "" |
||||
|
||||
switch packet.Tag { |
||||
case FilterAnd: |
||||
ret += "&" |
||||
for _, child := range packet.Children { |
||||
childStr, err = DecompileFilter(child) |
||||
if err != nil { |
||||
return |
||||
} |
||||
ret += childStr |
||||
} |
||||
case FilterOr: |
||||
ret += "|" |
||||
for _, child := range packet.Children { |
||||
childStr, err = DecompileFilter(child) |
||||
if err != nil { |
||||
return |
||||
} |
||||
ret += childStr |
||||
} |
||||
case FilterNot: |
||||
ret += "!" |
||||
childStr, err = DecompileFilter(packet.Children[0]) |
||||
if err != nil { |
||||
return |
||||
} |
||||
ret += childStr |
||||
|
||||
case FilterSubstrings: |
||||
ret += ber.DecodeString(packet.Children[0].Data.Bytes()) |
||||
ret += "=" |
||||
switch packet.Children[1].Children[0].Tag { |
||||
case FilterSubstringsInitial: |
||||
ret += ber.DecodeString(packet.Children[1].Children[0].Data.Bytes()) + "*" |
||||
case FilterSubstringsAny: |
||||
ret += "*" + ber.DecodeString(packet.Children[1].Children[0].Data.Bytes()) + "*" |
||||
case FilterSubstringsFinal: |
||||
ret += "*" + ber.DecodeString(packet.Children[1].Children[0].Data.Bytes()) |
||||
} |
||||
case FilterEqualityMatch: |
||||
ret += ber.DecodeString(packet.Children[0].Data.Bytes()) |
||||
ret += "=" |
||||
ret += ber.DecodeString(packet.Children[1].Data.Bytes()) |
||||
case FilterGreaterOrEqual: |
||||
ret += ber.DecodeString(packet.Children[0].Data.Bytes()) |
||||
ret += ">=" |
||||
ret += ber.DecodeString(packet.Children[1].Data.Bytes()) |
||||
case FilterLessOrEqual: |
||||
ret += ber.DecodeString(packet.Children[0].Data.Bytes()) |
||||
ret += "<=" |
||||
ret += ber.DecodeString(packet.Children[1].Data.Bytes()) |
||||
case FilterPresent: |
||||
ret += ber.DecodeString(packet.Children[0].Data.Bytes()) |
||||
ret += "=*" |
||||
case FilterApproxMatch: |
||||
ret += ber.DecodeString(packet.Children[0].Data.Bytes()) |
||||
ret += "~=" |
||||
ret += ber.DecodeString(packet.Children[1].Data.Bytes()) |
||||
} |
||||
|
||||
ret += ")" |
||||
return |
||||
} |
||||
|
||||
func compileFilterSet(filter string, pos int, parent *ber.Packet) (int, error) { |
||||
for pos < len(filter) && filter[pos] == '(' { |
||||
child, newPos, err := compileFilter(filter, pos+1) |
||||
if err != nil { |
||||
return pos, err |
||||
} |
||||
pos = newPos |
||||
parent.AppendChild(child) |
||||
} |
||||
if pos == len(filter) { |
||||
return pos, NewError(ErrorFilterCompile, errors.New("ldap: unexpected end of filter")) |
||||
} |
||||
|
||||
return pos + 1, nil |
||||
} |
||||
|
||||
func compileFilter(filter string, pos int) (*ber.Packet, int, error) { |
||||
var packet *ber.Packet |
||||
var err error |
||||
|
||||
defer func() { |
||||
if r := recover(); r != nil { |
||||
err = NewError(ErrorFilterCompile, errors.New("ldap: error compiling filter")) |
||||
} |
||||
}() |
||||
|
||||
newPos := pos |
||||
switch filter[pos] { |
||||
case '(': |
||||
packet, newPos, err = compileFilter(filter, pos+1) |
||||
newPos++ |
||||
return packet, newPos, err |
||||
case '&': |
||||
packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterAnd, nil, FilterMap[FilterAnd]) |
||||
newPos, err = compileFilterSet(filter, pos+1, packet) |
||||
return packet, newPos, err |
||||
case '|': |
||||
packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterOr, nil, FilterMap[FilterOr]) |
||||
newPos, err = compileFilterSet(filter, pos+1, packet) |
||||
return packet, newPos, err |
||||
case '!': |
||||
packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterNot, nil, FilterMap[FilterNot]) |
||||
var child *ber.Packet |
||||
child, newPos, err = compileFilter(filter, pos+1) |
||||
packet.AppendChild(child) |
||||
return packet, newPos, err |
||||
default: |
||||
attribute := "" |
||||
condition := "" |
||||
for newPos < len(filter) && filter[newPos] != ')' { |
||||
switch { |
||||
case packet != nil: |
||||
condition += fmt.Sprintf("%c", filter[newPos]) |
||||
case filter[newPos] == '=': |
||||
packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterEqualityMatch, nil, FilterMap[FilterEqualityMatch]) |
||||
case filter[newPos] == '>' && filter[newPos+1] == '=': |
||||
packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterGreaterOrEqual, nil, FilterMap[FilterGreaterOrEqual]) |
||||
newPos++ |
||||
case filter[newPos] == '<' && filter[newPos+1] == '=': |
||||
packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterLessOrEqual, nil, FilterMap[FilterLessOrEqual]) |
||||
newPos++ |
||||
case filter[newPos] == '~' && filter[newPos+1] == '=': |
||||
packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterApproxMatch, nil, FilterMap[FilterLessOrEqual]) |
||||
newPos++ |
||||
case packet == nil: |
||||
attribute += fmt.Sprintf("%c", filter[newPos]) |
||||
} |
||||
newPos++ |
||||
} |
||||
if newPos == len(filter) { |
||||
err = NewError(ErrorFilterCompile, errors.New("ldap: unexpected end of filter")) |
||||
return packet, newPos, err |
||||
} |
||||
if packet == nil { |
||||
err = NewError(ErrorFilterCompile, errors.New("ldap: error parsing filter")) |
||||
return packet, newPos, err |
||||
} |
||||
packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, attribute, "Attribute")) |
||||
switch { |
||||
case packet.Tag == FilterEqualityMatch && condition == "*": |
||||
packet.Tag = FilterPresent |
||||
packet.Description = FilterMap[uint64(packet.Tag)] |
||||
case packet.Tag == FilterEqualityMatch && condition[0] == '*' && condition[len(condition)-1] == '*': |
||||
// Any
|
||||
packet.Tag = FilterSubstrings |
||||
packet.Description = FilterMap[uint64(packet.Tag)] |
||||
seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Substrings") |
||||
seq.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, FilterSubstringsAny, condition[1:len(condition)-1], "Any Substring")) |
||||
packet.AppendChild(seq) |
||||
case packet.Tag == FilterEqualityMatch && condition[0] == '*': |
||||
// Final
|
||||
packet.Tag = FilterSubstrings |
||||
packet.Description = FilterMap[uint64(packet.Tag)] |
||||
seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Substrings") |
||||
seq.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, FilterSubstringsFinal, condition[1:], "Final Substring")) |
||||
packet.AppendChild(seq) |
||||
case packet.Tag == FilterEqualityMatch && condition[len(condition)-1] == '*': |
||||
// Initial
|
||||
packet.Tag = FilterSubstrings |
||||
packet.Description = FilterMap[uint64(packet.Tag)] |
||||
seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Substrings") |
||||
seq.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, FilterSubstringsInitial, condition[:len(condition)-1], "Initial Substring")) |
||||
packet.AppendChild(seq) |
||||
default: |
||||
packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, condition, "Condition")) |
||||
} |
||||
newPos++ |
||||
return packet, newPos, err |
||||
} |
||||
} |
@ -0,0 +1,78 @@
|
||||
package ldap |
||||
|
||||
import ( |
||||
"testing" |
||||
|
||||
"github.com/gogits/gogs/modules/asn1-ber" |
||||
) |
||||
|
||||
type compileTest struct { |
||||
filterStr string |
||||
filterType int |
||||
} |
||||
|
||||
var testFilters = []compileTest{ |
||||
compileTest{filterStr: "(&(sn=Miller)(givenName=Bob))", filterType: FilterAnd}, |
||||
compileTest{filterStr: "(|(sn=Miller)(givenName=Bob))", filterType: FilterOr}, |
||||
compileTest{filterStr: "(!(sn=Miller))", filterType: FilterNot}, |
||||
compileTest{filterStr: "(sn=Miller)", filterType: FilterEqualityMatch}, |
||||
compileTest{filterStr: "(sn=Mill*)", filterType: FilterSubstrings}, |
||||
compileTest{filterStr: "(sn=*Mill)", filterType: FilterSubstrings}, |
||||
compileTest{filterStr: "(sn=*Mill*)", filterType: FilterSubstrings}, |
||||
compileTest{filterStr: "(sn>=Miller)", filterType: FilterGreaterOrEqual}, |
||||
compileTest{filterStr: "(sn<=Miller)", filterType: FilterLessOrEqual}, |
||||
compileTest{filterStr: "(sn=*)", filterType: FilterPresent}, |
||||
compileTest{filterStr: "(sn~=Miller)", filterType: FilterApproxMatch}, |
||||
// compileTest{ filterStr: "()", filterType: FilterExtensibleMatch },
|
||||
} |
||||
|
||||
func TestFilter(t *testing.T) { |
||||
// Test Compiler and Decompiler
|
||||
for _, i := range testFilters { |
||||
filter, err := CompileFilter(i.filterStr) |
||||
if err != nil { |
||||
t.Errorf("Problem compiling %s - %s", i.filterStr, err.Error()) |
||||
} else if filter.Tag != uint8(i.filterType) { |
||||
t.Errorf("%q Expected %q got %q", i.filterStr, FilterMap[uint64(i.filterType)], FilterMap[uint64(filter.Tag)]) |
||||
} else { |
||||
o, err := DecompileFilter(filter) |
||||
if err != nil { |
||||
t.Errorf("Problem compiling %s - %s", i.filterStr, err.Error()) |
||||
} else if i.filterStr != o { |
||||
t.Errorf("%q expected, got %q", i.filterStr, o) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
func BenchmarkFilterCompile(b *testing.B) { |
||||
b.StopTimer() |
||||
filters := make([]string, len(testFilters)) |
||||
|
||||
// Test Compiler and Decompiler
|
||||
for idx, i := range testFilters { |
||||
filters[idx] = i.filterStr |
||||
} |
||||
|
||||
maxIdx := len(filters) |
||||
b.StartTimer() |
||||
for i := 0; i < b.N; i++ { |
||||
CompileFilter(filters[i%maxIdx]) |
||||
} |
||||
} |
||||
|
||||
func BenchmarkFilterDecompile(b *testing.B) { |
||||
b.StopTimer() |
||||
filters := make([]*ber.Packet, len(testFilters)) |
||||
|
||||
// Test Compiler and Decompiler
|
||||
for idx, i := range testFilters { |
||||
filters[idx], _ = CompileFilter(i.filterStr) |
||||
} |
||||
|
||||
maxIdx := len(filters) |
||||
b.StartTimer() |
||||
for i := 0; i < b.N; i++ { |
||||
DecompileFilter(filters[i%maxIdx]) |
||||
} |
||||
} |
@ -0,0 +1,302 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ldap |
||||
|
||||
import ( |
||||
"errors" |
||||
"fmt" |
||||
"io/ioutil" |
||||
|
||||
"github.com/gogits/gogs/modules/asn1-ber" |
||||
) |
||||
|
||||
// LDAP Application Codes
|
||||
const ( |
||||
ApplicationBindRequest = 0 |
||||
ApplicationBindResponse = 1 |
||||
ApplicationUnbindRequest = 2 |
||||
ApplicationSearchRequest = 3 |
||||
ApplicationSearchResultEntry = 4 |
||||
ApplicationSearchResultDone = 5 |
||||
ApplicationModifyRequest = 6 |
||||
ApplicationModifyResponse = 7 |
||||
ApplicationAddRequest = 8 |
||||
ApplicationAddResponse = 9 |
||||
ApplicationDelRequest = 10 |
||||
ApplicationDelResponse = 11 |
||||
ApplicationModifyDNRequest = 12 |
||||
ApplicationModifyDNResponse = 13 |
||||
ApplicationCompareRequest = 14 |
||||
ApplicationCompareResponse = 15 |
||||
ApplicationAbandonRequest = 16 |
||||
ApplicationSearchResultReference = 19 |
||||
ApplicationExtendedRequest = 23 |
||||
ApplicationExtendedResponse = 24 |
||||
) |
||||
|
||||
var ApplicationMap = map[uint8]string{ |
||||
ApplicationBindRequest: "Bind Request", |
||||
ApplicationBindResponse: "Bind Response", |
||||
ApplicationUnbindRequest: "Unbind Request", |
||||
ApplicationSearchRequest: "Search Request", |
||||
ApplicationSearchResultEntry: "Search Result Entry", |
||||
ApplicationSearchResultDone: "Search Result Done", |
||||
ApplicationModifyRequest: "Modify Request", |
||||
ApplicationModifyResponse: "Modify Response", |
||||
ApplicationAddRequest: "Add Request", |
||||
ApplicationAddResponse: "Add Response", |
||||
ApplicationDelRequest: "Del Request", |
||||
ApplicationDelResponse: "Del Response", |
||||
ApplicationModifyDNRequest: "Modify DN Request", |
||||
ApplicationModifyDNResponse: "Modify DN Response", |
||||
ApplicationCompareRequest: "Compare Request", |
||||
ApplicationCompareResponse: "Compare Response", |
||||
ApplicationAbandonRequest: "Abandon Request", |
||||
ApplicationSearchResultReference: "Search Result Reference", |
||||
ApplicationExtendedRequest: "Extended Request", |
||||
ApplicationExtendedResponse: "Extended Response", |
||||
} |
||||
|
||||
// LDAP Result Codes
|
||||
const ( |
||||
LDAPResultSuccess = 0 |
||||
LDAPResultOperationsError = 1 |
||||
LDAPResultProtocolError = 2 |
||||
LDAPResultTimeLimitExceeded = 3 |
||||
LDAPResultSizeLimitExceeded = 4 |
||||
LDAPResultCompareFalse = 5 |
||||
LDAPResultCompareTrue = 6 |
||||
LDAPResultAuthMethodNotSupported = 7 |
||||
LDAPResultStrongAuthRequired = 8 |
||||
LDAPResultReferral = 10 |
||||
LDAPResultAdminLimitExceeded = 11 |
||||
LDAPResultUnavailableCriticalExtension = 12 |
||||
LDAPResultConfidentialityRequired = 13 |
||||
LDAPResultSaslBindInProgress = 14 |
||||
LDAPResultNoSuchAttribute = 16 |
||||
LDAPResultUndefinedAttributeType = 17 |
||||
LDAPResultInappropriateMatching = 18 |
||||
LDAPResultConstraintViolation = 19 |
||||
LDAPResultAttributeOrValueExists = 20 |
||||
LDAPResultInvalidAttributeSyntax = 21 |
||||
LDAPResultNoSuchObject = 32 |
||||
LDAPResultAliasProblem = 33 |
||||
LDAPResultInvalidDNSyntax = 34 |
||||
LDAPResultAliasDereferencingProblem = 36 |
||||
LDAPResultInappropriateAuthentication = 48 |
||||
LDAPResultInvalidCredentials = 49 |
||||
LDAPResultInsufficientAccessRights = 50 |
||||
LDAPResultBusy = 51 |
||||
LDAPResultUnavailable = 52 |
||||
LDAPResultUnwillingToPerform = 53 |
||||
LDAPResultLoopDetect = 54 |
||||
LDAPResultNamingViolation = 64 |
||||
LDAPResultObjectClassViolation = 65 |
||||
LDAPResultNotAllowedOnNonLeaf = 66 |
||||
LDAPResultNotAllowedOnRDN = 67 |
||||
LDAPResultEntryAlreadyExists = 68 |
||||
LDAPResultObjectClassModsProhibited = 69 |
||||
LDAPResultAffectsMultipleDSAs = 71 |
||||
LDAPResultOther = 80 |
||||
|
||||
ErrorNetwork = 200 |
||||
ErrorFilterCompile = 201 |
||||
ErrorFilterDecompile = 202 |
||||
ErrorDebugging = 203 |
||||
) |
||||
|
||||
var LDAPResultCodeMap = map[uint8]string{ |
||||
LDAPResultSuccess: "Success", |
||||
LDAPResultOperationsError: "Operations Error", |
||||
LDAPResultProtocolError: "Protocol Error", |
||||
LDAPResultTimeLimitExceeded: "Time Limit Exceeded", |
||||
LDAPResultSizeLimitExceeded: "Size Limit Exceeded", |
||||
LDAPResultCompareFalse: "Compare False", |
||||
LDAPResultCompareTrue: "Compare True", |
||||
LDAPResultAuthMethodNotSupported: "Auth Method Not Supported", |
||||
LDAPResultStrongAuthRequired: "Strong Auth Required", |
||||
LDAPResultReferral: "Referral", |
||||
LDAPResultAdminLimitExceeded: "Admin Limit Exceeded", |
||||
LDAPResultUnavailableCriticalExtension: "Unavailable Critical Extension", |
||||
LDAPResultConfidentialityRequired: "Confidentiality Required", |
||||
LDAPResultSaslBindInProgress: "Sasl Bind In Progress", |
||||
LDAPResultNoSuchAttribute: "No Such Attribute", |
||||
LDAPResultUndefinedAttributeType: "Undefined Attribute Type", |
||||
LDAPResultInappropriateMatching: "Inappropriate Matching", |
||||
LDAPResultConstraintViolation: "Constraint Violation", |
||||
LDAPResultAttributeOrValueExists: "Attribute Or Value Exists", |
||||
LDAPResultInvalidAttributeSyntax: "Invalid Attribute Syntax", |
||||
LDAPResultNoSuchObject: "No Such Object", |
||||
LDAPResultAliasProblem: "Alias Problem", |
||||
LDAPResultInvalidDNSyntax: "Invalid DN Syntax", |
||||
LDAPResultAliasDereferencingProblem: "Alias Dereferencing Problem", |
||||
LDAPResultInappropriateAuthentication: "Inappropriate Authentication", |
||||
LDAPResultInvalidCredentials: "Invalid Credentials", |
||||
LDAPResultInsufficientAccessRights: "Insufficient Access Rights", |
||||
LDAPResultBusy: "Busy", |
||||
LDAPResultUnavailable: "Unavailable", |
||||
LDAPResultUnwillingToPerform: "Unwilling To Perform", |
||||
LDAPResultLoopDetect: "Loop Detect", |
||||
LDAPResultNamingViolation: "Naming Violation", |
||||
LDAPResultObjectClassViolation: "Object Class Violation", |
||||
LDAPResultNotAllowedOnNonLeaf: "Not Allowed On Non Leaf", |
||||
LDAPResultNotAllowedOnRDN: "Not Allowed On RDN", |
||||
LDAPResultEntryAlreadyExists: "Entry Already Exists", |
||||
LDAPResultObjectClassModsProhibited: "Object Class Mods Prohibited", |
||||
LDAPResultAffectsMultipleDSAs: "Affects Multiple DSAs", |
||||
LDAPResultOther: "Other", |
||||
} |
||||
|
||||
// Adds descriptions to an LDAP Response packet for debugging
|
||||
func addLDAPDescriptions(packet *ber.Packet) (err error) { |
||||
defer func() { |
||||
if r := recover(); r != nil { |
||||
err = NewError(ErrorDebugging, errors.New("ldap: cannot process packet to add descriptions")) |
||||
} |
||||
}() |
||||
packet.Description = "LDAP Response" |
||||
packet.Children[0].Description = "Message ID" |
||||
|
||||
application := packet.Children[1].Tag |
||||
packet.Children[1].Description = ApplicationMap[application] |
||||
|
||||
switch application { |
||||
case ApplicationBindRequest: |
||||
addRequestDescriptions(packet) |
||||
case ApplicationBindResponse: |
||||
addDefaultLDAPResponseDescriptions(packet) |
||||
case ApplicationUnbindRequest: |
||||
addRequestDescriptions(packet) |
||||
case ApplicationSearchRequest: |
||||
addRequestDescriptions(packet) |
||||
case ApplicationSearchResultEntry: |
||||
packet.Children[1].Children[0].Description = "Object Name" |
||||
packet.Children[1].Children[1].Description = "Attributes" |
||||
for _, child := range packet.Children[1].Children[1].Children { |
||||
child.Description = "Attribute" |
||||
child.Children[0].Description = "Attribute Name" |
||||
child.Children[1].Description = "Attribute Values" |
||||
for _, grandchild := range child.Children[1].Children { |
||||
grandchild.Description = "Attribute Value" |
||||
} |
||||
} |
||||
if len(packet.Children) == 3 { |
||||
addControlDescriptions(packet.Children[2]) |
||||
} |
||||
case ApplicationSearchResultDone: |
||||
addDefaultLDAPResponseDescriptions(packet) |
||||
case ApplicationModifyRequest: |
||||
addRequestDescriptions(packet) |
||||
case ApplicationModifyResponse: |
||||
case ApplicationAddRequest: |
||||
addRequestDescriptions(packet) |
||||
case ApplicationAddResponse: |
||||
case ApplicationDelRequest: |
||||
addRequestDescriptions(packet) |
||||
case ApplicationDelResponse: |
||||
case ApplicationModifyDNRequest: |
||||
addRequestDescriptions(packet) |
||||
case ApplicationModifyDNResponse: |
||||
case ApplicationCompareRequest: |
||||
addRequestDescriptions(packet) |
||||
case ApplicationCompareResponse: |
||||
case ApplicationAbandonRequest: |
||||
addRequestDescriptions(packet) |
||||
case ApplicationSearchResultReference: |
||||
case ApplicationExtendedRequest: |
||||
addRequestDescriptions(packet) |
||||
case ApplicationExtendedResponse: |
||||
} |
||||
|
||||
return nil |
||||
} |
||||
|
||||
func addControlDescriptions(packet *ber.Packet) { |
||||
packet.Description = "Controls" |
||||
for _, child := range packet.Children { |
||||
child.Description = "Control" |
||||
child.Children[0].Description = "Control Type (" + ControlTypeMap[child.Children[0].Value.(string)] + ")" |
||||
value := child.Children[1] |
||||
if len(child.Children) == 3 { |
||||
child.Children[1].Description = "Criticality" |
||||
value = child.Children[2] |
||||
} |
||||
value.Description = "Control Value" |
||||
|
||||
switch child.Children[0].Value.(string) { |
||||
case ControlTypePaging: |
||||
value.Description += " (Paging)" |
||||
if value.Value != nil { |
||||
valueChildren := ber.DecodePacket(value.Data.Bytes()) |
||||
value.Data.Truncate(0) |
||||
value.Value = nil |
||||
valueChildren.Children[1].Value = valueChildren.Children[1].Data.Bytes() |
||||
value.AppendChild(valueChildren) |
||||
} |
||||
value.Children[0].Description = "Real Search Control Value" |
||||
value.Children[0].Children[0].Description = "Paging Size" |
||||
value.Children[0].Children[1].Description = "Cookie" |
||||
} |
||||
} |
||||
} |
||||
|
||||
func addRequestDescriptions(packet *ber.Packet) { |
||||
packet.Description = "LDAP Request" |
||||
packet.Children[0].Description = "Message ID" |
||||
packet.Children[1].Description = ApplicationMap[packet.Children[1].Tag] |
||||
if len(packet.Children) == 3 { |
||||
addControlDescriptions(packet.Children[2]) |
||||
} |
||||
} |
||||
|
||||
func addDefaultLDAPResponseDescriptions(packet *ber.Packet) { |
||||
resultCode := packet.Children[1].Children[0].Value.(uint64) |
||||
packet.Children[1].Children[0].Description = "Result Code (" + LDAPResultCodeMap[uint8(resultCode)] + ")" |
||||
packet.Children[1].Children[1].Description = "Matched DN" |
||||
packet.Children[1].Children[2].Description = "Error Message" |
||||
if len(packet.Children[1].Children) > 3 { |
||||
packet.Children[1].Children[3].Description = "Referral" |
||||
} |
||||
if len(packet.Children) == 3 { |
||||
addControlDescriptions(packet.Children[2]) |
||||
} |
||||
} |
||||
|
||||
func DebugBinaryFile(fileName string) error { |
||||
file, err := ioutil.ReadFile(fileName) |
||||
if err != nil { |
||||
return NewError(ErrorDebugging, err) |
||||
} |
||||
ber.PrintBytes(file, "") |
||||
packet := ber.DecodePacket(file) |
||||
addLDAPDescriptions(packet) |
||||
ber.PrintPacket(packet) |
||||
|
||||
return nil |
||||
} |
||||
|
||||
type Error struct { |
||||
Err error |
||||
ResultCode uint8 |
||||
} |
||||
|
||||
func (e *Error) Error() string { |
||||
return fmt.Sprintf("LDAP Result Code %d %q: %s", e.ResultCode, LDAPResultCodeMap[e.ResultCode], e.Err.Error()) |
||||
} |
||||
|
||||
func NewError(resultCode uint8, err error) error { |
||||
return &Error{ResultCode: resultCode, Err: err} |
||||
} |
||||
|
||||
func getLDAPResultCode(packet *ber.Packet) (code uint8, description string) { |
||||
if len(packet.Children) >= 2 { |
||||
response := packet.Children[1] |
||||
if response.ClassType == ber.ClassApplication && response.TagType == ber.TypeConstructed && len(response.Children) == 3 { |
||||
return uint8(response.Children[0].Value.(uint64)), response.Children[2].Value.(string) |
||||
} |
||||
} |
||||
|
||||
return ErrorNetwork, "Invalid packet format" |
||||
} |
@ -0,0 +1,123 @@
|
||||
package ldap |
||||
|
||||
import ( |
||||
"fmt" |
||||
"testing" |
||||
) |
||||
|
||||
var ldapServer = "ldap.itd.umich.edu" |
||||
var ldapPort = uint16(389) |
||||
var baseDN = "dc=umich,dc=edu" |
||||
var filter = []string{ |
||||
"(cn=cis-fac)", |
||||
"(&(objectclass=rfc822mailgroup)(cn=*Computer*))", |
||||
"(&(objectclass=rfc822mailgroup)(cn=*Mathematics*))"} |
||||
var attributes = []string{ |
||||
"cn", |
||||
"description"} |
||||
|
||||
func TestConnect(t *testing.T) { |
||||
fmt.Printf("TestConnect: starting...\n") |
||||
l, err := Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort)) |
||||
if err != nil { |
||||
t.Errorf(err.Error()) |
||||
return |
||||
} |
||||
defer l.Close() |
||||
fmt.Printf("TestConnect: finished...\n") |
||||
} |
||||
|
||||
func TestSearch(t *testing.T) { |
||||
fmt.Printf("TestSearch: starting...\n") |
||||
l, err := Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort)) |
||||
if err != nil { |
||||
t.Errorf(err.Error()) |
||||
return |
||||
} |
||||
defer l.Close() |
||||
|
||||
searchRequest := NewSearchRequest( |
||||
baseDN, |
||||
ScopeWholeSubtree, DerefAlways, 0, 0, false, |
||||
filter[0], |
||||
attributes, |
||||
nil) |
||||
|
||||
sr, err := l.Search(searchRequest) |
||||
if err != nil { |
||||
t.Errorf(err.Error()) |
||||
return |
||||
} |
||||
|
||||
fmt.Printf("TestSearch: %s -> num of entries = %d\n", searchRequest.Filter, len(sr.Entries)) |
||||
} |
||||
|
||||
func TestSearchWithPaging(t *testing.T) { |
||||
fmt.Printf("TestSearchWithPaging: starting...\n") |
||||
l, err := Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort)) |
||||
if err != nil { |
||||
t.Errorf(err.Error()) |
||||
return |
||||
} |
||||
defer l.Close() |
||||
|
||||
err = l.Bind("", "") |
||||
if err != nil { |
||||
t.Errorf(err.Error()) |
||||
return |
||||
} |
||||
|
||||
searchRequest := NewSearchRequest( |
||||
baseDN, |
||||
ScopeWholeSubtree, DerefAlways, 0, 0, false, |
||||
filter[1], |
||||
attributes, |
||||
nil) |
||||
sr, err := l.SearchWithPaging(searchRequest, 5) |
||||
if err != nil { |
||||
t.Errorf(err.Error()) |
||||
return |
||||
} |
||||
|
||||
fmt.Printf("TestSearchWithPaging: %s -> num of entries = %d\n", searchRequest.Filter, len(sr.Entries)) |
||||
} |
||||
|
||||
func testMultiGoroutineSearch(t *testing.T, l *Conn, results chan *SearchResult, i int) { |
||||
searchRequest := NewSearchRequest( |
||||
baseDN, |
||||
ScopeWholeSubtree, DerefAlways, 0, 0, false, |
||||
filter[i], |
||||
attributes, |
||||
nil) |
||||
sr, err := l.Search(searchRequest) |
||||
if err != nil { |
||||
t.Errorf(err.Error()) |
||||
results <- nil |
||||
return |
||||
} |
||||
results <- sr |
||||
} |
||||
|
||||
func TestMultiGoroutineSearch(t *testing.T) { |
||||
fmt.Printf("TestMultiGoroutineSearch: starting...\n") |
||||
l, err := Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort)) |
||||
if err != nil { |
||||
t.Errorf(err.Error()) |
||||
return |
||||
} |
||||
defer l.Close() |
||||
|
||||
results := make([]chan *SearchResult, len(filter)) |
||||
for i := range filter { |
||||
results[i] = make(chan *SearchResult) |
||||
go testMultiGoroutineSearch(t, l, results[i], i) |
||||
} |
||||
for i := range filter { |
||||
sr := <-results[i] |
||||
if sr == nil { |
||||
t.Errorf("Did not receive results from goroutine for %q", filter[i]) |
||||
} else { |
||||
fmt.Printf("TestMultiGoroutineSearch(%d): %s -> num of entries = %d\n", i, filter[i], len(sr.Entries)) |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,156 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
//
|
||||
// File contains Modify functionality
|
||||
//
|
||||
// https://tools.ietf.org/html/rfc4511
|
||||
//
|
||||
// ModifyRequest ::= [APPLICATION 6] SEQUENCE {
|
||||
// object LDAPDN,
|
||||
// changes SEQUENCE OF change SEQUENCE {
|
||||
// operation ENUMERATED {
|
||||
// add (0),
|
||||
// delete (1),
|
||||
// replace (2),
|
||||
// ... },
|
||||
// modification PartialAttribute } }
|
||||
//
|
||||
// PartialAttribute ::= SEQUENCE {
|
||||
// type AttributeDescription,
|
||||
// vals SET OF value AttributeValue }
|
||||
//
|
||||
// AttributeDescription ::= LDAPString
|
||||
// -- Constrained to <attributedescription>
|
||||
// -- [RFC4512]
|
||||
//
|
||||
// AttributeValue ::= OCTET STRING
|
||||
//
|
||||
|
||||
package ldap |
||||
|
||||
import ( |
||||
"errors" |
||||
"log" |
||||
|
||||
"github.com/gogits/gogs/modules/asn1-ber" |
||||
) |
||||
|
||||
const ( |
||||
AddAttribute = 0 |
||||
DeleteAttribute = 1 |
||||
ReplaceAttribute = 2 |
||||
) |
||||
|
||||
type PartialAttribute struct { |
||||
attrType string |
||||
attrVals []string |
||||
} |
||||
|
||||
func (p *PartialAttribute) encode() *ber.Packet { |
||||
seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "PartialAttribute") |
||||
seq.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, p.attrType, "Type")) |
||||
set := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSet, nil, "AttributeValue") |
||||
for _, value := range p.attrVals { |
||||
set.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, value, "Vals")) |
||||
} |
||||
seq.AppendChild(set) |
||||
return seq |
||||
} |
||||
|
||||
type ModifyRequest struct { |
||||
dn string |
||||
addAttributes []PartialAttribute |
||||
deleteAttributes []PartialAttribute |
||||
replaceAttributes []PartialAttribute |
||||
} |
||||
|
||||
func (m *ModifyRequest) Add(attrType string, attrVals []string) { |
||||
m.addAttributes = append(m.addAttributes, PartialAttribute{attrType: attrType, attrVals: attrVals}) |
||||
} |
||||
|
||||
func (m *ModifyRequest) Delete(attrType string, attrVals []string) { |
||||
m.deleteAttributes = append(m.deleteAttributes, PartialAttribute{attrType: attrType, attrVals: attrVals}) |
||||
} |
||||
|
||||
func (m *ModifyRequest) Replace(attrType string, attrVals []string) { |
||||
m.replaceAttributes = append(m.replaceAttributes, PartialAttribute{attrType: attrType, attrVals: attrVals}) |
||||
} |
||||
|
||||
func (m ModifyRequest) encode() *ber.Packet { |
||||
request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationModifyRequest, nil, "Modify Request") |
||||
request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, m.dn, "DN")) |
||||
changes := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Changes") |
||||
for _, attribute := range m.addAttributes { |
||||
change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change") |
||||
change.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(AddAttribute), "Operation")) |
||||
change.AppendChild(attribute.encode()) |
||||
changes.AppendChild(change) |
||||
} |
||||
for _, attribute := range m.deleteAttributes { |
||||
change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change") |
||||
change.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(DeleteAttribute), "Operation")) |
||||
change.AppendChild(attribute.encode()) |
||||
changes.AppendChild(change) |
||||
} |
||||
for _, attribute := range m.replaceAttributes { |
||||
change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change") |
||||
change.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(ReplaceAttribute), "Operation")) |
||||
change.AppendChild(attribute.encode()) |
||||
changes.AppendChild(change) |
||||
} |
||||
request.AppendChild(changes) |
||||
return request |
||||
} |
||||
|
||||
func NewModifyRequest( |
||||
dn string, |
||||
) *ModifyRequest { |
||||
return &ModifyRequest{ |
||||
dn: dn, |
||||
} |
||||
} |
||||
|
||||
func (l *Conn) Modify(modifyRequest *ModifyRequest) error { |
||||
messageID := l.nextMessageID() |
||||
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") |
||||
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, messageID, "MessageID")) |
||||
packet.AppendChild(modifyRequest.encode()) |
||||
|
||||
l.Debug.PrintPacket(packet) |
||||
|
||||
channel, err := l.sendMessage(packet) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
if channel == nil { |
||||
return NewError(ErrorNetwork, errors.New("ldap: could not send message")) |
||||
} |
||||
defer l.finishMessage(messageID) |
||||
|
||||
l.Debug.Printf("%d: waiting for response", messageID) |
||||
packet = <-channel |
||||
l.Debug.Printf("%d: got response %p", messageID, packet) |
||||
if packet == nil { |
||||
return NewError(ErrorNetwork, errors.New("ldap: could not retrieve message")) |
||||
} |
||||
|
||||
if l.Debug { |
||||
if err := addLDAPDescriptions(packet); err != nil { |
||||
return err |
||||
} |
||||
ber.PrintPacket(packet) |
||||
} |
||||
|
||||
if packet.Children[1].Tag == ApplicationModifyResponse { |
||||
resultCode, resultDescription := getLDAPResultCode(packet) |
||||
if resultCode != 0 { |
||||
return NewError(resultCode, errors.New(resultDescription)) |
||||
} |
||||
} else { |
||||
log.Printf("Unexpected Response: %d", packet.Children[1].Tag) |
||||
} |
||||
|
||||
l.Debug.Printf("%d: returning", messageID) |
||||
return nil |
||||
} |
@ -0,0 +1,350 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
//
|
||||
// File contains Search functionality
|
||||
//
|
||||
// https://tools.ietf.org/html/rfc4511
|
||||
//
|
||||
// SearchRequest ::= [APPLICATION 3] SEQUENCE {
|
||||
// baseObject LDAPDN,
|
||||
// scope ENUMERATED {
|
||||
// baseObject (0),
|
||||
// singleLevel (1),
|
||||
// wholeSubtree (2),
|
||||
// ... },
|
||||
// derefAliases ENUMERATED {
|
||||
// neverDerefAliases (0),
|
||||
// derefInSearching (1),
|
||||
// derefFindingBaseObj (2),
|
||||
// derefAlways (3) },
|
||||
// sizeLimit INTEGER (0 .. maxInt),
|
||||
// timeLimit INTEGER (0 .. maxInt),
|
||||
// typesOnly BOOLEAN,
|
||||
// filter Filter,
|
||||
// attributes AttributeSelection }
|
||||
//
|
||||
// AttributeSelection ::= SEQUENCE OF selector LDAPString
|
||||
// -- The LDAPString is constrained to
|
||||
// -- <attributeSelector> in Section 4.5.1.8
|
||||
//
|
||||
// Filter ::= CHOICE {
|
||||
// and [0] SET SIZE (1..MAX) OF filter Filter,
|
||||
// or [1] SET SIZE (1..MAX) OF filter Filter,
|
||||
// not [2] Filter,
|
||||
// equalityMatch [3] AttributeValueAssertion,
|
||||
// substrings [4] SubstringFilter,
|
||||
// greaterOrEqual [5] AttributeValueAssertion,
|
||||
// lessOrEqual [6] AttributeValueAssertion,
|
||||
// present [7] AttributeDescription,
|
||||
// approxMatch [8] AttributeValueAssertion,
|
||||
// extensibleMatch [9] MatchingRuleAssertion,
|
||||
// ... }
|
||||
//
|
||||
// SubstringFilter ::= SEQUENCE {
|
||||
// type AttributeDescription,
|
||||
// substrings SEQUENCE SIZE (1..MAX) OF substring CHOICE {
|
||||
// initial [0] AssertionValue, -- can occur at most once
|
||||
// any [1] AssertionValue,
|
||||
// final [2] AssertionValue } -- can occur at most once
|
||||
// }
|
||||
//
|
||||
// MatchingRuleAssertion ::= SEQUENCE {
|
||||
// matchingRule [1] MatchingRuleId OPTIONAL,
|
||||
// type [2] AttributeDescription OPTIONAL,
|
||||
// matchValue [3] AssertionValue,
|
||||
// dnAttributes [4] BOOLEAN DEFAULT FALSE }
|
||||
//
|
||||
//
|
||||
|
||||
package ldap |
||||
|
||||
import ( |
||||
"errors" |
||||
"fmt" |
||||
"strings" |
||||
|
||||
"github.com/gogits/gogs/modules/asn1-ber" |
||||
) |
||||
|
||||
const ( |
||||
ScopeBaseObject = 0 |
||||
ScopeSingleLevel = 1 |
||||
ScopeWholeSubtree = 2 |
||||
) |
||||
|
||||
var ScopeMap = map[int]string{ |
||||
ScopeBaseObject: "Base Object", |
||||
ScopeSingleLevel: "Single Level", |
||||
ScopeWholeSubtree: "Whole Subtree", |
||||
} |
||||
|
||||
const ( |
||||
NeverDerefAliases = 0 |
||||
DerefInSearching = 1 |
||||
DerefFindingBaseObj = 2 |
||||
DerefAlways = 3 |
||||
) |
||||
|
||||
var DerefMap = map[int]string{ |
||||
NeverDerefAliases: "NeverDerefAliases", |
||||
DerefInSearching: "DerefInSearching", |
||||
DerefFindingBaseObj: "DerefFindingBaseObj", |
||||
DerefAlways: "DerefAlways", |
||||
} |
||||
|
||||
type Entry struct { |
||||
DN string |
||||
Attributes []*EntryAttribute |
||||
} |
||||
|
||||
func (e *Entry) GetAttributeValues(attribute string) []string { |
||||
for _, attr := range e.Attributes { |
||||
if attr.Name == attribute { |
||||
return attr.Values |
||||
} |
||||
} |
||||
return []string{} |
||||
} |
||||
|
||||
func (e *Entry) GetAttributeValue(attribute string) string { |
||||
values := e.GetAttributeValues(attribute) |
||||
if len(values) == 0 { |
||||
return "" |
||||
} |
||||
return values[0] |
||||
} |
||||
|
||||
func (e *Entry) Print() { |
||||
fmt.Printf("DN: %s\n", e.DN) |
||||
for _, attr := range e.Attributes { |
||||
attr.Print() |
||||
} |
||||
} |
||||
|
||||
func (e *Entry) PrettyPrint(indent int) { |
||||
fmt.Printf("%sDN: %s\n", strings.Repeat(" ", indent), e.DN) |
||||
for _, attr := range e.Attributes { |
||||
attr.PrettyPrint(indent + 2) |
||||
} |
||||
} |
||||
|
||||
type EntryAttribute struct { |
||||
Name string |
||||
Values []string |
||||
} |
||||
|
||||
func (e *EntryAttribute) Print() { |
||||
fmt.Printf("%s: %s\n", e.Name, e.Values) |
||||
} |
||||
|
||||
func (e *EntryAttribute) PrettyPrint(indent int) { |
||||
fmt.Printf("%s%s: %s\n", strings.Repeat(" ", indent), e.Name, e.Values) |
||||
} |
||||
|
||||
type SearchResult struct { |
||||
Entries []*Entry |
||||
Referrals []string |
||||
Controls []Control |
||||
} |
||||
|
||||
func (s *SearchResult) Print() { |
||||
for _, entry := range s.Entries { |
||||
entry.Print() |
||||
} |
||||
} |
||||
|
||||
func (s *SearchResult) PrettyPrint(indent int) { |
||||
for _, entry := range s.Entries { |
||||
entry.PrettyPrint(indent) |
||||
} |
||||
} |
||||
|
||||
type SearchRequest struct { |
||||
BaseDN string |
||||
Scope int |
||||
DerefAliases int |
||||
SizeLimit int |
||||
TimeLimit int |
||||
TypesOnly bool |
||||
Filter string |
||||
Attributes []string |
||||
Controls []Control |
||||
} |
||||
|
||||
func (s *SearchRequest) encode() (*ber.Packet, error) { |
||||
request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationSearchRequest, nil, "Search Request") |
||||
request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, s.BaseDN, "Base DN")) |
||||
request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(s.Scope), "Scope")) |
||||
request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(s.DerefAliases), "Deref Aliases")) |
||||
request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, uint64(s.SizeLimit), "Size Limit")) |
||||
request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, uint64(s.TimeLimit), "Time Limit")) |
||||
request.AppendChild(ber.NewBoolean(ber.ClassUniversal, ber.TypePrimitive, ber.TagBoolean, s.TypesOnly, "Types Only")) |
||||
// compile and encode filter
|
||||
filterPacket, err := CompileFilter(s.Filter) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
request.AppendChild(filterPacket) |
||||
// encode attributes
|
||||
attributesPacket := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Attributes") |
||||
for _, attribute := range s.Attributes { |
||||
attributesPacket.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, attribute, "Attribute")) |
||||
} |
||||
request.AppendChild(attributesPacket) |
||||
return request, nil |
||||
} |
||||
|
||||
func NewSearchRequest( |
||||
BaseDN string, |
||||
Scope, DerefAliases, SizeLimit, TimeLimit int, |
||||
TypesOnly bool, |
||||
Filter string, |
||||
Attributes []string, |
||||
Controls []Control, |
||||
) *SearchRequest { |
||||
return &SearchRequest{ |
||||
BaseDN: BaseDN, |
||||
Scope: Scope, |
||||
DerefAliases: DerefAliases, |
||||
SizeLimit: SizeLimit, |
||||
TimeLimit: TimeLimit, |
||||
TypesOnly: TypesOnly, |
||||
Filter: Filter, |
||||
Attributes: Attributes, |
||||
Controls: Controls, |
||||
} |
||||
} |
||||
|
||||
func (l *Conn) SearchWithPaging(searchRequest *SearchRequest, pagingSize uint32) (*SearchResult, error) { |
||||
if searchRequest.Controls == nil { |
||||
searchRequest.Controls = make([]Control, 0) |
||||
} |
||||
|
||||
pagingControl := NewControlPaging(pagingSize) |
||||
searchRequest.Controls = append(searchRequest.Controls, pagingControl) |
||||
searchResult := new(SearchResult) |
||||
for { |
||||
result, err := l.Search(searchRequest) |
||||
l.Debug.Printf("Looking for Paging Control...") |
||||
if err != nil { |
||||
return searchResult, err |
||||
} |
||||
if result == nil { |
||||
return searchResult, NewError(ErrorNetwork, errors.New("ldap: packet not received")) |
||||
} |
||||
|
||||
for _, entry := range result.Entries { |
||||
searchResult.Entries = append(searchResult.Entries, entry) |
||||
} |
||||
for _, referral := range result.Referrals { |
||||
searchResult.Referrals = append(searchResult.Referrals, referral) |
||||
} |
||||
for _, control := range result.Controls { |
||||
searchResult.Controls = append(searchResult.Controls, control) |
||||
} |
||||
|
||||
l.Debug.Printf("Looking for Paging Control...") |
||||
pagingResult := FindControl(result.Controls, ControlTypePaging) |
||||
if pagingResult == nil { |
||||
pagingControl = nil |
||||
l.Debug.Printf("Could not find paging control. Breaking...") |
||||
break |
||||
} |
||||
|
||||
cookie := pagingResult.(*ControlPaging).Cookie |
||||
if len(cookie) == 0 { |
||||
pagingControl = nil |
||||
l.Debug.Printf("Could not find cookie. Breaking...") |
||||
break |
||||
} |
||||
pagingControl.SetCookie(cookie) |
||||
} |
||||
|
||||
if pagingControl != nil { |
||||
l.Debug.Printf("Abandoning Paging...") |
||||
pagingControl.PagingSize = 0 |
||||
l.Search(searchRequest) |
||||
} |
||||
|
||||
return searchResult, nil |
||||
} |
||||
|
||||
func (l *Conn) Search(searchRequest *SearchRequest) (*SearchResult, error) { |
||||
messageID := l.nextMessageID() |
||||
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") |
||||
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, messageID, "MessageID")) |
||||
// encode search request
|
||||
encodedSearchRequest, err := searchRequest.encode() |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
packet.AppendChild(encodedSearchRequest) |
||||
// encode search controls
|
||||
if searchRequest.Controls != nil { |
||||
packet.AppendChild(encodeControls(searchRequest.Controls)) |
||||
} |
||||
|
||||
l.Debug.PrintPacket(packet) |
||||
|
||||
channel, err := l.sendMessage(packet) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
if channel == nil { |
||||
return nil, NewError(ErrorNetwork, errors.New("ldap: could not send message")) |
||||
} |
||||
defer l.finishMessage(messageID) |
||||
|
||||
result := &SearchResult{ |
||||
Entries: make([]*Entry, 0), |
||||
Referrals: make([]string, 0), |
||||
Controls: make([]Control, 0)} |
||||
|
||||
foundSearchResultDone := false |
||||
for !foundSearchResultDone { |
||||
l.Debug.Printf("%d: waiting for response", messageID) |
||||
packet = <-channel |
||||
l.Debug.Printf("%d: got response %p", messageID, packet) |
||||
if packet == nil { |
||||
return nil, NewError(ErrorNetwork, errors.New("ldap: could not retrieve message")) |
||||
} |
||||
|
||||
if l.Debug { |
||||
if err := addLDAPDescriptions(packet); err != nil { |
||||
return nil, err |
||||
} |
||||
ber.PrintPacket(packet) |
||||
} |
||||
|
||||
switch packet.Children[1].Tag { |
||||
case 4: |
||||
entry := new(Entry) |
||||
entry.DN = packet.Children[1].Children[0].Value.(string) |
||||
for _, child := range packet.Children[1].Children[1].Children { |
||||
attr := new(EntryAttribute) |
||||
attr.Name = child.Children[0].Value.(string) |
||||
for _, value := range child.Children[1].Children { |
||||
attr.Values = append(attr.Values, value.Value.(string)) |
||||
} |
||||
entry.Attributes = append(entry.Attributes, attr) |
||||
} |
||||
result.Entries = append(result.Entries, entry) |
||||
case 5: |
||||
resultCode, resultDescription := getLDAPResultCode(packet) |
||||
if resultCode != 0 { |
||||
return result, NewError(resultCode, errors.New(resultDescription)) |
||||
} |
||||
if len(packet.Children) == 3 { |
||||
for _, child := range packet.Children[2].Children { |
||||
result.Controls = append(result.Controls, DecodeControl(child)) |
||||
} |
||||
} |
||||
foundSearchResultDone = true |
||||
case 19: |
||||
result.Referrals = append(result.Referrals, packet.Children[1].Children[0].Value.(string)) |
||||
} |
||||
} |
||||
l.Debug.Printf("%d: returning", messageID) |
||||
return result, nil |
||||
} |
@ -0,0 +1,844 @@
|
||||
package mahonia |
||||
|
||||
import ( |
||||
"fmt" |
||||
"sync" |
||||
) |
||||
|
||||
// Converters for simple 8-bit character sets.
|
||||
|
||||
type eightBitInfo struct { |
||||
Name string |
||||
Aliases []string |
||||
|
||||
// the character used for characters that can't be converted
|
||||
SubstitutionChar byte |
||||
|
||||
// a string containing all 256 characters, in order.
|
||||
Repertoire string |
||||
|
||||
// used to synchronize unpacking Repertoire into the conversion tables
|
||||
once *sync.Once |
||||
|
||||
// true if the first 128 characters are the same as US-ASCII
|
||||
asciiCompatible bool |
||||
|
||||
byte2char [256]rune |
||||
char2byte map[rune]byte |
||||
} |
||||
|
||||
const asciiRepertoire = "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f" |
||||
|
||||
func (info *eightBitInfo) register() { |
||||
var cs Charset |
||||
cs.Name = info.Name |
||||
cs.Aliases = info.Aliases |
||||
|
||||
info.once = new(sync.Once) |
||||
|
||||
cs.NewDecoder = func() Decoder { |
||||
info.once.Do(func() { info.unpack() }) |
||||
|
||||
return func(p []byte) (c rune, size int, status Status) { |
||||
if len(p) == 0 { |
||||
status = NO_ROOM |
||||
return |
||||
} |
||||
|
||||
c = info.byte2char[p[0]] |
||||
|
||||
if c == 0xfffd { |
||||
status = INVALID_CHAR |
||||
} else { |
||||
status = SUCCESS |
||||
} |
||||
|
||||
size = 1 |
||||
return |
||||
} |
||||
} |
||||
|
||||
cs.NewEncoder = func() Encoder { |
||||
info.once.Do(func() { info.unpack() }) |
||||
|
||||
return func(p []byte, c rune) (size int, status Status) { |
||||
if len(p) == 0 { |
||||
status = NO_ROOM |
||||
return |
||||
} |
||||
|
||||
if c < 128 && info.asciiCompatible { |
||||
p[0] = byte(c) |
||||
return 1, SUCCESS |
||||
} |
||||
|
||||
b, ok := info.char2byte[c] |
||||
if !ok { |
||||
b = info.SubstitutionChar |
||||
status = INVALID_CHAR |
||||
} else { |
||||
status = SUCCESS |
||||
} |
||||
p[0] = b |
||||
size = 1 |
||||
return |
||||
} |
||||
} |
||||
|
||||
RegisterCharset(&cs) |
||||
} |
||||
|
||||
func (info *eightBitInfo) unpack() { |
||||
info.asciiCompatible = info.Repertoire[:128] == asciiRepertoire |
||||
|
||||
info.char2byte = make(map[rune]byte, 256) |
||||
i := 0 |
||||
for _, c := range info.Repertoire { |
||||
info.byte2char[i] = c |
||||
if c != 0xfffd { |
||||
info.char2byte[c] = byte(i) |
||||
} |
||||
i++ |
||||
} |
||||
if i != 256 { |
||||
panic(fmt.Errorf("%s has only %d characters", info.Name, i)) |
||||
} |
||||
} |
||||
|
||||
func init() { |
||||
for i := 0; i < len(eightBitCharsets); i++ { |
||||
eightBitCharsets[i].register() |
||||
} |
||||
} |
||||
|
||||
var eightBitCharsets = []eightBitInfo{ |
||||
{ |
||||
Name: "ISO-8859-2", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0104\u02d8\u0141\u00a4\u013d\u015a\u00a7\u00a8\u0160\u015e\u0164\u0179\u00ad\u017d\u017b\u00b0\u0105\u02db\u0142\u00b4\u013e\u015b\u02c7\u00b8\u0161\u015f\u0165\u017a\u02dd\u017e\u017c\u0154\u00c1\u00c2\u0102\u00c4\u0139\u0106\u00c7\u010c\u00c9\u0118\u00cb\u011a\u00cd\u00ce\u010e\u0110\u0143\u0147\u00d3\u00d4\u0150\u00d6\u00d7\u0158\u016e\u00da\u0170\u00dc\u00dd\u0162\u00df\u0155\u00e1\u00e2\u0103\u00e4\u013a\u0107\u00e7\u010d\u00e9\u0119\u00eb\u011b\u00ed\u00ee\u010f\u0111\u0144\u0148\u00f3\u00f4\u0151\u00f6\u00f7\u0159\u016f\u00fa\u0171\u00fc\u00fd\u0163\u02d9", |
||||
Aliases: []string{"ISO_8859-2:1987", "iso-ir-101", "latin2", "l2", "csISOLatin2"}, |
||||
}, |
||||
{ |
||||
Name: "ISO-8859-3", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0126\u02d8\u00a3\u00a4\ufffd\u0124\u00a7\u00a8\u0130\u015e\u011e\u0134\u00ad\ufffd\u017b\u00b0\u0127\u00b2\u00b3\u00b4\u00b5\u0125\u00b7\u00b8\u0131\u015f\u011f\u0135\u00bd\ufffd\u017c\u00c0\u00c1\u00c2\ufffd\u00c4\u010a\u0108\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\ufffd\u00d1\u00d2\u00d3\u00d4\u0120\u00d6\u00d7\u011c\u00d9\u00da\u00db\u00dc\u016c\u015c\u00df\u00e0\u00e1\u00e2\ufffd\u00e4\u010b\u0109\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\ufffd\u00f1\u00f2\u00f3\u00f4\u0121\u00f6\u00f7\u011d\u00f9\u00fa\u00fb\u00fc\u016d\u015d\u02d9", |
||||
Aliases: []string{"ISO_8859-3:1988", "iso-ir-109", "latin3", "l3", "csISOLatin3"}, |
||||
}, |
||||
{ |
||||
Name: "ISO-8859-4", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0104\u0138\u0156\u00a4\u0128\u013b\u00a7\u00a8\u0160\u0112\u0122\u0166\u00ad\u017d\u00af\u00b0\u0105\u02db\u0157\u00b4\u0129\u013c\u02c7\u00b8\u0161\u0113\u0123\u0167\u014a\u017e\u014b\u0100\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u012e\u010c\u00c9\u0118\u00cb\u0116\u00cd\u00ce\u012a\u0110\u0145\u014c\u0136\u00d4\u00d5\u00d6\u00d7\u00d8\u0172\u00da\u00db\u00dc\u0168\u016a\u00df\u0101\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u012f\u010d\u00e9\u0119\u00eb\u0117\u00ed\u00ee\u012b\u0111\u0146\u014d\u0137\u00f4\u00f5\u00f6\u00f7\u00f8\u0173\u00fa\u00fb\u00fc\u0169\u016b\u02d9", |
||||
Aliases: []string{"ISO_8859-4:1988", "iso-ir-110", "latin4", "l4", "csISOLatin4"}, |
||||
}, |
||||
{ |
||||
Name: "ISO-8859-5", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0401\u0402\u0403\u0404\u0405\u0406\u0407\u0408\u0409\u040a\u040b\u040c\u00ad\u040e\u040f\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\u2116\u0451\u0452\u0453\u0454\u0455\u0456\u0457\u0458\u0459\u045a\u045b\u045c\u00a7\u045e\u045f", |
||||
Aliases: []string{"ISO_8859-5:1988", "iso-ir-144", "cyrillic", "csISOLatinCyrillic"}, |
||||
}, |
||||
{ |
||||
Name: "ISO-8859-6", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\ufffd\ufffd\ufffd\u00a4\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u060c\u00ad\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u061b\ufffd\ufffd\ufffd\u061f\ufffd\u0621\u0622\u0623\u0624\u0625\u0626\u0627\u0628\u0629\u062a\u062b\u062c\u062d\u062e\u062f\u0630\u0631\u0632\u0633\u0634\u0635\u0636\u0637\u0638\u0639\u063a\ufffd\ufffd\ufffd\ufffd\ufffd\u0640\u0641\u0642\u0643\u0644\u0645\u0646\u0647\u0648\u0649\u064a\u064b\u064c\u064d\u064e\u064f\u0650\u0651\u0652\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd", |
||||
Aliases: []string{"ISO_8859-6:1987", "iso-ir-127", "ECMA-114", "ASMO-708", "arabic", "csISOLatinArabic"}, |
||||
}, |
||||
{ |
||||
Name: "ISO-8859-7", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u2018\u2019\u00a3\u20ac\u20af\u00a6\u00a7\u00a8\u00a9\u037a\u00ab\u00ac\u00ad\ufffd\u2015\u00b0\u00b1\u00b2\u00b3\u0384\u0385\u0386\u00b7\u0388\u0389\u038a\u00bb\u038c\u00bd\u038e\u038f\u0390\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\ufffd\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa\u03ab\u03ac\u03ad\u03ae\u03af\u03b0\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9\u03ca\u03cb\u03cc\u03cd\u03ce\ufffd", |
||||
Aliases: []string{"ISO_8859-7:2003", "iso-ir-126", "ELOT_928", "ECMA-118", "greek", "greek8", "csISOLatinGreek"}, |
||||
}, |
||||
{ |
||||
Name: "ISO-8859-8", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\ufffd\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u00d7\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00f7\u00bb\u00bc\u00bd\u00be\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u2017\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\ufffd\ufffd\u200e\u200f\ufffd", |
||||
Aliases: []string{"ISO_8859-8:1999", "iso-ir-138", "hebrew", "csISOLatinHebrew"}, |
||||
}, |
||||
{ |
||||
Name: "ISO-8859-9", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u00a1\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00ba\u00bb\u00bc\u00bd\u00be\u00bf\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u011e\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u0130\u015e\u00df\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u011f\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u0131\u015f\u00ff", |
||||
Aliases: []string{"ISO_8859-9:1999", "iso-ir-148", "latin5", "l5", "csISOLatin5"}, |
||||
}, |
||||
{ |
||||
Name: "ISO-8859-10", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0104\u0112\u0122\u012a\u0128\u0136\u00a7\u013b\u0110\u0160\u0166\u017d\u00ad\u016a\u014a\u00b0\u0105\u0113\u0123\u012b\u0129\u0137\u00b7\u013c\u0111\u0161\u0167\u017e\u2015\u016b\u014b\u0100\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u012e\u010c\u00c9\u0118\u00cb\u0116\u00cd\u00ce\u00cf\u00d0\u0145\u014c\u00d3\u00d4\u00d5\u00d6\u0168\u00d8\u0172\u00da\u00db\u00dc\u00dd\u00de\u00df\u0101\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u012f\u010d\u00e9\u0119\u00eb\u0117\u00ed\u00ee\u00ef\u00f0\u0146\u014d\u00f3\u00f4\u00f5\u00f6\u0169\u00f8\u0173\u00fa\u00fb\u00fc\u00fd\u00fe\u0138", |
||||
Aliases: []string{"iso_8859-10:1992", "l6", "iso-ir-157", "latin6", "csISOLatin6"}, |
||||
}, |
||||
{ |
||||
Name: "ISO-8859-11", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0e01\u0e02\u0e03\u0e04\u0e05\u0e06\u0e07\u0e08\u0e09\u0e0a\u0e0b\u0e0c\u0e0d\u0e0e\u0e0f\u0e10\u0e11\u0e12\u0e13\u0e14\u0e15\u0e16\u0e17\u0e18\u0e19\u0e1a\u0e1b\u0e1c\u0e1d\u0e1e\u0e1f\u0e20\u0e21\u0e22\u0e23\u0e24\u0e25\u0e26\u0e27\u0e28\u0e29\u0e2a\u0e2b\u0e2c\u0e2d\u0e2e\u0e2f\u0e30\u0e31\u0e32\u0e33\u0e34\u0e35\u0e36\u0e37\u0e38\u0e39\u0e3a\ufffd\ufffd\ufffd\ufffd\u0e3f\u0e40\u0e41\u0e42\u0e43\u0e44\u0e45\u0e46\u0e47\u0e48\u0e49\u0e4a\u0e4b\u0e4c\u0e4d\u0e4e\u0e4f\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0e5a\u0e5b\ufffd\ufffd\ufffd\ufffd", |
||||
Aliases: []string{"iso_8859-11:2001", "Latin/Thai", "TIS-620"}, |
||||
}, |
||||
{ |
||||
Name: "ISO-8859-13", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u201d\u00a2\u00a3\u00a4\u201e\u00a6\u00a7\u00d8\u00a9\u0156\u00ab\u00ac\u00ad\u00ae\u00c6\u00b0\u00b1\u00b2\u00b3\u201c\u00b5\u00b6\u00b7\u00f8\u00b9\u0157\u00bb\u00bc\u00bd\u00be\u00e6\u0104\u012e\u0100\u0106\u00c4\u00c5\u0118\u0112\u010c\u00c9\u0179\u0116\u0122\u0136\u012a\u013b\u0160\u0143\u0145\u00d3\u014c\u00d5\u00d6\u00d7\u0172\u0141\u015a\u016a\u00dc\u017b\u017d\u00df\u0105\u012f\u0101\u0107\u00e4\u00e5\u0119\u0113\u010d\u00e9\u017a\u0117\u0123\u0137\u012b\u013c\u0161\u0144\u0146\u00f3\u014d\u00f5\u00f6\u00f7\u0173\u0142\u015b\u016b\u00fc\u017c\u017e\u2019", |
||||
Aliases: []string{"latin7", "Baltic Rim"}, |
||||
}, |
||||
{ |
||||
Name: "ISO-8859-14", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u1e02\u1e03\u00a3\u010a\u010b\u1e0a\u00a7\u1e80\u00a9\u1e82\u1e0b\u1ef2\u00ad\u00ae\u0178\u1e1e\u1e1f\u0120\u0121\u1e40\u1e41\u00b6\u1e56\u1e81\u1e57\u1e83\u1e60\u1ef3\u1e84\u1e85\u1e61\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u0174\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u1e6a\u00d8\u00d9\u00da\u00db\u00dc\u00dd\u0176\u00df\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u0175\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u1e6b\u00f8\u00f9\u00fa\u00fb\u00fc\u00fd\u0177\u00ff", |
||||
Aliases: []string{"iso-ir-199", "ISO_8859-14:1998", "latin8", "iso-celtic", "l8"}, |
||||
}, |
||||
{ |
||||
Name: "ISO-8859-15", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u00a1\u00a2\u00a3\u20ac\u00a5\u0160\u00a7\u0161\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u017d\u00b5\u00b6\u00b7\u017e\u00b9\u00ba\u00bb\u0152\u0153\u0178\u00bf\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u00d0\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u00dd\u00de\u00df\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u00f0\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u00fd\u00fe\u00ff", |
||||
Aliases: []string{"Latin-9"}, |
||||
}, |
||||
{ |
||||
Name: "ISO-8859-16", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0104\u0105\u0141\u20ac\u201e\u0160\u00a7\u0161\u00a9\u0218\u00ab\u0179\u00ad\u017a\u017b\u00b0\u00b1\u010c\u0142\u017d\u201d\u00b6\u00b7\u017e\u010d\u0219\u00bb\u0152\u0153\u0178\u017c\u00c0\u00c1\u00c2\u0102\u00c4\u0106\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u0110\u0143\u00d2\u00d3\u00d4\u0150\u00d6\u015a\u0170\u00d9\u00da\u00db\u00dc\u0118\u021a\u00df\u00e0\u00e1\u00e2\u0103\u00e4\u0107\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u0111\u0144\u00f2\u00f3\u00f4\u0151\u00f6\u015b\u0171\u00f9\u00fa\u00fb\u00fc\u0119\u021b\u00ff", |
||||
Aliases: []string{"iso-ir-226", "ISO_8859-16:2001", "latin10", "l10"}, |
||||
}, |
||||
{ |
||||
Name: "macos-0_2-10.2", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u00c4\u00c5\u00c7\u00c9\u00d1\u00d6\u00dc\u00e1\u00e0\u00e2\u00e4\u00e3\u00e5\u00e7\u00e9\u00e8\u00ea\u00eb\u00ed\u00ec\u00ee\u00ef\u00f1\u00f3\u00f2\u00f4\u00f6\u00f5\u00fa\u00f9\u00fb\u00fc\u2020\u00b0\u00a2\u00a3\u00a7\u2022\u00b6\u00df\u00ae\u00a9\u2122\u00b4\u00a8\u2260\u00c6\u00d8\u221e\u00b1\u2264\u2265\u00a5\u00b5\u2202\u2211\u220f\u03c0\u222b\u00aa\u00ba\u03a9\u00e6\u00f8\u00bf\u00a1\u00ac\u221a\u0192\u2248\u2206\u00ab\u00bb\u2026\u00a0\u00c0\u00c3\u00d5\u0152\u0153\u2013\u2014\u201c\u201d\u2018\u2019\u00f7\u25ca\u00ff\u0178\u2044\u20ac\u2039\u203a\ufb01\ufb02\u2021\u00b7\u201a\u201e\u2030\u00c2\u00ca\u00c1\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00d3\u00d4\uf8ff\u00d2\u00da\u00db\u00d9\u0131\u02c6\u02dc\u00af\u02d8\u02d9\u02da\u00b8\u02dd\u02db\u02c7", |
||||
Aliases: []string{"macos-0_2-10.2", "macintosh", "mac", "csMacintosh", "windows-10000", "macroman"}, |
||||
}, |
||||
{ |
||||
Name: "macos-6_2-10.4", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u00c4\u00b9\u00b2\u00c9\u00b3\u00d6\u00dc\u0385\u00e0\u00e2\u00e4\u0384\u00a8\u00e7\u00e9\u00e8\u00ea\u00eb\u00a3\u2122\u00ee\u00ef\u2022\u00bd\u2030\u00f4\u00f6\u00a6\u20ac\u00f9\u00fb\u00fc\u2020\u0393\u0394\u0398\u039b\u039e\u03a0\u00df\u00ae\u00a9\u03a3\u03aa\u00a7\u2260\u00b0\u00b7\u0391\u00b1\u2264\u2265\u00a5\u0392\u0395\u0396\u0397\u0399\u039a\u039c\u03a6\u03ab\u03a8\u03a9\u03ac\u039d\u00ac\u039f\u03a1\u2248\u03a4\u00ab\u00bb\u2026\u00a0\u03a5\u03a7\u0386\u0388\u0153\u2013\u2015\u201c\u201d\u2018\u2019\u00f7\u0389\u038a\u038c\u038e\u03ad\u03ae\u03af\u03cc\u038f\u03cd\u03b1\u03b2\u03c8\u03b4\u03b5\u03c6\u03b3\u03b7\u03b9\u03be\u03ba\u03bb\u03bc\u03bd\u03bf\u03c0\u03ce\u03c1\u03c3\u03c4\u03b8\u03c9\u03c2\u03c7\u03c5\u03b6\u03ca\u03cb\u0390\u03b0\u00ad", |
||||
Aliases: []string{"macos-6_2-10.4", "x-mac-greek", "windows-10006", "macgr"}, |
||||
}, |
||||
{ |
||||
Name: "macos-7_3-10.2", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u2020\u00b0\u0490\u00a3\u00a7\u2022\u00b6\u0406\u00ae\u00a9\u2122\u0402\u0452\u2260\u0403\u0453\u221e\u00b1\u2264\u2265\u0456\u00b5\u0491\u0408\u0404\u0454\u0407\u0457\u0409\u0459\u040a\u045a\u0458\u0405\u00ac\u221a\u0192\u2248\u2206\u00ab\u00bb\u2026\u00a0\u040b\u045b\u040c\u045c\u0455\u2013\u2014\u201c\u201d\u2018\u2019\u00f7\u201e\u040e\u045e\u040f\u045f\u2116\u0401\u0451\u044f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u20ac", |
||||
Aliases: []string{"macos-7_3-10.2", "x-mac-cyrillic", "windows-10007", "mac-cyrillic", "maccy"}, |
||||
}, |
||||
{ |
||||
Name: "macos-29-10.2", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u00c4\u0100\u0101\u00c9\u0104\u00d6\u00dc\u00e1\u0105\u010c\u00e4\u010d\u0106\u0107\u00e9\u0179\u017a\u010e\u00ed\u010f\u0112\u0113\u0116\u00f3\u0117\u00f4\u00f6\u00f5\u00fa\u011a\u011b\u00fc\u2020\u00b0\u0118\u00a3\u00a7\u2022\u00b6\u00df\u00ae\u00a9\u2122\u0119\u00a8\u2260\u0123\u012e\u012f\u012a\u2264\u2265\u012b\u0136\u2202\u2211\u0142\u013b\u013c\u013d\u013e\u0139\u013a\u0145\u0146\u0143\u00ac\u221a\u0144\u0147\u2206\u00ab\u00bb\u2026\u00a0\u0148\u0150\u00d5\u0151\u014c\u2013\u2014\u201c\u201d\u2018\u2019\u00f7\u25ca\u014d\u0154\u0155\u0158\u2039\u203a\u0159\u0156\u0157\u0160\u201a\u201e\u0161\u015a\u015b\u00c1\u0164\u0165\u00cd\u017d\u017e\u016a\u00d3\u00d4\u016b\u016e\u00da\u016f\u0170\u0171\u0172\u0173\u00dd\u00fd\u0137\u017b\u0141\u017c\u0122\u02c7", |
||||
Aliases: []string{"macos-29-10.2", "x-mac-centraleurroman", "windows-10029", "x-mac-ce", "macce", "maccentraleurope"}, |
||||
}, |
||||
{ |
||||
Name: "macos-35-10.2", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u00c4\u00c5\u00c7\u00c9\u00d1\u00d6\u00dc\u00e1\u00e0\u00e2\u00e4\u00e3\u00e5\u00e7\u00e9\u00e8\u00ea\u00eb\u00ed\u00ec\u00ee\u00ef\u00f1\u00f3\u00f2\u00f4\u00f6\u00f5\u00fa\u00f9\u00fb\u00fc\u2020\u00b0\u00a2\u00a3\u00a7\u2022\u00b6\u00df\u00ae\u00a9\u2122\u00b4\u00a8\u2260\u00c6\u00d8\u221e\u00b1\u2264\u2265\u00a5\u00b5\u2202\u2211\u220f\u03c0\u222b\u00aa\u00ba\u03a9\u00e6\u00f8\u00bf\u00a1\u00ac\u221a\u0192\u2248\u2206\u00ab\u00bb\u2026\u00a0\u00c0\u00c3\u00d5\u0152\u0153\u2013\u2014\u201c\u201d\u2018\u2019\u00f7\u25ca\u00ff\u0178\u011e\u011f\u0130\u0131\u015e\u015f\u2021\u00b7\u201a\u201e\u2030\u00c2\u00ca\u00c1\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00d3\u00d4\uf8ff\u00d2\u00da\u00db\u00d9\uf8a0\u02c6\u02dc\u00af\u02d8\u02d9\u02da\u00b8\u02dd\u02db\u02c7", |
||||
Aliases: []string{"macos-35-10.2", "x-mac-turkish", "windows-10081", "mactr"}, |
||||
}, |
||||
{ |
||||
Name: "windows-1250", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\u201a\ufffd\u201e\u2026\u2020\u2021\ufffd\u2030\u0160\u2039\u015a\u0164\u017d\u0179\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\ufffd\u2122\u0161\u203a\u015b\u0165\u017e\u017a\u00a0\u02c7\u02d8\u0141\u00a4\u0104\u00a6\u00a7\u00a8\u00a9\u015e\u00ab\u00ac\u00ad\u00ae\u017b\u00b0\u00b1\u02db\u0142\u00b4\u00b5\u00b6\u00b7\u00b8\u0105\u015f\u00bb\u013d\u02dd\u013e\u017c\u0154\u00c1\u00c2\u0102\u00c4\u0139\u0106\u00c7\u010c\u00c9\u0118\u00cb\u011a\u00cd\u00ce\u010e\u0110\u0143\u0147\u00d3\u00d4\u0150\u00d6\u00d7\u0158\u016e\u00da\u0170\u00dc\u00dd\u0162\u00df\u0155\u00e1\u00e2\u0103\u00e4\u013a\u0107\u00e7\u010d\u00e9\u0119\u00eb\u011b\u00ed\u00ee\u010f\u0111\u0144\u0148\u00f3\u00f4\u0151\u00f6\u00f7\u0159\u016f\u00fa\u0171\u00fc\u00fd\u0163\u02d9", |
||||
}, |
||||
{ |
||||
Name: "windows-1251", |
||||
Aliases: []string{"CP1251"}, |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0402\u0403\u201a\u0453\u201e\u2026\u2020\u2021\u20ac\u2030\u0409\u2039\u040a\u040c\u040b\u040f\u0452\u2018\u2019\u201c\u201d\u2022\u2013\u2014\ufffd\u2122\u0459\u203a\u045a\u045c\u045b\u045f\u00a0\u040e\u045e\u0408\u00a4\u0490\u00a6\u00a7\u0401\u00a9\u0404\u00ab\u00ac\u00ad\u00ae\u0407\u00b0\u00b1\u0406\u0456\u0491\u00b5\u00b6\u00b7\u0451\u2116\u0454\u00bb\u0458\u0405\u0455\u0457\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f", |
||||
}, |
||||
{ |
||||
Name: "windows-1252", |
||||
Aliases: []string{"cp1252"}, |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\u201a\u0192\u201e\u2026\u2020\u2021\u02c6\u2030\u0160\u2039\u0152\ufffd\u017d\ufffd\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u02dc\u2122\u0161\u203a\u0153\ufffd\u017e\u0178\u00a0\u00a1\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00ba\u00bb\u00bc\u00bd\u00be\u00bf\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u00d0\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u00dd\u00de\u00df\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u00f0\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u00fd\u00fe\u00ff", |
||||
}, |
||||
{ |
||||
Name: "windows-1253", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\u201a\u0192\u201e\u2026\u2020\u2021\ufffd\u2030\ufffd\u2039\ufffd\ufffd\ufffd\ufffd\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\ufffd\u2122\ufffd\u203a\ufffd\ufffd\ufffd\ufffd\u00a0\u0385\u0386\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\ufffd\u00ab\u00ac\u00ad\u00ae\u2015\u00b0\u00b1\u00b2\u00b3\u0384\u00b5\u00b6\u00b7\u0388\u0389\u038a\u00bb\u038c\u00bd\u038e\u038f\u0390\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\ufffd\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa\u03ab\u03ac\u03ad\u03ae\u03af\u03b0\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9\u03ca\u03cb\u03cc\u03cd\u03ce\ufffd", |
||||
}, |
||||
{ |
||||
Name: "windows-1254", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\u201a\u0192\u201e\u2026\u2020\u2021\u02c6\u2030\u0160\u2039\u0152\ufffd\ufffd\ufffd\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u02dc\u2122\u0161\u203a\u0153\ufffd\ufffd\u0178\u00a0\u00a1\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00ba\u00bb\u00bc\u00bd\u00be\u00bf\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u011e\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u0130\u015e\u00df\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u011f\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u0131\u015f\u00ff", |
||||
}, |
||||
{ |
||||
Name: "windows-1255", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\u201a\u0192\u201e\u2026\u2020\u2021\u02c6\u2030\ufffd\u2039\ufffd\ufffd\ufffd\ufffd\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u02dc\u2122\ufffd\u203a\ufffd\ufffd\ufffd\ufffd\u00a0\u00a1\u00a2\u00a3\u20aa\u00a5\u00a6\u00a7\u00a8\u00a9\u00d7\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00f7\u00bb\u00bc\u00bd\u00be\u00bf\u05b0\u05b1\u05b2\u05b3\u05b4\u05b5\u05b6\u05b7\u05b8\u05b9\ufffd\u05bb\u05bc\u05bd\u05be\u05bf\u05c0\u05c1\u05c2\u05c3\u05f0\u05f1\u05f2\u05f3\u05f4\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\ufffd\ufffd\u200e\u200f\ufffd", |
||||
}, |
||||
{ |
||||
Name: "windows-1256", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\u067e\u201a\u0192\u201e\u2026\u2020\u2021\u02c6\u2030\u0679\u2039\u0152\u0686\u0698\u0688\u06af\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u06a9\u2122\u0691\u203a\u0153\u200c\u200d\u06ba\u00a0\u060c\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u06be\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u061b\u00bb\u00bc\u00bd\u00be\u061f\u06c1\u0621\u0622\u0623\u0624\u0625\u0626\u0627\u0628\u0629\u062a\u062b\u062c\u062d\u062e\u062f\u0630\u0631\u0632\u0633\u0634\u0635\u0636\u00d7\u0637\u0638\u0639\u063a\u0640\u0641\u0642\u0643\u00e0\u0644\u00e2\u0645\u0646\u0647\u0648\u00e7\u00e8\u00e9\u00ea\u00eb\u0649\u064a\u00ee\u00ef\u064b\u064c\u064d\u064e\u00f4\u064f\u0650\u00f7\u0651\u00f9\u0652\u00fb\u00fc\u200e\u200f\u06d2", |
||||
}, |
||||
{ |
||||
Name: "windows-1257", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\u201a\ufffd\u201e\u2026\u2020\u2021\ufffd\u2030\ufffd\u2039\ufffd\u00a8\u02c7\u00b8\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\ufffd\u2122\ufffd\u203a\ufffd\u00af\u02db\ufffd\u00a0\ufffd\u00a2\u00a3\u00a4\ufffd\u00a6\u00a7\u00d8\u00a9\u0156\u00ab\u00ac\u00ad\u00ae\u00c6\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00f8\u00b9\u0157\u00bb\u00bc\u00bd\u00be\u00e6\u0104\u012e\u0100\u0106\u00c4\u00c5\u0118\u0112\u010c\u00c9\u0179\u0116\u0122\u0136\u012a\u013b\u0160\u0143\u0145\u00d3\u014c\u00d5\u00d6\u00d7\u0172\u0141\u015a\u016a\u00dc\u017b\u017d\u00df\u0105\u012f\u0101\u0107\u00e4\u00e5\u0119\u0113\u010d\u00e9\u017a\u0117\u0123\u0137\u012b\u013c\u0161\u0144\u0146\u00f3\u014d\u00f5\u00f6\u00f7\u0173\u0142\u015b\u016b\u00fc\u017c\u017e\u02d9", |
||||
}, |
||||
{ |
||||
Name: "windows-1258", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\u201a\u0192\u201e\u2026\u2020\u2021\u02c6\u2030\ufffd\u2039\u0152\ufffd\ufffd\ufffd\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u02dc\u2122\ufffd\u203a\u0153\ufffd\ufffd\u0178\u00a0\u00a1\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00ba\u00bb\u00bc\u00bd\u00be\u00bf\u00c0\u00c1\u00c2\u0102\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u0300\u00cd\u00ce\u00cf\u0110\u00d1\u0309\u00d3\u00d4\u01a0\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u01af\u0303\u00df\u00e0\u00e1\u00e2\u0103\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u0301\u00ed\u00ee\u00ef\u0111\u00f1\u0323\u00f3\u00f4\u01a1\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u01b0\u20ab\u00ff", |
||||
}, |
||||
{ |
||||
Name: "windows-874", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\ufffd\ufffd\ufffd\u2026\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u00a0\u0e01\u0e02\u0e03\u0e04\u0e05\u0e06\u0e07\u0e08\u0e09\u0e0a\u0e0b\u0e0c\u0e0d\u0e0e\u0e0f\u0e10\u0e11\u0e12\u0e13\u0e14\u0e15\u0e16\u0e17\u0e18\u0e19\u0e1a\u0e1b\u0e1c\u0e1d\u0e1e\u0e1f\u0e20\u0e21\u0e22\u0e23\u0e24\u0e25\u0e26\u0e27\u0e28\u0e29\u0e2a\u0e2b\u0e2c\u0e2d\u0e2e\u0e2f\u0e30\u0e31\u0e32\u0e33\u0e34\u0e35\u0e36\u0e37\u0e38\u0e39\u0e3a\ufffd\ufffd\ufffd\ufffd\u0e3f\u0e40\u0e41\u0e42\u0e43\u0e44\u0e45\u0e46\u0e47\u0e48\u0e49\u0e4a\u0e4b\u0e4c\u0e4d\u0e4e\u0e4f\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0e5a\u0e5b\ufffd\ufffd\ufffd\ufffd", |
||||
}, |
||||
{ |
||||
Name: "IBM037", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1\u00a2.<(+|&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df!$*);\u00ac-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4\u00b5~stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae^\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be[]\u00af\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||
Aliases: []string{"cp037", "ebcdic-cp-us", "ebcdic-cp-ca", "ebcdic-cp-wt", "ebcdic-cp-nl", "csIBM037"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-273_P100-1995", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2{\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1\u00c4.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec~\u00dc$*);^-/\u00c2[\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00f6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#\u00a7'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4\u00b5\u00dfstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9@\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e4ABCDEFGHI\u00ad\u00f4\u00a6\u00f2\u00f3\u00f5\u00fcJKLMNOPQR\u00b9\u00fb}\u00f9\u00fa\u00ff\u00d6\u00f7STUVWXYZ\u00b2\u00d4\\\u00d2\u00d3\u00d50123456789\u00b3\u00db]\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-273_P100-1995", "ibm-273", "IBM273", "CP273", "csIBM273", "ebcdic-de", "273"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-277_P100-1995", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3}\u00e7\u00f1#.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u00a4\u00c5*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3$\u00c7\u00d1\u00f8,%_>?\u00a6\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:\u00c6\u00d8'=\"@abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba{\u00b8[]\u00b5\u00fcstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e6ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5\u00e5JKLMNOPQR\u00b9\u00fb~\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-277_P100-1995", "ibm-277", "IBM277", "cp277", "EBCDIC-CP-DK", "EBCDIC-CP-NO", "csIBM277", "ebcdic-dk", "277"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-278_P100-1995", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2{\u00e0\u00e1\u00e3}\u00e7\u00f1\u00a7.<(+!&`\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u00a4\u00c5*);^-/\u00c2#\u00c0\u00c1\u00c3$\u00c7\u00d1\u00f6,%_>?\u00f8\\\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00e9:\u00c4\u00d6'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6]\u00b5\u00fcstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9[\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e4ABCDEFGHI\u00ad\u00f4\u00a6\u00f2\u00f3\u00f5\u00e5JKLMNOPQR\u00b9\u00fb~\u00f9\u00fa\u00ff\u00c9\u00f7STUVWXYZ\u00b2\u00d4@\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-278_P100-1995", "ibm-278", "IBM278", "cp278", "ebcdic-cp-fi", "ebcdic-cp-se", "csIBM278", "ebcdic-sv", "278"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-280_P100-1995", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4{\u00e1\u00e3\u00e5\\\u00f1\u00b0.<(+!&]\u00ea\u00eb}\u00ed\u00ee\u00ef~\u00df\u00e9$*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00f2,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00f9:\u00a3\u00a7'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1[jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4\u00b5\u00ecstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2#\u00a5\u00b7\u00a9@\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e0ABCDEFGHI\u00ad\u00f4\u00f6\u00a6\u00f3\u00f5\u00e8JKLMNOPQR\u00b9\u00fb\u00fc`\u00fa\u00ff\u00e7\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-280_P100-1995", "ibm-280", "IBM280", "CP280", "ebcdic-cp-it", "csIBM280", "280"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-284_P100-1995", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00a6[.<(+|&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df]$*);\u00ac-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7#\u00f1,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:\u00d1@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4\u00b5\u00a8stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be^!\u00af~\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-284_P100-1995", "ibm-284", "IBM284", "CP284", "ebcdic-cp-es", "csIBM284", "cpibm284", "284"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-285_P100-1995", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1$.<(+|&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df!\u00a3*);\u00ac-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4\u00b5\u00afstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2[\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be^]~\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-285_P100-1995", "ibm-285", "IBM285", "CP285", "ebcdic-cp-gb", "csIBM285", "cpibm285", "ebcdic-gb", "285"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-290_P100-1995", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \uff61\uff62\uff63\uff64\uff65\uff66\uff67\uff68\uff69\u00a3.<(+|&\uff6a\uff6b\uff6c\uff6d\uff6e\uff6f\ufffd\uff70\ufffd!\u00a5*);\u00ac-/abcdefgh\ufffd,%_>?[ijklmnop`:#@'=\"]\uff71\uff72\uff73\uff74\uff75\uff76\uff77\uff78\uff79\uff7aq\uff7b\uff7c\uff7d\uff7e\uff7f\uff80\uff81\uff82\uff83\uff84\uff85\uff86\uff87\uff88\uff89r\ufffd\uff8a\uff8b\uff8c~\u203e\uff8d\uff8e\uff8f\uff90\uff91\uff92\uff93\uff94\uff95s\uff96\uff97\uff98\uff99^\u00a2\\tuvwxyz\uff9a\uff9b\uff9c\uff9d\uff9e\uff9f{ABCDEFGHI\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd}JKLMNOPQR\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd$\ufffdSTUVWXYZ\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd0123456789\ufffd\ufffd\ufffd\ufffd\ufffd\u009f", |
||||
Aliases: []string{"ibm-290_P100-1995", "ibm-290", "IBM290", "cp290", "EBCDIC-JP-kana", "csIBM290"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-297_P100-1995", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4@\u00e1\u00e3\u00e5\\\u00f1\u00b0.<(+!&{\u00ea\u00eb}\u00ed\u00ee\u00ef\u00ec\u00df\u00a7$*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00f9,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00b5:\u00a3\u00e0'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1[jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4`\u00a8stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2#\u00a5\u00b7\u00a9]\u00b6\u00bc\u00bd\u00be\u00ac|\u00af~\u00b4\u00d7\u00e9ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5\u00e8JKLMNOPQR\u00b9\u00fb\u00fc\u00a6\u00fa\u00ff\u00e7\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-297_P100-1995", "ibm-297", "IBM297", "cp297", "ebcdic-cp-fr", "csIBM297", "cpibm297", "297"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-420_X120-1999", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0651\ufe7d\u0640\u200b\u0621\u0622\ufe82\u0623\u00a2.<(+|&\ufe84\u0624\ufffd\ufffd\u0626\u0627\ufe8e\u0628\ufe91!$*);\u00ac-/\u0629\u062a\ufe97\u062b\ufe9b\u062c\ufe9f\u062d\u00a6,%_>?\ufea3\u062e\ufea7\u062f\u0630\u0631\u0632\u0633\ufeb3\u060c:#@'=\"\u0634abcdefghi\ufeb7\u0635\ufebb\u0636\ufebf\u0637\u0638jklmnopqr\u0639\ufeca\ufecb\ufecc\u063a\ufece\ufecf\u00f7stuvwxyz\ufed0\u0641\ufed3\u0642\ufed7\u0643\ufedb\u0644\ufef5\ufef6\ufef7\ufef8\ufffd\ufffd\ufefb\ufefc\ufedf\u0645\ufee3\u0646\ufee7\u0647\u061bABCDEFGHI\u00ad\ufeeb\ufffd\ufeec\ufffd\u0648\u061fJKLMNOPQR\u0649\ufef0\u064a\ufef2\ufef3\u0660\u00d7\ufffdSTUVWXYZ\u0661\u0662\ufffd\u0663\u0664\u06650123456789\ufffd\u0666\u0667\u0668\u0669\u009f", |
||||
Aliases: []string{"ibm-420_X120-1999", "ibm-420", "IBM420", "cp420", "ebcdic-cp-ar1", "csIBM420", "420"}, |
||||
}, |
||||
{ |
||||
Name: "IBM424", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u00a2.<(+|&\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1!$*);\u00ac-/\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u00a6,%_>?\ufffd\u05ea\ufffd\ufffd\u00a0\ufffd\ufffd\ufffd\u2017`:#@'=\"\ufffdabcdefghi\u00ab\u00bb\ufffd\ufffd\ufffd\u00b1\u00b0jklmnopqr\ufffd\ufffd\ufffd\u00b8\ufffd\u00a4\u00b5~stuvwxyz\ufffd\ufffd\ufffd\ufffd\ufffd\u00ae^\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be[]\u00af\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\ufffd\ufffd\ufffd\ufffd\ufffd}JKLMNOPQR\u00b9\ufffd\ufffd\ufffd\ufffd\ufffd\\\u00f7STUVWXYZ\u00b2\ufffd\ufffd\ufffd\ufffd\ufffd0123456789\u00b3\ufffd\ufffd\ufffd\ufffd\u009f", |
||||
Aliases: []string{"cp424", "ebcdic-cp-he", "csIBM424"}, |
||||
}, |
||||
{ |
||||
Name: "IBM437", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00a2\u00a3\u00a5\u20a7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u2310\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u00df\u0393\u03c0\u03a3\u03c3\u00b5\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u03c6\u03b5\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0", |
||||
Aliases: []string{"cp437", "437", "csPC8CodePage437"}, |
||||
}, |
||||
{ |
||||
Name: "IBM500", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1[.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df]$*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4\u00b5~stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||
Aliases: []string{"CP500", "ebcdic-cp-be", "ebcdic-cp-ch", "csIBM500"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-720_P100-1997", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\ufffd\ufffd\u00e9\u00e2\ufffd\u00e0\ufffd\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\ufffd\ufffd\ufffd\ufffd\u0651\u0652\u00f4\u00a4\u0640\u00fb\u00f9\u0621\u0622\u0623\u0624\u00a3\u0625\u0626\u0627\u0628\u0629\u062a\u062b\u062c\u062d\u062e\u062f\u0630\u0631\u0632\u0633\u0634\u0635\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u0636\u0637\u0638\u0639\u063a\u0641\u00b5\u0642\u0643\u0644\u0645\u0646\u0647\u0648\u0649\u064a\u2261\u064b\u064c\u064d\u064e\u064f\u0650\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0", |
||||
Aliases: []string{"ibm-720_P100-1997", "ibm-720", "windows-720", "DOS-720"}, |
||||
}, |
||||
{ |
||||
Name: "IBM737", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c3\u03c2\u03c4\u03c5\u03c6\u03c7\u03c8\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03c9\u03ac\u03ad\u03ae\u03ca\u03af\u03cc\u03cd\u03cb\u03ce\u0386\u0388\u0389\u038a\u038c\u038e\u038f\u00b1\u2265\u2264\u03aa\u03ab\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0", |
||||
Aliases: []string{"cp737", "cp737_DOSGreek"}, |
||||
}, |
||||
{ |
||||
Name: "IBM775", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0106\u00fc\u00e9\u0101\u00e4\u0123\u00e5\u0107\u0142\u0113\u0156\u0157\u012b\u0179\u00c4\u00c5\u00c9\u00e6\u00c6\u014d\u00f6\u0122\u00a2\u015a\u015b\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u00a4\u0100\u012a\u00f3\u017b\u017c\u017a\u201d\u00a6\u00a9\u00ae\u00ac\u00bd\u00bc\u0141\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u0104\u010c\u0118\u0116\u2563\u2551\u2557\u255d\u012e\u0160\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u0172\u016a\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u017d\u0105\u010d\u0119\u0117\u012f\u0161\u0173\u016b\u017e\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u00d3\u00df\u014c\u0143\u00f5\u00d5\u00b5\u0144\u0136\u0137\u013b\u013c\u0146\u0112\u0145\u2019\u00ad\u00b1\u201c\u00be\u00b6\u00a7\u00f7\u201e\u00b0\u2219\u00b7\u00b9\u00b3\u00b2\u25a0\u00a0", |
||||
Aliases: []string{"cp775", "csPC775Baltic"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-803_P100-1999", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd$.<(+|\u05d0\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd!\u00a2*);\u00ac-/\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd,%_>?\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd:#@'=\"\ufffd\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdABCDEFGHI\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdJKLMNOPQR\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdSTUVWXYZ\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd0123456789\ufffd\ufffd\ufffd\ufffd\ufffd\u009f", |
||||
Aliases: []string{"ibm-803_P100-1999", "ibm-803", "cp803"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-838_P100-1995", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0e01\u0e02\u0e03\u0e04\u0e05\u0e06\u0e07[\u00a2.<(+|&\u0e48\u0e08\u0e09\u0e0a\u0e0b\u0e0c\u0e0d\u0e0e]!$*);\u00ac-/\u0e0f\u0e10\u0e11\u0e12\u0e13\u0e14\u0e15^\u00a6,%_>?\u0e3f\u0e4e\u0e16\u0e17\u0e18\u0e19\u0e1a\u0e1b\u0e1c`:#@'=\"\u0e4fabcdefghi\u0e1d\u0e1e\u0e1f\u0e20\u0e21\u0e22\u0e5ajklmnopqr\u0e23\u0e24\u0e25\u0e26\u0e27\u0e28\u0e5b~stuvwxyz\u0e29\u0e2a\u0e2b\u0e2c\u0e2d\u0e2e\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0e2f\u0e30\u0e31\u0e32\u0e33\u0e34{ABCDEFGHI\u0e49\u0e35\u0e36\u0e37\u0e38\u0e39}JKLMNOPQR\u0e3a\u0e40\u0e41\u0e42\u0e43\u0e44\\\u0e4aSTUVWXYZ\u0e45\u0e46\u0e47\u0e48\u0e49\u0e4a0123456789\u0e4b\u0e4c\u0e4d\u0e4b\u0e4c\u009f", |
||||
Aliases: []string{"ibm-838_P100-1995", "ibm-838", "IBM838", "IBM-Thai", "csIBMThai", "cp838", "838", "ibm-9030"}, |
||||
}, |
||||
{ |
||||
Name: "IBM850", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u00c1\u00c2\u00c0\u00a9\u2563\u2551\u2557\u255d\u00a2\u00a5\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u00e3\u00c3\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u00a4\u00f0\u00d0\u00ca\u00cb\u00c8\u0131\u00cd\u00ce\u00cf\u2518\u250c\u2588\u2584\u00a6\u00cc\u2580\u00d3\u00df\u00d4\u00d2\u00f5\u00d5\u00b5\u00fe\u00de\u00da\u00db\u00d9\u00fd\u00dd\u00af\u00b4\u00ad\u00b1\u2017\u00be\u00b6\u00a7\u00f7\u00b8\u00b0\u00a8\u00b7\u00b9\u00b3\u00b2\u25a0\u00a0", |
||||
Aliases: []string{"cp850", "850", "csPC850Multilingual"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-851_P100-1995", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u0386\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u0388\u00c4\u0389\u038a\ufffd\u038c\u00f4\u00f6\u038e\u00fb\u00f9\u038f\u00d6\u00dc\u03ac\u00a3\u03ad\u03ae\u03af\u03ca\u0390\u03cc\u03cd\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u00bd\u0398\u0399\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u039a\u039b\u039c\u039d\u2563\u2551\u2557\u255d\u039e\u039f\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u03a0\u03a1\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03b1\u03b2\u03b3\u2518\u250c\u2588\u2584\u03b4\u03b5\u2580\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c3\u03c2\u03c4\u00b4\u00ad\u00b1\u03c5\u03c6\u03c7\u00a7\u03c8\u00b8\u00b0\u00a8\u03c9\u03cb\u03b0\u03ce\u25a0\u00a0", |
||||
Aliases: []string{"ibm-851_P100-1995", "ibm-851", "IBM851", "cp851", "851", "csPC851"}, |
||||
}, |
||||
{ |
||||
Name: "IBM852", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u00c7\u00fc\u00e9\u00e2\u00e4\u016f\u0107\u00e7\u0142\u00eb\u0150\u0151\u00ee\u0179\u00c4\u0106\u00c9\u0139\u013a\u00f4\u00f6\u013d\u013e\u015a\u015b\u00d6\u00dc\u0164\u0165\u0141\u00d7\u010d\u00e1\u00ed\u00f3\u00fa\u0104\u0105\u017d\u017e\u0118\u0119\u00ac\u017a\u010c\u015f\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u00c1\u00c2\u011a\u015e\u2563\u2551\u2557\u255d\u017b\u017c\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u0102\u0103\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u00a4\u0111\u0110\u010e\u00cb\u010f\u0147\u00cd\u00ce\u011b\u2518\u250c\u2588\u2584\u0162\u016e\u2580\u00d3\u00df\u00d4\u0143\u0144\u0148\u0160\u0161\u0154\u00da\u0155\u0170\u00fd\u00dd\u0163\u00b4\u00ad\u02dd\u02db\u02c7\u02d8\u00a7\u00f7\u00b8\u00b0\u00a8\u02d9\u0171\u0158\u0159\u25a0\u00a0", |
||||
Aliases: []string{"cp852", "852", "csPCp852"}, |
||||
}, |
||||
{ |
||||
Name: "IBM855", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0452\u0402\u0453\u0403\u0451\u0401\u0454\u0404\u0455\u0405\u0456\u0406\u0457\u0407\u0458\u0408\u0459\u0409\u045a\u040a\u045b\u040b\u045c\u040c\u045e\u040e\u045f\u040f\u044e\u042e\u044a\u042a\u0430\u0410\u0431\u0411\u0446\u0426\u0434\u0414\u0435\u0415\u0444\u0424\u0433\u0413\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u0445\u0425\u0438\u0418\u2563\u2551\u2557\u255d\u0439\u0419\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u043a\u041a\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u00a4\u043b\u041b\u043c\u041c\u043d\u041d\u043e\u041e\u043f\u2518\u250c\u2588\u2584\u041f\u044f\u2580\u042f\u0440\u0420\u0441\u0421\u0442\u0422\u0443\u0423\u0436\u0416\u0432\u0412\u044c\u042c\u2116\u00ad\u044b\u042b\u0437\u0417\u0448\u0428\u044d\u042d\u0449\u0429\u0447\u0427\u00a7\u25a0\u00a0", |
||||
Aliases: []string{"cp855", "855", "csIBM855"}, |
||||
}, |
||||
{ |
||||
Name: "IBM856", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\ufffd\u00a3\ufffd\u00d7\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u00ae\u00ac\u00bd\u00bc\ufffd\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\ufffd\ufffd\ufffd\u00a9\u2563\u2551\u2557\u255d\u00a2\u00a5\u2510\u2514\u2534\u252c\u251c\u2500\u253c\ufffd\ufffd\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u00a4\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u2518\u250c\u2588\u2584\u00a6\ufffd\u2580\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u00b5\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u00af\u00b4\u00ad\u00b1\u2017\u00be\u00b6\u00a7\u00f7\u00b8\u00b0\u00a8\u00b7\u00b9\u00b3\u00b2\u25a0\u00a0", |
||||
Aliases: []string{"cp856", "cp856_Hebrew_PC"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-857_P100-1995", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u0131\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u0130\u00d6\u00dc\u00f8\u00a3\u00d8\u015e\u015f\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u011e\u011f\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u00c1\u00c2\u00c0\u00a9\u2563\u2551\u2557\u255d\u00a2\u00a5\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u00e3\u00c3\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u00a4\u00ba\u00aa\u00ca\u00cb\u00c8\ufffd\u00cd\u00ce\u00cf\u2518\u250c\u2588\u2584\u00a6\u00cc\u2580\u00d3\u00df\u00d4\u00d2\u00f5\u00d5\u00b5\ufffd\u00d7\u00da\u00db\u00d9\u00ec\u00ff\u00af\u00b4\u00ad\u00b1\ufffd\u00be\u00b6\u00a7\u00f7\u00b8\u00b0\u00a8\u00b7\u00b9\u00b3\u00b2\u25a0\u00a0", |
||||
Aliases: []string{"ibm-857_P100-1995", "ibm-857", "IBM857", "cp857", "857", "csIBM857", "windows-857"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-858_P100-1997", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u00c1\u00c2\u00c0\u00a9\u2563\u2551\u2557\u255d\u00a2\u00a5\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u00e3\u00c3\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u00a4\u00f0\u00d0\u00ca\u00cb\u00c8\u20ac\u00cd\u00ce\u00cf\u2518\u250c\u2588\u2584\u00a6\u00cc\u2580\u00d3\u00df\u00d4\u00d2\u00f5\u00d5\u00b5\u00fe\u00de\u00da\u00db\u00d9\u00fd\u00dd\u00af\u00b4\u00ad\u00b1\u2017\u00be\u00b6\u00a7\u00f7\u00b8\u00b0\u00a8\u00b7\u00b9\u00b3\u00b2\u25a0\u00a0", |
||||
Aliases: []string{"ibm-858_P100-1997", "ibm-858", "IBM00858", "CCSID00858", "CP00858", "PC-Multilingual-850+euro", "cp858", "windows-858"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-860_P100-1995", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u00c7\u00fc\u00e9\u00e2\u00e3\u00e0\u00c1\u00e7\u00ea\u00ca\u00e8\u00cd\u00d4\u00ec\u00c3\u00c2\u00c9\u00c0\u00c8\u00f4\u00f5\u00f2\u00da\u00f9\u00cc\u00d5\u00dc\u00a2\u00a3\u00d9\u20a7\u00d3\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00d2\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u00df\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u03c6\u03b5\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0", |
||||
Aliases: []string{"ibm-860_P100-1995", "ibm-860", "IBM860", "cp860", "860", "csIBM860"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-861_P100-1995", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00d0\u00f0\u00de\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00fe\u00fb\u00dd\u00fd\u00d6\u00dc\u00f8\u00a3\u00d8\u20a7\u0192\u00e1\u00ed\u00f3\u00fa\u00c1\u00cd\u00d3\u00da\u00bf\u2310\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u00df\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u03c6\u03b5\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0", |
||||
Aliases: []string{"ibm-861_P100-1995", "ibm-861", "IBM861", "cp861", "861", "cp-is", "csIBM861", "windows-861"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-862_P100-1995", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\u00a2\u00a3\u00a5\u20a7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u2310\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u00df\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u03c6\u03b5\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0", |
||||
Aliases: []string{"ibm-862_P100-1995", "ibm-862", "IBM862", "cp862", "862", "csPC862LatinHebrew", "DOS-862", "windows-862"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-863_P100-1995", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u00c7\u00fc\u00e9\u00e2\u00c2\u00e0\u00b6\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u2017\u00c0\u00a7\u00c9\u00c8\u00ca\u00f4\u00cb\u00cf\u00fb\u00f9\u00a4\u00d4\u00dc\u00a2\u00a3\u00d9\u00db\u0192\u00a6\u00b4\u00f3\u00fa\u00a8\u00b8\u00b3\u00af\u00ce\u2310\u00ac\u00bd\u00bc\u00be\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u00df\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u03c6\u03b5\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0", |
||||
Aliases: []string{"ibm-863_P100-1995", "ibm-863", "IBM863", "cp863", "863", "csIBM863"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-864_X110-1999", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u00b0\u00b7\u2219\u221a\u2592\u2500\u2502\u253c\u2524\u252c\u251c\u2534\u2510\u250c\u2514\u2518\u03b2\u221e\u03c6\u00b1\u00bd\u00bc\u2248\u00ab\u00bb\ufef7\ufef8\ufffd\ufffd\ufefb\ufefc\u200b\u00a0\u00ad\ufe82\u00a3\u00a4\ufe84\ufffd\ufffd\ufe8e\ufe8f\ufe95\ufe99\u060c\ufe9d\ufea1\ufea5\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\ufed1\u061b\ufeb1\ufeb5\ufeb9\u061f\u00a2\ufe80\ufe81\ufe83\ufe85\ufeca\ufe8b\ufe8d\ufe91\ufe93\ufe97\ufe9b\ufe9f\ufea3\ufea7\ufea9\ufeab\ufead\ufeaf\ufeb3\ufeb7\ufebb\ufebf\ufec3\ufec7\ufecb\ufecf\u00a6\u00ac\u00f7\u00d7\ufec9\u0640\ufed3\ufed7\ufedb\ufedf\ufee3\ufee7\ufeeb\ufeed\ufeef\ufef3\ufebd\ufecc\ufece\ufecd\ufee1\ufe7d\ufe7c\ufee5\ufee9\ufeec\ufef0\ufef2\ufed0\ufed5\ufef5\ufef6\ufedd\ufed9\ufef1\u25a0\ufffd", |
||||
Aliases: []string{"ibm-864_X110-1999", "ibm-864", "IBM864", "cp864", "csIBM864"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-865_P100-1995", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u20a7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u2310\u00ac\u00bd\u00bc\u00a1\u00ab\u00a4\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u00df\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u03c6\u03b5\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0", |
||||
Aliases: []string{"ibm-865_P100-1995", "ibm-865", "IBM865", "cp865", "865", "csIBM865"}, |
||||
}, |
||||
{ |
||||
Name: "IBM866", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\u0401\u0451\u0404\u0454\u0407\u0457\u040e\u045e\u00b0\u2219\u00b7\u221a\u2116\u00a4\u25a0\u00a0", |
||||
Aliases: []string{"cp866", "866", "csIBM866"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-867_P100-1998", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\u00a2\u00a3\u00a5\ufffd\u20aa\u200e\u200f\u202a\u202b\u202d\u202e\u202c\ufffd\ufffd\u2310\u00ac\u00bd\u00bc\u20ac\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u00df\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u03c6\u03b5\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0", |
||||
Aliases: []string{"ibm-867_P100-1998", "ibm-867"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-868_P100-1995", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u06f0\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9\u060c\u061b\u061f\ufe81\ufe8d\ufe8e\uf8fb\ufe8f\ufe91\ufb56\ufb58\ufe93\ufe95\ufe97\ufb66\ufb68\ufe99\ufe9b\ufe9d\ufe9f\ufb7a\ufb7c\ufea1\ufea3\ufea5\ufea7\ufea9\ufb88\ufeab\ufead\ufb8c\ufeaf\ufb8a\ufeb1\ufeb3\ufeb5\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\ufeb7\ufeb9\ufebb\ufebd\u2563\u2551\u2557\u255d\ufebf\ufec3\u2510\u2514\u2534\u252c\u251c\u2500\u253c\ufec7\ufec9\u255a\u2554\u2569\u2566\u2560\u2550\u256c\ufeca\ufecb\ufecc\ufecd\ufece\ufecf\ufed0\ufed1\ufed3\ufed5\u2518\u250c\u2588\u2584\ufed7\ufb8e\u2580\ufedb\ufb92\ufb94\ufedd\ufedf\ufee0\ufee1\ufee3\ufb9e\ufee5\ufee7\ufe85\ufeed\ufba6\ufba8\ufba9\u00ad\ufbaa\ufe80\ufe89\ufe8a\ufe8b\ufbfc\ufbfd\ufbfe\ufbb0\ufbae\ufe7c\ufe7d\ufffd\u25a0\u00a0", |
||||
Aliases: []string{"ibm-868_P100-1995", "ibm-868", "IBM868", "CP868", "868", "csIBM868", "cp-ar"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-869_P100-1995", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u0386\ufffd\u0387\u00ac\u00a6\u2018\u2019\u0388\u2015\u0389\u038a\u03aa\u038c\ufffd\ufffd\u038e\u03ab\u00a9\u038f\u00b2\u00b3\u03ac\u00a3\u03ad\u03ae\u03af\u03ca\u0390\u03cc\u03cd\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u00bd\u0398\u0399\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u039a\u039b\u039c\u039d\u2563\u2551\u2557\u255d\u039e\u039f\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u03a0\u03a1\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03b1\u03b2\u03b3\u2518\u250c\u2588\u2584\u03b4\u03b5\u2580\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c3\u03c2\u03c4\u00b4\u00ad\u00b1\u03c5\u03c6\u03c7\u00a7\u03c8\u0385\u00b0\u00a8\u03c9\u03cb\u03b0\u03ce\u25a0\u00a0", |
||||
Aliases: []string{"ibm-869_P100-1995", "ibm-869", "IBM869", "cp869", "869", "cp-gr", "csIBM869", "windows-869"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-870_P100-1995", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u0163\u00e1\u0103\u010d\u00e7\u0107[.<(+!&\u00e9\u0119\u00eb\u016f\u00ed\u00ee\u013e\u013a\u00df]$*);^-/\u00c2\u00c4\u02dd\u00c1\u0102\u010c\u00c7\u0106|,%_>?\u02c7\u00c9\u0118\u00cb\u016e\u00cd\u00ce\u013d\u0139`:#@'=\"\u02d8abcdefghi\u015b\u0148\u0111\u00fd\u0159\u015f\u00b0jklmnopqr\u0142\u0144\u0161\u00b8\u02db\u00a4\u0105~stuvwxyz\u015a\u0147\u0110\u00dd\u0158\u015e\u02d9\u0104\u017c\u0162\u017b\u00a7\u017e\u017a\u017d\u0179\u0141\u0143\u0160\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u0155\u00f3\u0151}JKLMNOPQR\u011a\u0171\u00fc\u0165\u00fa\u011b\\\u00f7STUVWXYZ\u010f\u00d4\u00d6\u0154\u00d3\u01500123456789\u010e\u0170\u00dc\u0164\u00da\u009f", |
||||
Aliases: []string{"ibm-870_P100-1995", "ibm-870", "IBM870", "CP870", "ebcdic-cp-roece", "ebcdic-cp-yu", "csIBM870"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-871_P100-1995", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1\u00de.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u00c6$*);\u00d6-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00f0:#\u00d0'=\"\u00d8abcdefghi\u00ab\u00bb`\u00fd{\u00b1\u00b0jklmnopqr\u00aa\u00ba}\u00b8]\u00a4\u00b5\u00f6stuvwxyz\u00a1\u00bf@\u00dd[\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\\\u00d7\u00feABCDEFGHI\u00ad\u00f4~\u00f2\u00f3\u00f5\u00e6JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\u00b4\u00f7STUVWXYZ\u00b2\u00d4^\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-871_P100-1995", "ibm-871", "IBM871", "ebcdic-cp-is", "csIBM871", "CP871", "ebcdic-is", "871"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-874_P100-1995", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u0e48\u0e01\u0e02\u0e03\u0e04\u0e05\u0e06\u0e07\u0e08\u0e09\u0e0a\u0e0b\u0e0c\u0e0d\u0e0e\u0e0f\u0e10\u0e11\u0e12\u0e13\u0e14\u0e15\u0e16\u0e17\u0e18\u0e19\u0e1a\u0e1b\u0e1c\u0e1d\u0e1e\u0e1f\u0e20\u0e21\u0e22\u0e23\u0e24\u0e25\u0e26\u0e27\u0e28\u0e29\u0e2a\u0e2b\u0e2c\u0e2d\u0e2e\u0e2f\u0e30\u0e31\u0e32\u0e33\u0e34\u0e35\u0e36\u0e37\u0e38\u0e39\u0e3a\u0e49\u0e4a\u0e4b\u0e4c\u0e3f\u0e40\u0e41\u0e42\u0e43\u0e44\u0e45\u0e46\u0e47\u0e48\u0e49\u0e4a\u0e4b\u0e4c\u0e4d\u0e4e\u0e4f\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0e5a\u0e5b\u00a2\u00ac\u00a6\u00a0", |
||||
Aliases: []string{"ibm-874_P100-1995", "ibm-874", "ibm-9066", "cp874", "tis620.2533", "eucTH"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-875_P100-1995", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399[.<(+!&\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3]$*);^-/\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa\u03ab|,%_>?\u00a8\u0386\u0388\u0389\u00a0\u038a\u038c\u038e\u038f`:#@'=\"\u0385abcdefghi\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u00b0jklmnopqr\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u00b4~stuvwxyz\u03bd\u03be\u03bf\u03c0\u03c1\u03c3\u00a3\u03ac\u03ad\u03ae\u03ca\u03af\u03cc\u03cd\u03cb\u03ce\u03c2\u03c4\u03c5\u03c6\u03c7\u03c8{ABCDEFGHI\u00ad\u03c9\u0390\u03b0\u2018\u2015}JKLMNOPQR\u00b1\u00bd\ufffd\u0387\u2019\u00a6\\\ufffdSTUVWXYZ\u00b2\u00a7\ufffd\ufffd\u00ab\u00ac0123456789\u00b3\u00a9\ufffd\ufffd\u00bb\u009f", |
||||
Aliases: []string{"ibm-875_P100-1995", "ibm-875", "IBM875", "cp875", "875"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-901_P100-1999", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u201d\u00a2\u00a3\u20ac\u201e\u00a6\u00a7\u00d8\u00a9\u0156\u00ab\u00ac\u00ad\u00ae\u00c6\u00b0\u00b1\u00b2\u00b3\u201c\u00b5\u00b6\u00b7\u00f8\u00b9\u0157\u00bb\u00bc\u00bd\u00be\u00e6\u0104\u012e\u0100\u0106\u00c4\u00c5\u0118\u0112\u010c\u00c9\u0179\u0116\u0122\u0136\u012a\u013b\u0160\u0143\u0145\u00d3\u014c\u00d5\u00d6\u00d7\u0172\u0141\u015a\u016a\u00dc\u017b\u017d\u00df\u0105\u012f\u0101\u0107\u00e4\u00e5\u0119\u0113\u010d\u00e9\u017a\u0117\u0123\u0137\u012b\u013c\u0161\u0144\u0146\u00f3\u014d\u00f5\u00f6\u00f7\u0173\u0142\u015b\u016b\u00fc\u017c\u017e\u2019", |
||||
Aliases: []string{"ibm-901_P100-1999", "ibm-901"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-902_P100-1999", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u00a1\u00a2\u00a3\u20ac\u00a5\u00a6\u00a7\u00a8\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00ba\u00bb\u00bc\u00bd\u00be\u00bf\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u0160\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u00dd\u017d\u00df\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u0161\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u00fd\u017e\u00ff", |
||||
Aliases: []string{"ibm-902_P100-1999", "ibm-902"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-916_P100-1995", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\ufffd\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u00d7\u00ab\u00ac\u00ad\u00ae\u203e\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u2022\u00b8\u00b9\u00f7\u00bb\u00bc\u00bd\u00be\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u2017\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\ufffd\ufffd\ufffd\ufffd\ufffd", |
||||
Aliases: []string{"ibm-916_P100-1995", "ibm-916", "cp916", "916"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-918_P100-1995", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u060c\u061b\u061f\ufe81\ufe8d\ufe8e\uf8fb\ufe8f[.<(+!&\ufe91\ufb56\ufb58\ufe93\ufe95\ufe97\ufb66\ufb68\ufe99]$*);^-/\ufe9b\ufe9d\ufe9f\ufb7a\ufb7c\ufea1\ufea3\ufea5`,%_>?\u06f0\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9:#@'=\"\ufea7abcdefghi\ufea9\ufb88\ufeab\ufead\ufb8c\ufeaf\ufb8ajklmnopqr\ufeb1\ufeb3\ufeb5\ufeb7\ufeb9\ufebb\ufebd~stuvwxyz\ufebf\ufec3\ufec7\ufec9\ufeca\ufecb\ufecc\ufecd\ufece\ufecf\ufed0\ufed1\ufed3\ufed5\ufed7\ufb8e\ufedb|\ufb92\ufb94\ufedd\ufedf{ABCDEFGHI\u00ad\ufee0\ufee1\ufee3\ufb9e\ufee5}JKLMNOPQR\ufee7\ufe85\ufeed\ufba6\ufba8\ufba9\\\ufbaaSTUVWXYZ\ufe80\ufe89\ufe8a\ufe8b\ufbfc\ufbfd0123456789\ufbfe\ufbb0\ufbae\ufe7c\ufe7d\u009f", |
||||
Aliases: []string{"ibm-918_P100-1995", "ibm-918", "IBM918", "CP918", "ebcdic-cp-ar2", "csIBM918"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-922_P100-1999", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u00a1\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00ba\u00bb\u00bc\u00bd\u00be\u00bf\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u0160\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u00dd\u017d\u00df\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u0161\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u00fd\u017e\u00ff", |
||||
Aliases: []string{"ibm-922_P100-1999", "ibm-922", "IBM922", "cp922", "922"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1006_P100-1995", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u06f0\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9\u060c\u061b\u00ad\u061f\ufe81\ufe8d\ufe8e\uf8fb\ufe8f\ufe91\ufb56\ufb58\ufe93\ufe95\ufe97\ufb66\ufb68\ufe99\ufe9b\ufe9d\ufe9f\ufb7a\ufb7c\ufea1\ufea3\ufea5\ufea7\ufea9\ufb88\ufeab\ufead\ufb8c\ufeaf\ufb8a\ufeb1\ufeb3\ufeb5\ufeb7\ufeb9\ufebb\ufebd\ufebf\ufec3\ufec7\ufec9\ufeca\ufecb\ufecc\ufecd\ufece\ufecf\ufed0\ufed1\ufed3\ufed5\ufed7\ufb8e\ufedb\ufb92\ufb94\ufedd\ufedf\ufee0\ufee1\ufee3\ufb9e\ufee5\ufee7\ufe85\ufeed\ufba6\ufba8\ufba9\ufbaa\ufe80\ufe89\ufe8a\ufe8b\ufbfc\ufbfd\ufbfe\ufbb0\ufbae\ufe7c\ufe7d", |
||||
Aliases: []string{"ibm-1006_P100-1995", "ibm-1006", "IBM1006", "cp1006", "1006"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1025_P100-1995", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0452\u0453\u0451\u0454\u0455\u0456\u0457\u0458[.<(+!&\u0459\u045a\u045b\u045c\u045e\u045f\u042a\u2116\u0402]$*);^-/\u0403\u0401\u0404\u0405\u0406\u0407\u0408\u0409|,%_>?\u040a\u040b\u040c\u00ad\u040e\u040f\u044e\u0430\u0431`:#@'=\"\u0446abcdefghi\u0434\u0435\u0444\u0433\u0445\u0438\u0439jklmnopqr\u043a\u043b\u043c\u043d\u043e\u043f\u044f~stuvwxyz\u0440\u0441\u0442\u0443\u0436\u0432\u044c\u044b\u0437\u0448\u044d\u0449\u0447\u044a\u042e\u0410\u0411\u0426\u0414\u0415\u0424\u0413{ABCDEFGHI\u0425\u0418\u0419\u041a\u041b\u041c}JKLMNOPQR\u041d\u041e\u041f\u042f\u0420\u0421\\\u00a7STUVWXYZ\u0422\u0423\u0416\u0412\u042c\u042b0123456789\u0417\u0428\u042d\u0429\u0427\u009f", |
||||
Aliases: []string{"ibm-1025_P100-1995", "ibm-1025", "cp1025", "1025"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1026_P100-1995", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5{\u00f1\u00c7.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u011e\u0130*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5[\u00d1\u015f,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u0131:\u00d6\u015e'=\u00dc\u00d8abcdefghi\u00ab\u00bb}`\u00a6\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4\u00b5\u00f6stuvwxyz\u00a1\u00bf]$@\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e7ABCDEFGHI\u00ad\u00f4~\u00f2\u00f3\u00f5\u011fJKLMNOPQR\u00b9\u00fb\\\u00f9\u00fa\u00ff\u00fc\u00f7STUVWXYZ\u00b2\u00d4#\u00d2\u00d3\u00d50123456789\u00b3\u00db\"\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-1026_P100-1995", "ibm-1026", "IBM1026", "CP1026", "csIBM1026", "1026"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1047_P100-1995", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1\u00a2.<(+|&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df!$*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4\u00b5~stuvwxyz\u00a1\u00bf\u00d0[\u00de\u00ae\u00ac\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00dd\u00a8\u00af]\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-1047_P100-1995", "ibm-1047", "IBM1047", "cp1047", "1047"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1097_P100-1995", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u060c\u064b\ufe81\ufe82\uf8fa\ufe8d\ufe8e\uf8fb\u00a4.<(+|&\ufe80\ufe83\ufe84\uf8f9\ufe85\ufe8b\ufe8f\ufe91\ufb56!$*);\u00ac-/\ufb58\ufe95\ufe97\ufe99\ufe9b\ufe9d\ufe9f\ufb7a\u061b,%_>?\ufb7c\ufea1\ufea3\ufea5\ufea7\ufea9\ufeab\ufead\ufeaf`:#@'=\"\ufb8aabcdefghi\u00ab\u00bb\ufeb1\ufeb3\ufeb5\ufeb7\ufeb9jklmnopqr\ufebb\ufebd\ufebf\ufec1\ufec3\ufec5\ufec7~stuvwxyz\ufec9\ufeca\ufecb\ufecc\ufecd\ufece\ufecf\ufed0\ufed1\ufed3\ufed5\ufed7\ufb8e\ufedb\ufb92\ufb94[]\ufedd\ufedf\ufee1\u00d7{ABCDEFGHI\u00ad\ufee3\ufee5\ufee7\ufeed\ufee9}JKLMNOPQR\ufeeb\ufeec\ufba4\ufbfc\ufbfd\ufbfe\\\u061fSTUVWXYZ\u0640\u06f0\u06f1\u06f2\u06f3\u06f40123456789\u06f5\u06f6\u06f7\u06f8\u06f9\u009f", |
||||
Aliases: []string{"ibm-1097_P100-1995", "ibm-1097", "cp1097", "1097"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1098_P100-1995", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\ufffd\ufffd\u060c\u061b\u061f\u064b\ufe81\ufe82\uf8fa\ufe8d\ufe8e\uf8fb\ufe80\ufe83\ufe84\uf8f9\ufe85\ufe8b\ufe8f\ufe91\ufb56\ufb58\ufe95\ufe97\ufe99\ufe9b\ufe9d\ufe9f\ufb7a\ufb7c\u00d7\ufea1\ufea3\ufea5\ufea7\ufea9\ufeab\ufead\ufeaf\ufb8a\ufeb1\ufeb3\ufeb5\ufeb7\ufeb9\ufebb\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\ufebd\ufebf\ufec1\ufec3\u2563\u2551\u2557\u255d\u00a4\ufec5\u2510\u2514\u2534\u252c\u251c\u2500\u253c\ufec7\ufec9\u255a\u2554\u2569\u2566\u2560\u2550\u256c\ufffd\ufeca\ufecb\ufecc\ufecd\ufece\ufecf\ufed0\ufed1\ufed3\u2518\u250c\u2588\u2584\ufed5\ufed7\u2580\ufb8e\ufedb\ufb92\ufb94\ufedd\ufedf\ufee1\ufee3\ufee5\ufee7\ufeed\ufee9\ufeeb\ufeec\ufba4\ufbfc\u00ad\ufbfd\ufbfe\u0640\u06f0\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9\u25a0\u00a0", |
||||
Aliases: []string{"ibm-1098_P100-1995", "ibm-1098", "IBM1098", "cp1098", "1098"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1112_P100-1995", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0161\u00e4\u0105\u012f\u016b\u00e5\u0113\u017e\u00a2.<(+|&\u00e9\u0119\u0117\u010d\u0173\u201e\u201c\u0123\u00df!$*);\u00ac-/\u0160\u00c4\u0104\u012e\u016a\u00c5\u0112\u017d\u00a6,%_>?\u00f8\u00c9\u0118\u0116\u010c\u0172\u012a\u013b\u0122`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u0101\u017c\u0144\u00b1\u00b0jklmnopqr\u0156\u0157\u00e6\u0137\u00c6\u00a4\u00b5~stuvwxyz\u201d\u017a\u0100\u017b\u0143\u00ae^\u00a3\u012b\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be[]\u0179\u0136\u013c\u00d7{ABCDEFGHI\u00ad\u014d\u00f6\u0146\u00f3\u00f5}JKLMNOPQR\u00b9\u0107\u00fc\u0142\u015b\u2019\\\u00f7STUVWXYZ\u00b2\u014c\u00d6\u0145\u00d3\u00d50123456789\u00b3\u0106\u00dc\u0141\u015a\u009f", |
||||
Aliases: []string{"ibm-1112_P100-1995", "ibm-1112", "cp1112", "1112"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1122_P100-1999", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2{\u00e0\u00e1\u00e3}\u00e7\u00f1\u00a7.<(+!&`\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u00a4\u00c5*);^-/\u00c2#\u00c0\u00c1\u00c3$\u00c7\u00d1\u00f6,%_>?\u00f8\\\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00e9:\u00c4\u00d6'=\"\u00d8abcdefghi\u00ab\u00bb\u0161\u00fd\u017e\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6]\u00b5\u00fcstuvwxyz\u00a1\u00bf\u0160\u00dd\u017d\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9[\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e4ABCDEFGHI\u00ad\u00f4\u00a6\u00f2\u00f3\u00f5\u00e5JKLMNOPQR\u00b9\u00fb~\u00f9\u00fa\u00ff\u00c9\u00f7STUVWXYZ\u00b2\u00d4@\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-1122_P100-1999", "ibm-1122", "cp1122", "1122"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1123_P100-1995", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0452\u0491\u0451\u0454\u0455\u0456\u0457\u0458[.<(+!&\u0459\u045a\u045b\u045c\u045e\u045f\u042a\u2116\u0402]$*);^-/\u0490\u0401\u0404\u0405\u0406\u0407\u0408\u0409|,%_>?\u040a\u040b\u040c\u00ad\u040e\u040f\u044e\u0430\u0431`:#@'=\"\u0446abcdefghi\u0434\u0435\u0444\u0433\u0445\u0438\u0439jklmnopqr\u043a\u043b\u043c\u043d\u043e\u043f\u044f~stuvwxyz\u0440\u0441\u0442\u0443\u0436\u0432\u044c\u044b\u0437\u0448\u044d\u0449\u0447\u044a\u042e\u0410\u0411\u0426\u0414\u0415\u0424\u0413{ABCDEFGHI\u0425\u0418\u0419\u041a\u041b\u041c}JKLMNOPQR\u041d\u041e\u041f\u042f\u0420\u0421\\\u00a7STUVWXYZ\u0422\u0423\u0416\u0412\u042c\u042b0123456789\u0417\u0428\u042d\u0429\u0427\u009f", |
||||
Aliases: []string{"ibm-1123_P100-1995", "ibm-1123", "cp1123", "1123"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1124_P100-1996", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0401\u0402\u0490\u0404\u0405\u0406\u0407\u0408\u0409\u040a\u040b\u040c\u00ad\u040e\u040f\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\u2116\u0451\u0452\u0491\u0454\u0455\u0456\u0457\u0458\u0459\u045a\u045b\u045c\u00a7\u045e\u045f", |
||||
Aliases: []string{"ibm-1124_P100-1996", "ibm-1124", "cp1124", "1124"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1125_P100-1997", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\u0401\u0451\u0490\u0491\u0404\u0454\u0406\u0456\u0407\u0457\u00f7\u00b1\u2116\u00a4\u25a0\u00a0", |
||||
Aliases: []string{"ibm-1125_P100-1997", "ibm-1125", "cp1125"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1129_P100-1997", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u00a1\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u0153\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u0178\u00b5\u00b6\u00b7\u0152\u00b9\u00ba\u00bb\u00bc\u00bd\u00be\u00bf\u00c0\u00c1\u00c2\u0102\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u0300\u00cd\u00ce\u00cf\u0110\u00d1\u0309\u00d3\u00d4\u01a0\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u01af\u0303\u00df\u00e0\u00e1\u00e2\u0103\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u0301\u00ed\u00ee\u00ef\u0111\u00f1\u0323\u00f3\u00f4\u01a1\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u01b0\u20ab\u00ff", |
||||
Aliases: []string{"ibm-1129_P100-1997", "ibm-1129"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1130_P100-1997", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u0103\u00e5\u00e7\u00f1[.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u0303\u00df]$*);^-/\u00c2\u00c4\u00c0\u00c1\u0102\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u20ab`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u0111\u0309\u0300\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u0152\u00c6\u00a4\u00b5~stuvwxyz\u00a1\u00bf\u0110\u0323\u0301\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u0153\u0178\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u01b0\u00f3\u01a1}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u01af\u00d3\u01a00123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-1130_P100-1997", "ibm-1130"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1131_P100-1997", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\u0401\u0451\u0404\u0454\u0407\u0457\u040e\u045e\u0406\u0456\u00b7\u00a4\u0490\u0491\u2219\u00a0", |
||||
Aliases: []string{"ibm-1131_P100-1997", "ibm-1131", "cp1131"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1132_P100-1998", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0e81\u0e82\u0e84\u0e87\u0e88\u0eaa\u0e8a[\u00a2.<(+|&\ufffd\u0e8d\u0e94\u0e95\u0e96\u0e97\u0e99\u0e9a]!$*);\u00ac-/\u0e9b\u0e9c\u0e9d\u0e9e\u0e9f\u0ea1\u0ea2^\u00a6,%_>?\u20ad\ufffd\u0ea3\u0ea5\u0ea7\u0eab\u0ead\u0eae\ufffd`:#@'=\"\ufffdabcdefghi\ufffd\ufffd\u0eaf\u0eb0\u0eb2\u0eb3\ufffdjklmnopqr\u0eb4\u0eb5\u0eb6\u0eb7\u0eb8\u0eb9\ufffd~stuvwxyz\u0ebc\u0eb1\u0ebb\u0ebd\ufffd\ufffd\u0ed0\u0ed1\u0ed2\u0ed3\u0ed4\u0ed5\u0ed6\u0ed7\u0ed8\u0ed9\ufffd\u0ec0\u0ec1\u0ec2\u0ec3\u0ec4{ABCDEFGHI\ufffd\u0ec8\u0ec9\u0eca\u0ecb\u0ecc}JKLMNOPQR\u0ecd\u0ec6\ufffd\u0edc\u0edd\ufffd\\\ufffdSTUVWXYZ\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd0123456789\ufffd\ufffd\ufffd\ufffd\ufffd\u009f", |
||||
Aliases: []string{"ibm-1132_P100-1998", "ibm-1132"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1133_P100-1997", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\ufffd\u0e81\u0e82\u0e84\u0e87\u0e88\u0eaa\u0e8a\u0e8d\u0e94\u0e95\u0e96\u0e97\u0e99\u0e9a\u0e9b\u0e9c\u0e9d\u0e9e\u0e9f\u0ea1\u0ea2\u0ea3\u0ea5\u0ea7\u0eab\u0ead\u0eae\ufffd\ufffd\ufffd\u0eaf\u0eb0\u0eb2\u0eb3\u0eb4\u0eb5\u0eb6\u0eb7\u0eb8\u0eb9\u0ebc\u0eb1\u0ebb\u0ebd\ufffd\ufffd\ufffd\u0ec0\u0ec1\u0ec2\u0ec3\u0ec4\u0ec8\u0ec9\u0eca\u0ecb\u0ecc\u0ecd\u0ec6\ufffd\u0edc\u0eddk\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u0ed0\u0ed1\u0ed2\u0ed3\u0ed4\u0ed5\u0ed6\u0ed7\u0ed8\u0ed9\ufffd\ufffd\u00a2\u00ac\u00a6\u00a0", |
||||
Aliases: []string{"ibm-1133_P100-1997", "ibm-1133"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1137_P100-1999", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0901\u0902\u0903\u0905\u0906\u0907\u0908\u0909\u090a.<(+|&\u090b\u090c\u090d\u090e\u090f\u0910\u0911\u0912\u0913!$*);^-/\u0914\u0915\u0916\u0917\u0918\u0919\u091a\u091b\u091c,%_>?\u091d\u091e\u091f\u0920\u0921\u0922\u0923\u0924\u0925`:#@'=\"\u0926abcdefghi\u0927\u0928\u092a\u092b\u092c\u092d\u092ejklmnopqr\u092f\u0930\u0932\u0933\u0935\u0936\u200c~stuvwxyz\u0937\u0938\u0939[\u093c\u093d\u093e\u093f\u0940\u0941\u0942\u0943\u0944\u0945\u0946\u0947\u0948\u0949\u094a]\u094b\u094c{ABCDEFGHI\u094d\u0950\u0951\u0952\ufffd\ufffd}JKLMNOPQR\u0960\u0961\u0962\u0963\u0964\u0965\\\u200dSTUVWXYZ\u0966\u0967\u0968\u0969\u096a\u096b0123456789\u096c\u096d\u096e\u096f\u0970\u009f", |
||||
Aliases: []string{"ibm-1137_P100-1999", "ibm-1137"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1140_P100-1997", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1\u00a2.<(+|&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df!$*);\u00ac-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac\u00b5~stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae^\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be[]\u00af\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-1140_P100-1997", "ibm-1140", "IBM01140", "CCSID01140", "CP01140", "cp1140", "ebcdic-us-37+euro"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1141_P100-1997", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2{\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1\u00c4.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec~\u00dc$*);^-/\u00c2[\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00f6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#\u00a7'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac\u00b5\u00dfstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9@\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e4ABCDEFGHI\u00ad\u00f4\u00a6\u00f2\u00f3\u00f5\u00fcJKLMNOPQR\u00b9\u00fb}\u00f9\u00fa\u00ff\u00d6\u00f7STUVWXYZ\u00b2\u00d4\\\u00d2\u00d3\u00d50123456789\u00b3\u00db]\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-1141_P100-1997", "ibm-1141", "IBM01141", "CCSID01141", "CP01141", "cp1141", "ebcdic-de-273+euro"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1142_P100-1997", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3}\u00e7\u00f1#.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u20ac\u00c5*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3$\u00c7\u00d1\u00f8,%_>?\u00a6\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:\u00c6\u00d8'=\"@abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba{\u00b8[]\u00b5\u00fcstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e6ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5\u00e5JKLMNOPQR\u00b9\u00fb~\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-1142_P100-1997", "ibm-1142", "IBM01142", "CCSID01142", "CP01142", "cp1142", "ebcdic-dk-277+euro", "ebcdic-no-277+euro"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1143_P100-1997", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2{\u00e0\u00e1\u00e3}\u00e7\u00f1\u00a7.<(+!&`\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u20ac\u00c5*);^-/\u00c2#\u00c0\u00c1\u00c3$\u00c7\u00d1\u00f6,%_>?\u00f8\\\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00e9:\u00c4\u00d6'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6]\u00b5\u00fcstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9[\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e4ABCDEFGHI\u00ad\u00f4\u00a6\u00f2\u00f3\u00f5\u00e5JKLMNOPQR\u00b9\u00fb~\u00f9\u00fa\u00ff\u00c9\u00f7STUVWXYZ\u00b2\u00d4@\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-1143_P100-1997", "ibm-1143", "IBM01143", "CCSID01143", "CP01143", "cp1143", "ebcdic-fi-278+euro", "ebcdic-se-278+euro"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1144_P100-1997", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4{\u00e1\u00e3\u00e5\\\u00f1\u00b0.<(+!&]\u00ea\u00eb}\u00ed\u00ee\u00ef~\u00df\u00e9$*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00f2,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00f9:\u00a3\u00a7'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1[jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac\u00b5\u00ecstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2#\u00a5\u00b7\u00a9@\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e0ABCDEFGHI\u00ad\u00f4\u00f6\u00a6\u00f3\u00f5\u00e8JKLMNOPQR\u00b9\u00fb\u00fc`\u00fa\u00ff\u00e7\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-1144_P100-1997", "ibm-1144", "IBM01144", "CCSID01144", "CP01144", "cp1144", "ebcdic-it-280+euro"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1145_P100-1997", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00a6[.<(+|&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df]$*);\u00ac-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7#\u00f1,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:\u00d1@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac\u00b5\u00a8stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be^!\u00af~\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-1145_P100-1997", "ibm-1145", "IBM01145", "CCSID01145", "CP01145", "cp1145", "ebcdic-es-284+euro"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1146_P100-1997", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1$.<(+|&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df!\u00a3*);\u00ac-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac\u00b5\u00afstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2[\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be^]~\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-1146_P100-1997", "ibm-1146", "IBM01146", "CCSID01146", "CP01146", "cp1146", "ebcdic-gb-285+euro"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1147_P100-1997", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4@\u00e1\u00e3\u00e5\\\u00f1\u00b0.<(+!&{\u00ea\u00eb}\u00ed\u00ee\u00ef\u00ec\u00df\u00a7$*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00f9,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00b5:\u00a3\u00e0'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1[jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac`\u00a8stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2#\u00a5\u00b7\u00a9]\u00b6\u00bc\u00bd\u00be\u00ac|\u00af~\u00b4\u00d7\u00e9ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5\u00e8JKLMNOPQR\u00b9\u00fb\u00fc\u00a6\u00fa\u00ff\u00e7\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-1147_P100-1997", "ibm-1147", "IBM01147", "CCSID01147", "CP01147", "cp1147", "ebcdic-fr-297+euro"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1148_P100-1997", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1[.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df]$*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac\u00b5~stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-1148_P100-1997", "ibm-1148", "IBM01148", "CCSID01148", "CP01148", "cp1148", "ebcdic-international-500+euro"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1149_P100-1997", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1\u00de.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u00c6$*);\u00d6-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00f0:#\u00d0'=\"\u00d8abcdefghi\u00ab\u00bb`\u00fd{\u00b1\u00b0jklmnopqr\u00aa\u00ba}\u00b8]\u20ac\u00b5\u00f6stuvwxyz\u00a1\u00bf@\u00dd[\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\\\u00d7\u00feABCDEFGHI\u00ad\u00f4~\u00f2\u00f3\u00f5\u00e6JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\u00b4\u00f7STUVWXYZ\u00b2\u00d4^\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-1149_P100-1997", "ibm-1149", "IBM01149", "CCSID01149", "CP01149", "cp1149", "ebcdic-is-871+euro"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1153_P100-1999", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u0163\u00e1\u0103\u010d\u00e7\u0107[.<(+!&\u00e9\u0119\u00eb\u016f\u00ed\u00ee\u013e\u013a\u00df]$*);^-/\u00c2\u00c4\u02dd\u00c1\u0102\u010c\u00c7\u0106|,%_>?\u02c7\u00c9\u0118\u00cb\u016e\u00cd\u00ce\u013d\u0139`:#@'=\"\u02d8abcdefghi\u015b\u0148\u0111\u00fd\u0159\u015f\u00b0jklmnopqr\u0142\u0144\u0161\u00b8\u02db\u20ac\u0105~stuvwxyz\u015a\u0147\u0110\u00dd\u0158\u015e\u02d9\u0104\u017c\u0162\u017b\u00a7\u017e\u017a\u017d\u0179\u0141\u0143\u0160\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u0155\u00f3\u0151}JKLMNOPQR\u011a\u0171\u00fc\u0165\u00fa\u011b\\\u00f7STUVWXYZ\u010f\u00d4\u00d6\u0154\u00d3\u01500123456789\u010e\u0170\u00dc\u0164\u00da\u009f", |
||||
Aliases: []string{"ibm-1153_P100-1999", "ibm-1153"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1154_P100-1999", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0452\u0453\u0451\u0454\u0455\u0456\u0457\u0458[.<(+!&\u0459\u045a\u045b\u045c\u045e\u045f\u042a\u2116\u0402]$*);^-/\u0403\u0401\u0404\u0405\u0406\u0407\u0408\u0409|,%_>?\u040a\u040b\u040c\u00ad\u040e\u040f\u044e\u0430\u0431`:#@'=\"\u0446abcdefghi\u0434\u0435\u0444\u0433\u0445\u0438\u0439jklmnopqr\u043a\u043b\u043c\u043d\u043e\u043f\u044f~stuvwxyz\u0440\u0441\u0442\u0443\u0436\u0432\u044c\u044b\u0437\u0448\u044d\u0449\u0447\u044a\u042e\u0410\u0411\u0426\u0414\u0415\u0424\u0413{ABCDEFGHI\u0425\u0418\u0419\u041a\u041b\u041c}JKLMNOPQR\u041d\u041e\u041f\u042f\u0420\u0421\\\u20acSTUVWXYZ\u0422\u0423\u0416\u0412\u042c\u042b0123456789\u0417\u0428\u042d\u0429\u0427\u009f", |
||||
Aliases: []string{"ibm-1154_P100-1999", "ibm-1154"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1155_P100-1999", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5{\u00f1\u00c7.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u011e\u0130*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5[\u00d1\u015f,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u0131:\u00d6\u015e'=\u00dc\u00d8abcdefghi\u00ab\u00bb}`\u00a6\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac\u00b5\u00f6stuvwxyz\u00a1\u00bf]$@\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e7ABCDEFGHI\u00ad\u00f4~\u00f2\u00f3\u00f5\u011fJKLMNOPQR\u00b9\u00fb\\\u00f9\u00fa\u00ff\u00fc\u00f7STUVWXYZ\u00b2\u00d4#\u00d2\u00d3\u00d50123456789\u00b3\u00db\"\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-1155_P100-1999", "ibm-1155"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1156_P100-1999", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0161\u00e4\u0105\u012f\u016b\u00e5\u0113\u017e\u00a2.<(+|&\u00e9\u0119\u0117\u010d\u0173\u201e\u201c\u0123\u00df!$*);\u00ac-/\u0160\u00c4\u0104\u012e\u016a\u00c5\u0112\u017d\u00a6,%_>?\u00f8\u00c9\u0118\u0116\u010c\u0172\u012a\u013b\u0122`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u0101\u017c\u0144\u00b1\u00b0jklmnopqr\u0156\u0157\u00e6\u0137\u00c6\u20ac\u00b5~stuvwxyz\u201d\u017a\u0100\u017b\u0143\u00ae^\u00a3\u012b\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be[]\u0179\u0136\u013c\u00d7{ABCDEFGHI\u00ad\u014d\u00f6\u0146\u00f3\u00f5}JKLMNOPQR\u00b9\u0107\u00fc\u0142\u015b\u2019\\\u00f7STUVWXYZ\u00b2\u014c\u00d6\u0145\u00d3\u00d50123456789\u00b3\u0106\u00dc\u0141\u015a\u009f", |
||||
Aliases: []string{"ibm-1156_P100-1999", "ibm-1156"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1157_P100-1999", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2{\u00e0\u00e1\u00e3}\u00e7\u00f1\u00a7.<(+!&`\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u20ac\u00c5*);^-/\u00c2#\u00c0\u00c1\u00c3$\u00c7\u00d1\u00f6,%_>?\u00f8\\\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00e9:\u00c4\u00d6'=\"\u00d8abcdefghi\u00ab\u00bb\u0161\u00fd\u017e\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6]\u00b5\u00fcstuvwxyz\u00a1\u00bf\u0160\u00dd\u017d\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9[\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e4ABCDEFGHI\u00ad\u00f4\u00a6\u00f2\u00f3\u00f5\u00e5JKLMNOPQR\u00b9\u00fb~\u00f9\u00fa\u00ff\u00c9\u00f7STUVWXYZ\u00b2\u00d4@\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-1157_P100-1999", "ibm-1157"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1158_P100-1999", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0452\u0491\u0451\u0454\u0455\u0456\u0457\u0458[.<(+!&\u0459\u045a\u045b\u045c\u045e\u045f\u042a\u2116\u0402]$*);^-/\u0490\u0401\u0404\u0405\u0406\u0407\u0408\u0409|,%_>?\u040a\u040b\u040c\u00ad\u040e\u040f\u044e\u0430\u0431`:#@'=\"\u0446abcdefghi\u0434\u0435\u0444\u0433\u0445\u0438\u0439jklmnopqr\u043a\u043b\u043c\u043d\u043e\u043f\u044f~stuvwxyz\u0440\u0441\u0442\u0443\u0436\u0432\u044c\u044b\u0437\u0448\u044d\u0449\u0447\u044a\u042e\u0410\u0411\u0426\u0414\u0415\u0424\u0413{ABCDEFGHI\u0425\u0418\u0419\u041a\u041b\u041c}JKLMNOPQR\u041d\u041e\u041f\u042f\u0420\u0421\\\u20acSTUVWXYZ\u0422\u0423\u0416\u0412\u042c\u042b0123456789\u0417\u0428\u042d\u0429\u0427\u009f", |
||||
Aliases: []string{"ibm-1158_P100-1999", "ibm-1158"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1160_P100-1999", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0e01\u0e02\u0e03\u0e04\u0e05\u0e06\u0e07[\u00a2.<(+|&\u0e48\u0e08\u0e09\u0e0a\u0e0b\u0e0c\u0e0d\u0e0e]!$*);\u00ac-/\u0e0f\u0e10\u0e11\u0e12\u0e13\u0e14\u0e15^\u00a6,%_>?\u0e3f\u0e4e\u0e16\u0e17\u0e18\u0e19\u0e1a\u0e1b\u0e1c`:#@'=\"\u0e4fabcdefghi\u0e1d\u0e1e\u0e1f\u0e20\u0e21\u0e22\u0e5ajklmnopqr\u0e23\u0e24\u0e25\u0e26\u0e27\u0e28\u0e5b~stuvwxyz\u0e29\u0e2a\u0e2b\u0e2c\u0e2d\u0e2e\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0e2f\u0e30\u0e31\u0e32\u0e33\u0e34{ABCDEFGHI\u0e49\u0e35\u0e36\u0e37\u0e38\u0e39}JKLMNOPQR\u0e3a\u0e40\u0e41\u0e42\u0e43\u0e44\\\u0e4aSTUVWXYZ\u0e45\u0e46\u0e47\u0e48\u0e49\u0e4a0123456789\u0e4b\u0e4c\u0e4d\u0e4b\u20ac\u009f", |
||||
Aliases: []string{"ibm-1160_P100-1999", "ibm-1160"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1162_P100-1999", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\u0081\u0082\u0083\u0084\u2026\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0e01\u0e02\u0e03\u0e04\u0e05\u0e06\u0e07\u0e08\u0e09\u0e0a\u0e0b\u0e0c\u0e0d\u0e0e\u0e0f\u0e10\u0e11\u0e12\u0e13\u0e14\u0e15\u0e16\u0e17\u0e18\u0e19\u0e1a\u0e1b\u0e1c\u0e1d\u0e1e\u0e1f\u0e20\u0e21\u0e22\u0e23\u0e24\u0e25\u0e26\u0e27\u0e28\u0e29\u0e2a\u0e2b\u0e2c\u0e2d\u0e2e\u0e2f\u0e30\u0e31\u0e32\u0e33\u0e34\u0e35\u0e36\u0e37\u0e38\u0e39\u0e3a\ufffd\ufffd\ufffd\ufffd\u0e3f\u0e40\u0e41\u0e42\u0e43\u0e44\u0e45\u0e46\u0e47\u0e48\u0e49\u0e4a\u0e4b\u0e4c\u0e4d\u0e4e\u0e4f\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0e5a\u0e5b\ufffd\ufffd\ufffd\ufffd", |
||||
Aliases: []string{"ibm-1162_P100-1999", "ibm-1162"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1164_P100-1999", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u0103\u00e5\u00e7\u00f1[.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u0303\u00df]$*);^-/\u00c2\u00c4\u00c0\u00c1\u0102\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u20ab`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u0111\u0309\u0300\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u0152\u00c6\u20ac\u00b5~stuvwxyz\u00a1\u00bf\u0110\u0323\u0301\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u0153\u0178\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u01b0\u00f3\u01a1}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u01af\u00d3\u01a00123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||
Aliases: []string{"ibm-1164_P100-1999", "ibm-1164"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-4517_P100-2005", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\ufe7c\ufe7d\u0640\u200b\ufe80\ufe81\ufe82\ufe83\u00b0.<(+!&\ufe84\ufe85\ufffd\ufffd\ufe8b\ufe8d\ufe8e\ufe8f\ufe91\u00a7$*);^-/\ufe93\ufe95\ufe97\ufe99\ufe9b\ufe9d\ufe9f\ufea1\u00fa,%_>?\ufea3\ufea5\ufea7\ufea9\ufeab\ufead\ufeaf\ufeb1\ufeb3\u00a3:\u00b5\u00e1'=\"\ufeb5abcdefghi\ufeb7\ufeb9\ufebb\ufebd\ufebf\ufec3\ufec7jklmnopqr\ufec9\ufeca\ufecb\ufecc\ufecd\ufece\ufecf\u00a8stuvwxyz\ufed0\ufed1\ufed3\ufed5\ufed7\ufed9\ufedb\ufedd\ufef5\ufef6\ufef7\ufef8\ufffd\ufffd\ufefb\ufefc\ufedf\ufee1\ufee3\ufee5\ufee7\ufee9\u00e9ABCDEFGHI\u00ad\ufeeb\ufffd\ufeec\ufffd\ufeed\u00e8JKLMNOPQR\ufeef\ufef0\ufef1\ufef2\ufef3\ufffd\u00e7\u2007STUVWXYZ\u00f7\u060c\ufffd\u00d7\u061f\u061b0123456789\ufffd\ufffd\ufffd\ufffd\ufffd\u009f", |
||||
Aliases: []string{"ibm-4517_P100-2005", "ibm-4517"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-4899_P100-1998", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd$.<(+|\u05d0\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd!\u00a2*);\u00ac-/\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd,%_>?\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd:#@'=\"\ufffd\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\ufffd\ufffd\u20ac\ufffd\u20aa\ufffd\ufffd\ufffd\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdABCDEFGHI\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdJKLMNOPQR\ufffd\u202d\u202e\u202c\ufffd\ufffd\ufffd\ufffdSTUVWXYZ\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd0123456789\ufffd\u202a\u202b\u200e\u200f\u009f", |
||||
Aliases: []string{"ibm-4899_P100-1998", "ibm-4899"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-4909_P100-1999", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u2018\u2019\u00a3\u20ac\ufffd\u00a6\u00a7\u00a8\u00a9\ufffd\u00ab\u00ac\u00ad\ufffd\u2015\u00b0\u00b1\u00b2\u00b3\u00b4\u0385\u0386\u0387\u0388\u0389\u038a\u00bb\u038c\u00bd\u038e\u038f\u0390\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\ufffd\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa\u03ab\u03ac\u03ad\u03ae\u03af\u03b0\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9\u03ca\u03cb\u03cc\u03cd\u03ce\ufffd", |
||||
Aliases: []string{"ibm-4909_P100-1999", "ibm-4909"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-4971_P100-1999", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399[.<(+!&\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3]$*);^-/\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa\u03ab|,%_>?\u00a8\u0386\u0388\u0389\u00a0\u038a\u038c\u038e\u038f`:#@'=\"\u0385abcdefghi\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u00b0jklmnopqr\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u00b4~stuvwxyz\u03bd\u03be\u03bf\u03c0\u03c1\u03c3\u00a3\u03ac\u03ad\u03ae\u03ca\u03af\u03cc\u03cd\u03cb\u03ce\u03c2\u03c4\u03c5\u03c6\u03c7\u03c8{ABCDEFGHI\u00ad\u03c9\u0390\u03b0\u2018\u2015}JKLMNOPQR\u00b1\u00bd\ufffd\u0387\u2019\u00a6\\\ufffdSTUVWXYZ\u00b2\u00a7\ufffd\ufffd\u00ab\u00ac0123456789\u00b3\u00a9\u20ac\ufffd\u00bb\u009f", |
||||
Aliases: []string{"ibm-4971_P100-1999", "ibm-4971"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-5123_P100-1999", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \ufffd\uff61\uff62\uff63\uff64\uff65\uff66\uff67\uff68\u00a2.<(+|&\uff69\uff6a\uff6b\uff6c\uff6d\uff6e\uff6f\uff70\uff71!$*);\u00ac-/\uff72\uff73\uff74\uff75\uff76\uff77\uff78\uff79\ufffd,%_>?\uff7a\uff7b\uff7c\uff7d\uff7e\uff7f\uff80\uff81\uff82`:#@'=\"\ufffdabcdefghi\uff83\uff84\uff85\uff86\uff87\uff88\ufffdjklmnopqr\uff89\uff8a\uff8b\uff8c\uff8d\uff8e\u203e~stuvwxyz\uff8f\uff90\uff91[\uff92\uff93^\u00a3\u00a5\uff94\uff95\uff96\uff97\uff98\uff99\uff9a\uff9b\uff9c\uff9d]\uff9e\uff9f{ABCDEFGHI\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd}JKLMNOPQR\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\\\u20acSTUVWXYZ\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd0123456789\ufffd\ufffd\ufffd\ufffd\ufffd\u009f", |
||||
Aliases: []string{"ibm-5123_P100-1999", "ibm-5123"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-8482_P100-1999", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \uff61\uff62\uff63\uff64\uff65\uff66\uff67\uff68\uff69\u00a3.<(+|&\uff6a\uff6b\uff6c\uff6d\uff6e\uff6f\ufffd\uff70\ufffd!\u00a5*);\u00ac-/abcdefgh\ufffd,%_>?[ijklmnop`:#@'=\"]\uff71\uff72\uff73\uff74\uff75\uff76\uff77\uff78\uff79\uff7aq\uff7b\uff7c\uff7d\uff7e\uff7f\uff80\uff81\uff82\uff83\uff84\uff85\uff86\uff87\uff88\uff89r\ufffd\uff8a\uff8b\uff8c~\u203e\uff8d\uff8e\uff8f\uff90\uff91\uff92\uff93\uff94\uff95s\uff96\uff97\uff98\uff99^\u00a2\\tuvwxyz\uff9a\uff9b\uff9c\uff9d\uff9e\uff9f{ABCDEFGHI\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd}JKLMNOPQR\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd$\u20acSTUVWXYZ\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd0123456789\ufffd\ufffd\ufffd\ufffd\ufffd\u009f", |
||||
Aliases: []string{"ibm-8482_P100-1999", "ibm-8482"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-9067_X100-2005", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399[.<(+!&\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3]$*);^-/\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa\u03ab|,%_>?\u00a8\u0386\u0388\u0389\u00a0\u038a\u038c\u038e\u038f`:#@'=\"\u0385abcdefghi\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u00b0jklmnopqr\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u00b4~stuvwxyz\u03bd\u03be\u03bf\u03c0\u03c1\u03c3\u00a3\u03ac\u03ad\u03ae\u03ca\u03af\u03cc\u03cd\u03cb\u03ce\u03c2\u03c4\u03c5\u03c6\u03c7\u03c8{ABCDEFGHI\u00ad\u03c9\u0390\u03b0\u2018\u2015}JKLMNOPQR\u00b1\u00bd\ufffd\u0387\u2019\u00a6\\\u20afSTUVWXYZ\u00b2\u00a7\u037a\ufffd\u00ab\u00ac0123456789\u00b3\u00a9\u20ac\ufffd\u00bb\u009f", |
||||
Aliases: []string{"ibm-9067_X100-2005", "ibm-9067"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-12712_P100-1998", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u00a2.<(+|&\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1!$*);\u00ac-/\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u00a6,%_>?\ufffd\u05ea\ufffd\ufffd\u00a0\ufffd\ufffd\ufffd\u2017`:#@'=\"\ufffdabcdefghi\u00ab\u00bb\ufffd\ufffd\ufffd\u00b1\u00b0jklmnopqr\ufffd\ufffd\u20ac\u00b8\u20aa\u00a4\u00b5~stuvwxyz\ufffd\ufffd\ufffd\ufffd\ufffd\u00ae^\u00a3\u00a5\u2022\u00a9\u00a7\u00b6\u00bc\u00bd\u00be[]\u203e\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\ufffd\ufffd\ufffd\ufffd\ufffd}JKLMNOPQR\u00b9\u202d\u202e\u202c\ufffd\ufffd\\\u00f7STUVWXYZ\u00b2\ufffd\ufffd\ufffd\ufffd\ufffd0123456789\u00b3\u202a\u202b\u200e\u200f\u009f", |
||||
Aliases: []string{"ibm-12712_P100-1998", "ibm-12712", "ebcdic-he"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-16804_X110-1999", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0651\ufe7d\u0640\u200b\u0621\u0622\ufe82\u0623\u00a2.<(+|&\ufe84\u0624\ufffd\ufffd\u0626\u0627\ufe8e\u0628\ufe91!$*);\u00ac-/\u0629\u062a\ufe97\u062b\ufe9b\u062c\ufe9f\u062d\u00a6,%_>?\ufea3\u062e\ufea7\u062f\u0630\u0631\u0632\u0633\ufeb3\u060c:#@'=\"\u0634abcdefghi\ufeb7\u0635\ufebb\u0636\ufebf\u0637\u0638jklmnopqr\u0639\ufeca\ufecb\ufecc\u063a\ufece\ufecf\u00f7stuvwxyz\ufed0\u0641\ufed3\u0642\ufed7\u0643\ufedb\u0644\ufef5\ufef6\ufef7\ufef8\ufffd\ufffd\ufefb\ufefc\ufedf\u0645\ufee3\u0646\ufee7\u0647\u061bABCDEFGHI\u00ad\ufeeb\ufffd\ufeec\ufffd\u0648\u061fJKLMNOPQR\u0649\ufef0\u064a\ufef2\ufef3\u0660\u00d7\u2007STUVWXYZ\u0661\u0662\ufffd\u0663\u0664\u06650123456789\u20ac\u0666\u0667\u0668\u0669\u009f", |
||||
Aliases: []string{"ibm-16804_X110-1999", "ibm-16804", "ebcdic-ar"}, |
||||
}, |
||||
{ |
||||
Name: "KOI8-R", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u2500\u2502\u250c\u2510\u2514\u2518\u251c\u2524\u252c\u2534\u253c\u2580\u2584\u2588\u258c\u2590\u2591\u2592\u2593\u2320\u25a0\u2219\u221a\u2248\u2264\u2265\u00a0\u2321\u00b0\u00b2\u00b7\u00f7\u2550\u2551\u2552\u0451\u2553\u2554\u2555\u2556\u2557\u2558\u2559\u255a\u255b\u255c\u255d\u255e\u255f\u2560\u2561\u0401\u2562\u2563\u2564\u2565\u2566\u2567\u2568\u2569\u256a\u256b\u256c\u00a9\u044e\u0430\u0431\u0446\u0434\u0435\u0444\u0433\u0445\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u044f\u0440\u0441\u0442\u0443\u0436\u0432\u044c\u044b\u0437\u0448\u044d\u0449\u0447\u044a\u042e\u0410\u0411\u0426\u0414\u0415\u0424\u0413\u0425\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u042f\u0420\u0421\u0422\u0423\u0416\u0412\u042c\u042b\u0417\u0428\u042d\u0429\u0427\u042a", |
||||
Aliases: []string{"csKOI8R"}, |
||||
}, |
||||
{ |
||||
Name: "KOI8-U", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u2500\u2502\u250c\u2510\u2514\u2518\u251c\u2524\u252c\u2534\u253c\u2580\u2584\u2588\u258c\u2590\u2591\u2592\u2593\u2320\u25a0\u2219\u221a\u2248\u2264\u2265\u00a0\u2321\u00b0\u00b2\u00b7\u00f7\u2550\u2551\u2552\u0451\u0454\u2554\u0456\u0457\u2557\u2558\u2559\u255a\u255b\u0491\u255d\u255e\u255f\u2560\u2561\u0401\u0404\u2563\u0406\u0407\u2566\u2567\u2568\u2569\u256a\u0490\u256c\u00a9\u044e\u0430\u0431\u0446\u0434\u0435\u0444\u0433\u0445\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u044f\u0440\u0441\u0442\u0443\u0436\u0432\u044c\u044b\u0437\u0448\u044d\u0449\u0447\u044a\u042e\u0410\u0411\u0426\u0414\u0415\u0424\u0413\u0425\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u042f\u0420\u0421\u0422\u0423\u0416\u0412\u042c\u042b\u0417\u0428\u042d\u0429\u0427\u042a", |
||||
}, |
||||
{ |
||||
Name: "ibm-1051_P100-1995", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\ufffd\u00c0\u00c2\u00c8\u00ca\u00cb\u00ce\u00cf\u00b4`\u02c6\u00a8\u02dc\u00d9\u00db\u00a3\u203e\u00dd\u00fd\u02da\u00c7\u00e7\u00d1\u00f1\u00a1\u00bf\u00a4\u00a3\u00a5\u00a7\u0192\u00a2\u00e2\u00ea\u00f4\u00fb\u00e1\u00e9\u00f3\u00fa\u00e0\u00e8\u00f2\u00f9\u00e4\u00eb\u00f6\u00fc\u00c5\u00ee\u00d8\u00c6\u00e5\u00ed\u00f8\u00e6\u00c4\u00ec\u00d6\u00dc\u00c9\u00ef\u00df\u00d4\u00c1\u00c3\u00e3\u00d0\u00f0\u00cd\u00cc\u00d3\u00d2\u00d5\u00f5\u0160\u0161\u00da\u0178\u00ff\u00de\u00fe\u00b7\u03bc\u00b6\u00be-\u00bc\u00bd\u00aa\u00ba\u00ab\u25a0\u00bb\u00b1\ufffd", |
||||
Aliases: []string{"ibm-1051_P100-1995", "ibm-1051", "hp-roman8", "roman8", "r8", "csHPRoman8"}, |
||||
}, |
||||
{ |
||||
Name: "ibm-1276_P100-1995", |
||||
SubstitutionChar: '?', |
||||
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&\u2019()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_\u2018abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\ufffd\u00a1\u00a2\u00a3\u2044\u00a5\u0192\u00a7\u00a4'\u201c\u00ab\u2039\u203a\ufb01\ufb02\ufffd\u2013\u2020\u2021\u00b7\ufffd\u00b6\u2022\u201a\u201e\u201d\u00bb\u2026\u2030\ufffd\u00bf\ufffd`\u00b4\u02c6\u02dc\u00af\u02d8\u02d9\u00a8\ufffd\u02da\u00b8\ufffd\u02dd\u02db\u02c7\u2014\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u00c6\ufffd\u00aa\ufffd\ufffd\ufffd\ufffd\u0141\u00d8\u0152\u00ba\ufffd\ufffd\ufffd\ufffd\ufffd\u00e6\ufffd\ufffd\ufffd\u0131\ufffd\ufffd\u0142\u00f8\u0153\u00df\ufffd\ufffd\ufffd\ufffd", |
||||
Aliases: []string{"ibm-1276_P100-1995", "ibm-1276", "Adobe-Standard-Encoding", "csAdobeStandardEncoding"}, |
||||
}, |
||||
{ |
||||
Name: "ebcdic-xml-us", |
||||
SubstitutionChar: 0x6f, |
||||
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\n\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1\u00a2.<(+|&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df!$*);\u00ac-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac\u00b5~stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae^\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be[]\u00af\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f", |
||||
Aliases: []string{"ebcdic-xml-us"}, |
||||
}, |
||||
} |
@ -0,0 +1,76 @@
|
||||
package mahonia |
||||
|
||||
// Converters for ASCII and ISO-8859-1
|
||||
|
||||
func init() { |
||||
for i := 0; i < len(asciiCharsets); i++ { |
||||
RegisterCharset(&asciiCharsets[i]) |
||||
} |
||||
} |
||||
|
||||
var asciiCharsets = []Charset{ |
||||
{ |
||||
Name: "US-ASCII", |
||||
NewDecoder: func() Decoder { return decodeASCIIRune }, |
||||
NewEncoder: func() Encoder { return encodeASCIIRune }, |
||||
Aliases: []string{"ASCII", "US", "ISO646-US", "IBM367", "cp367", "ANSI_X3.4-1968", "iso-ir-6", "ANSI_X3.4-1986", "ISO_646.irv:1991", "csASCII"}, |
||||
}, |
||||
{ |
||||
Name: "ISO-8859-1", |
||||
NewDecoder: func() Decoder { return decodeLatin1Rune }, |
||||
NewEncoder: func() Encoder { return encodeLatin1Rune }, |
||||
Aliases: []string{"latin1", "ISO Latin 1", "IBM819", "cp819", "ISO_8859-1:1987", "iso-ir-100", "l1", "csISOLatin1"}, |
||||
}, |
||||
} |
||||
|
||||
func decodeASCIIRune(p []byte) (c rune, size int, status Status) { |
||||
if len(p) == 0 { |
||||
status = NO_ROOM |
||||
return |
||||
} |
||||
|
||||
b := p[0] |
||||
if b > 127 { |
||||
return 0xfffd, 1, INVALID_CHAR |
||||
} |
||||
return rune(b), 1, SUCCESS |
||||
} |
||||
|
||||
func encodeASCIIRune(p []byte, c rune) (size int, status Status) { |
||||
if len(p) == 0 { |
||||
status = NO_ROOM |
||||
return |
||||
} |
||||
|
||||
if c < 128 { |
||||
p[0] = byte(c) |
||||
return 1, SUCCESS |
||||
} |
||||
|
||||
p[0] = '?' |
||||
return 1, INVALID_CHAR |
||||
} |
||||
|
||||
func decodeLatin1Rune(p []byte) (c rune, size int, status Status) { |
||||
if len(p) == 0 { |
||||
status = NO_ROOM |
||||
return |
||||
} |
||||
|
||||
return rune(p[0]), 1, SUCCESS |
||||
} |
||||
|
||||
func encodeLatin1Rune(p []byte, c rune) (size int, status Status) { |
||||
if len(p) == 0 { |
||||
status = NO_ROOM |
||||
return |
||||
} |
||||
|
||||
if c < 256 { |
||||
p[0] = byte(c) |
||||
return 1, SUCCESS |
||||
} |
||||
|
||||
p[0] = '?' |
||||
return 1, INVALID_CHAR |
||||
} |
@ -0,0 +1,89 @@
|
||||
package mahonia |
||||
|
||||
// Converters for Big 5 encoding.
|
||||
|
||||
import ( |
||||
"sync" |
||||
) |
||||
|
||||
func init() { |
||||
RegisterCharset(&Charset{ |
||||
Name: "Big5", |
||||
Aliases: []string{"csBig5"}, |
||||
NewDecoder: func() Decoder { |
||||
return decodeBig5Rune |
||||
}, |
||||
NewEncoder: func() Encoder { |
||||
big5Once.Do(reverseBig5Table) |
||||
return encodeBig5Rune |
||||
}, |
||||
}) |
||||
} |
||||
|
||||
func decodeBig5Rune(p []byte) (r rune, size int, status Status) { |
||||
if len(p) == 0 { |
||||
status = NO_ROOM |
||||
return |
||||
} |
||||
|
||||
b := p[0] |
||||
if b < 128 { |
||||
return rune(b), 1, SUCCESS |
||||
} |
||||
|
||||
if len(p) < 2 { |
||||
status = NO_ROOM |
||||
return |
||||
} |
||||
|
||||
c := int(p[0])<<8 + int(p[1]) |
||||
c = int(big5ToUnicode[c]) |
||||
if c > 0 { |
||||
return rune(c), 2, SUCCESS |
||||
} |
||||
|
||||
return 0xfffd, 1, INVALID_CHAR |
||||
} |
||||
|
||||
func encodeBig5Rune(p []byte, r rune) (size int, status Status) { |
||||
if len(p) == 0 { |
||||
status = NO_ROOM |
||||
return |
||||
} |
||||
|
||||
if r < 128 { |
||||
p[0] = byte(r) |
||||
return 1, SUCCESS |
||||
} |
||||
|
||||
if len(p) < 2 { |
||||
status = NO_ROOM |
||||
return |
||||
} |
||||
|
||||
if r < 0x10000 { |
||||
c := unicodeToBig5[r] |
||||
if c > 0 { |
||||
p[0] = byte(c >> 8) |
||||
p[1] = byte(c) |
||||
return 2, SUCCESS |
||||
} |
||||
} |
||||
|
||||
p[0] = '?' |
||||
return 1, INVALID_CHAR |
||||
} |
||||
|
||||
var big5Once sync.Once |
||||
|
||||
var unicodeToBig5 []uint16 |
||||
|
||||
func reverseBig5Table() { |
||||
unicodeToBig5 = make([]uint16, 65536) |
||||
|
||||
for big5, unicode := range big5ToUnicode { |
||||
if unicode > 0 { |
||||
unicodeToBig5[unicode] = uint16(big5) |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,115 @@
|
||||
// This package is a character-set conversion library for Go.
|
||||
//
|
||||
// (DEPRECATED: use code.google.com/p/go.text/encoding, perhaps along with
|
||||
// code.google.com/p/go.net/html/charset)
|
||||
package mahonia |
||||
|
||||
import ( |
||||
"bytes" |
||||
"unicode" |
||||
) |
||||
|
||||
// Status is the type for the status return value from a Decoder or Encoder.
|
||||
type Status int |
||||
|
||||
const ( |
||||
// SUCCESS means that the character was converted with no problems.
|
||||
SUCCESS = Status(iota) |
||||
|
||||
// INVALID_CHAR means that the source contained invalid bytes, or that the character
|
||||
// could not be represented in the destination encoding.
|
||||
// The Encoder or Decoder should have output a substitute character.
|
||||
INVALID_CHAR |
||||
|
||||
// NO_ROOM means there were not enough input bytes to form a complete character,
|
||||
// or there was not enough room in the output buffer to write a complete character.
|
||||
// No bytes were written, and no internal state was changed in the Encoder or Decoder.
|
||||
NO_ROOM |
||||
|
||||
// STATE_ONLY means that bytes were read or written indicating a state transition,
|
||||
// but no actual character was processed. (Examples: byte order marks, ISO-2022 escape sequences)
|
||||
STATE_ONLY |
||||
) |
||||
|
||||
// A Decoder is a function that decodes a character set, one character at a time.
|
||||
// It works much like utf8.DecodeRune, but has an aditional status return value.
|
||||
type Decoder func(p []byte) (c rune, size int, status Status) |
||||
|
||||
// An Encoder is a function that encodes a character set, one character at a time.
|
||||
// It works much like utf8.EncodeRune, but has an additional status return value.
|
||||
type Encoder func(p []byte, c rune) (size int, status Status) |
||||
|
||||
// A Charset represents a character set that can be converted, and contains functions
|
||||
// to create Converters to encode and decode strings in that character set.
|
||||
type Charset struct { |
||||
// Name is the character set's canonical name.
|
||||
Name string |
||||
|
||||
// Aliases returns a list of alternate names.
|
||||
Aliases []string |
||||
|
||||
// NewDecoder returns a Decoder to convert from the charset to Unicode.
|
||||
NewDecoder func() Decoder |
||||
|
||||
// NewEncoder returns an Encoder to convert from Unicode to the charset.
|
||||
NewEncoder func() Encoder |
||||
} |
||||
|
||||
// The charsets are stored in charsets under their canonical names.
|
||||
var charsets = make(map[string]*Charset) |
||||
|
||||
// aliases maps their aliases to their canonical names.
|
||||
var aliases = make(map[string]string) |
||||
|
||||
// simplifyName converts a name to lower case and removes non-alphanumeric characters.
|
||||
// This is how the names are used as keys to the maps.
|
||||
func simplifyName(name string) string { |
||||
var buf bytes.Buffer |
||||
for _, c := range name { |
||||
switch { |
||||
case unicode.IsDigit(c): |
||||
buf.WriteRune(c) |
||||
case unicode.IsLetter(c): |
||||
buf.WriteRune(unicode.ToLower(c)) |
||||
default: |
||||
|
||||
} |
||||
} |
||||
|
||||
return buf.String() |
||||
} |
||||
|
||||
// RegisterCharset adds a charset to the charsetMap.
|
||||
func RegisterCharset(cs *Charset) { |
||||
name := cs.Name |
||||
charsets[name] = cs |
||||
aliases[simplifyName(name)] = name |
||||
for _, alias := range cs.Aliases { |
||||
aliases[simplifyName(alias)] = name |
||||
} |
||||
} |
||||
|
||||
// GetCharset fetches a charset by name.
|
||||
// If the name is not found, it returns nil.
|
||||
func GetCharset(name string) *Charset { |
||||
return charsets[aliases[simplifyName(name)]] |
||||
} |
||||
|
||||
// NewDecoder returns a Decoder to decode the named charset.
|
||||
// If the name is not found, it returns nil.
|
||||
func NewDecoder(name string) Decoder { |
||||
cs := GetCharset(name) |
||||
if cs == nil { |
||||
return nil |
||||
} |
||||
return cs.NewDecoder() |
||||
} |
||||
|
||||
// NewEncoder returns an Encoder to encode the named charset.
|
||||
func NewEncoder(name string) Encoder { |
||||
cs := GetCharset(name) |
||||
if cs == nil { |
||||
return nil |
||||
} |
||||
return cs.NewEncoder() |
||||
} |
@ -0,0 +1,135 @@
|
||||
package mahonia |
||||
|
||||
import ( |
||||
"unicode/utf8" |
||||
) |
||||
|
||||
// ConvertString converts a string from UTF-8 to e's encoding.
|
||||
func (e Encoder) ConvertString(s string) string { |
||||
dest := make([]byte, len(s)+10) |
||||
destPos := 0 |
||||
|
||||
for _, rune := range s { |
||||
retry: |
||||
size, status := e(dest[destPos:], rune) |
||||
|
||||
if status == NO_ROOM { |
||||
newDest := make([]byte, len(dest)*2) |
||||
copy(newDest, dest) |
||||
dest = newDest |
||||
goto retry |
||||
} |
||||
|
||||
if status == STATE_ONLY { |
||||
destPos += size |
||||
goto retry |
||||
} |
||||
|
||||
destPos += size |
||||
} |
||||
|
||||
return string(dest[:destPos]) |
||||
} |
||||
|
||||
// ConvertString converts a string from d's encoding to UTF-8.
|
||||
func (d Decoder) ConvertString(s string) string { |
||||
bytes := []byte(s) |
||||
runes := make([]rune, len(s)) |
||||
destPos := 0 |
||||
|
||||
for len(bytes) > 0 { |
||||
c, size, status := d(bytes) |
||||
|
||||
if status == STATE_ONLY { |
||||
bytes = bytes[size:] |
||||
continue |
||||
} |
||||
|
||||
if status == NO_ROOM { |
||||
c = 0xfffd |
||||
size = len(bytes) |
||||
status = INVALID_CHAR |
||||
} |
||||
|
||||
bytes = bytes[size:] |
||||
runes[destPos] = c |
||||
destPos++ |
||||
} |
||||
|
||||
return string(runes[:destPos]) |
||||
} |
||||
|
||||
// ConvertStringOK converts a string from UTF-8 to e's encoding. It also
|
||||
// returns a boolean indicating whether every character was converted
|
||||
// successfully.
|
||||
func (e Encoder) ConvertStringOK(s string) (result string, ok bool) { |
||||
dest := make([]byte, len(s)+10) |
||||
destPos := 0 |
||||
ok = true |
||||
|
||||
for i, r := range s { |
||||
// The following test is copied from utf8.ValidString.
|
||||
if r == utf8.RuneError && ok { |
||||
_, size := utf8.DecodeRuneInString(s[i:]) |
||||
if size == 1 { |
||||
ok = false |
||||
} |
||||
} |
||||
|
||||
retry: |
||||
size, status := e(dest[destPos:], r) |
||||
|
||||
switch status { |
||||
case NO_ROOM: |
||||
newDest := make([]byte, len(dest)*2) |
||||
copy(newDest, dest) |
||||
dest = newDest |
||||
goto retry |
||||
|
||||
case STATE_ONLY: |
||||
destPos += size |
||||
goto retry |
||||
|
||||
case INVALID_CHAR: |
||||
ok = false |
||||
} |
||||
|
||||
destPos += size |
||||
} |
||||
|
||||
return string(dest[:destPos]), ok |
||||
} |
||||
|
||||
// ConvertStringOK converts a string from d's encoding to UTF-8.
|
||||
// It also returns a boolean indicating whether every character was converted
|
||||
// successfully.
|
||||
func (d Decoder) ConvertStringOK(s string) (result string, ok bool) { |
||||
bytes := []byte(s) |
||||
runes := make([]rune, len(s)) |
||||
destPos := 0 |
||||
ok = true |
||||
|
||||
for len(bytes) > 0 { |
||||
c, size, status := d(bytes) |
||||
|
||||
switch status { |
||||
case STATE_ONLY: |
||||
bytes = bytes[size:] |
||||
continue |
||||
|
||||
case NO_ROOM: |
||||
c = 0xfffd |
||||
size = len(bytes) |
||||
ok = false |
||||
|
||||
case INVALID_CHAR: |
||||
ok = false |
||||
} |
||||
|
||||
bytes = bytes[size:] |
||||
runes[destPos] = c |
||||
destPos++ |
||||
} |
||||
|
||||
return string(runes[:destPos]), ok |
||||
} |
@ -0,0 +1,76 @@
|
||||
package mahonia |
||||
|
||||
import ( |
||||
"unicode/utf8" |
||||
) |
||||
|
||||
// Converters for Microsoft's version of the EUC-JP encoding
|
||||
|
||||
func init() { |
||||
RegisterCharset(&Charset{ |
||||
Name: "cp51932", |
||||
Aliases: []string{"windows-51932"}, |
||||
NewDecoder: func() Decoder { |
||||
return decodeCP51932 |
||||
}, |
||||
NewEncoder: func() Encoder { |
||||
msJISTable.Reverse() |
||||
return encodeCP51932 |
||||
}, |
||||
}) |
||||
} |
||||
|
||||
func decodeCP51932(p []byte) (c rune, size int, status Status) { |
||||
if len(p) == 0 { |
||||
return 0, 0, NO_ROOM |
||||
} |
||||
|
||||
b := p[0] |
||||
switch { |
||||
case b < 0x80: |
||||
return rune(b), 1, SUCCESS |
||||
|
||||
case b == 0x8e: |
||||
if len(p) < 2 { |
||||
return 0, 0, NO_ROOM |
||||
} |
||||
b2 := p[1] |
||||
if b2 < 0xa1 || b2 > 0xdf { |
||||
return utf8.RuneError, 1, INVALID_CHAR |
||||
} |
||||
return rune(b2) + (0xff61 - 0xa1), 2, SUCCESS |
||||
|
||||
case 0xa1 <= b && b <= 0xfe: |
||||
return msJISTable.DecodeHigh(p) |
||||
} |
||||
|
||||
return utf8.RuneError, 1, INVALID_CHAR |
||||
} |
||||
|
||||
func encodeCP51932(p []byte, c rune) (size int, status Status) { |
||||
if len(p) == 0 { |
||||
return 0, NO_ROOM |
||||
} |
||||
|
||||
if c < 0x80 { |
||||
p[0] = byte(c) |
||||
return 1, SUCCESS |
||||
} |
||||
|
||||
if len(p) < 2 { |
||||
return 0, NO_ROOM |
||||
} |
||||
|
||||
if c > 0xffff { |
||||
p[0] = '?' |
||||
return 1, INVALID_CHAR |
||||
} |
||||
|
||||
if 0xff61 <= c && c <= 0xff9f { |
||||
p[0] = 0x8e |
||||
p[1] = byte(c - (0xff61 - 0xa1)) |
||||
return 2, SUCCESS |
||||
} |
||||
|
||||
return msJISTable.EncodeHigh(p, c) |
||||
} |
@ -0,0 +1,179 @@
|
||||
package mahonia |
||||
|
||||
// decoding HTML entities
|
||||
|
||||
import ( |
||||
"sort" |
||||
) |
||||
|
||||
// EntityDecoder returns a Decoder that decodes HTML character entities.
|
||||
// If there is no valid character entity at the current position, it returns INVALID_CHAR.
|
||||
// So it needs to be combined with another Decoder via FallbackDecoder.
|
||||
func EntityDecoder() Decoder { |
||||
var leftover rune // leftover rune from two-rune entity
|
||||
return func(p []byte) (r rune, size int, status Status) { |
||||
if leftover != 0 { |
||||
r = leftover |
||||
leftover = 0 |
||||
return r, 0, SUCCESS |
||||
} |
||||
|
||||
if len(p) == 0 { |
||||
return 0, 0, NO_ROOM |
||||
} |
||||
|
||||
if p[0] != '&' { |
||||
return 0xfffd, 1, INVALID_CHAR |
||||
} |
||||
|
||||
if len(p) < 3 { |
||||
return 0, 1, NO_ROOM |
||||
} |
||||
|
||||
r, size, status = 0xfffd, 1, INVALID_CHAR |
||||
n := 1 // number of bytes read so far
|
||||
|
||||
if p[n] == '#' { |
||||
n++ |
||||
c := p[n] |
||||
hex := false |
||||
if c == 'x' || c == 'X' { |
||||
hex = true |
||||
n++ |
||||
} |
||||
|
||||
var x rune |
||||
for n < len(p) { |
||||
c = p[n] |
||||
n++ |
||||
if hex { |
||||
if '0' <= c && c <= '9' { |
||||
x = 16*x + rune(c) - '0' |
||||
continue |
||||
} else if 'a' <= c && c <= 'f' { |
||||
x = 16*x + rune(c) - 'a' + 10 |
||||
continue |
||||
} else if 'A' <= c && c <= 'F' { |
||||
x = 16*x + rune(c) - 'A' + 10 |
||||
continue |
||||
} |
||||
} else if '0' <= c && c <= '9' { |
||||
x = 10*x + rune(c) - '0' |
||||
continue |
||||
} |
||||
if c != ';' { |
||||
n-- |
||||
} |
||||
break |
||||
} |
||||
|
||||
if n == len(p) && p[n-1] != ';' { |
||||
return 0, 0, NO_ROOM |
||||
} |
||||
|
||||
size = n |
||||
if p[n-1] == ';' { |
||||
n-- |
||||
} |
||||
if hex { |
||||
n-- |
||||
} |
||||
n-- |
||||
// Now n is the number of actual digits read.
|
||||
if n == 0 { |
||||
return 0xfffd, 1, INVALID_CHAR |
||||
} |
||||
|
||||
if 0x80 <= x && x <= 0x9F { |
||||
// Replace characters from Windows-1252 with UTF-8 equivalents.
|
||||
x = replacementTable[x-0x80] |
||||
} else if x == 0 || (0xD800 <= x && x <= 0xDFFF) || x > 0x10FFFF { |
||||
// Replace invalid characters with the replacement character.
|
||||
return 0xfffd, size, INVALID_CHAR |
||||
} |
||||
|
||||
r = x |
||||
status = SUCCESS |
||||
return |
||||
} |
||||
|
||||
// Look for a named entity in EntityList.
|
||||
|
||||
possible := entityList |
||||
for len(possible) > 0 { |
||||
if len(p) <= n { |
||||
leftover = 0 |
||||
return 0, 0, NO_ROOM |
||||
} |
||||
|
||||
c := p[n] |
||||
|
||||
// Narrow down the selection in possible to those items that have c in the
|
||||
// appropriate byte.
|
||||
first := sort.Search(len(possible), func(i int) bool { |
||||
e := possible[i].name |
||||
if len(e) < n { |
||||
return false |
||||
} |
||||
return e[n-1] >= c |
||||
}) |
||||
possible = possible[first:] |
||||
last := sort.Search(len(possible), func(i int) bool { |
||||
return possible[i].name[n-1] > c |
||||
}) |
||||
possible = possible[:last] |
||||
|
||||
n++ |
||||
if len(possible) > 0 && len(possible[0].name) == n-1 { |
||||
r, leftover = possible[0].r1, possible[0].r2 |
||||
size = n |
||||
status = SUCCESS |
||||
// but don't return yet, since we need the longest match
|
||||
} |
||||
} |
||||
|
||||
return |
||||
} |
||||
} |
||||
|
||||
// This table is copied from /src/pkg/html/escape.go in the Go source
|
||||
//
|
||||
// These replacements permit compatibility with old numeric entities that
|
||||
// assumed Windows-1252 encoding.
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#consume-a-character-reference
|
||||
var replacementTable = [...]rune{ |
||||
'\u20AC', // First entry is what 0x80 should be replaced with.
|
||||
'\u0081', |
||||
'\u201A', |
||||
'\u0192', |
||||
'\u201E', |
||||
'\u2026', |
||||
'\u2020', |
||||
'\u2021', |
||||
'\u02C6', |
||||
'\u2030', |
||||
'\u0160', |
||||
'\u2039', |
||||
'\u0152', |
||||
'\u008D', |
||||
'\u017D', |
||||
'\u008F', |
||||
'\u0090', |
||||
'\u2018', |
||||
'\u2019', |
||||
'\u201C', |
||||
'\u201D', |
||||
'\u2022', |
||||
'\u2013', |
||||
'\u2014', |
||||
'\u02DC', |
||||
'\u2122', |
||||
'\u0161', |
||||
'\u203A', |
||||
'\u0153', |
||||
'\u009D', |
||||
'\u017E', |
||||
'\u0178', // Last entry is 0x9F.
|
||||
// 0x00->'\uFFFD' is handled programmatically.
|
||||
// 0x0D->'\u000D' is a no-op.
|
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue