diff --git a/data/keyboards/geometry/extended.xml b/data/keyboards/geometry/extended.xml
new file mode 100644
index 00000000..c73217e0
--- /dev/null
+++ b/data/keyboards/geometry/extended.xml
@@ -0,0 +1,123 @@
+
+
+  
+  
+  
+    
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+    
+  
+  
+    
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+    
+  
+  
+  
+  
+    
+    
+    
+    
+  
+  
+    
+    
+    
+    
+  
+  
+    
+    
+    
+    
+  
+  
+    
+    
+    
+    
+  
+  
+    
+    
+    
+    
+  
+  
+    
+    
+    
+    
+  
+  
+    
+    
+    
+    
+  
+  
+    
+    
+    
+    
+  
+  
+    
+    
+    
+    
+  
+  
+    
+    
+    
+    
+  
+  
+    
+    
+    
+    
+  
+
diff --git a/data/keyboards/keyboards.xml b/data/keyboards/keyboards.xml
index 8b71cb48..87ad1843 100644
--- a/data/keyboards/keyboards.xml
+++ b/data/keyboards/keyboards.xml
@@ -24,6 +24,9 @@
   
+  
   
diff --git a/data/keyboards/symbols/nb.xml b/data/keyboards/symbols/nb.xml
new file mode 100644
index 00000000..8915bde1
--- /dev/null
+++ b/data/keyboards/symbols/nb.xml
@@ -0,0 +1,192 @@
+
+
+  
+    q
+    Q
+    1
+    asciitilde
+  
+  
+    w
+    W
+    2
+    quoteleft
+  
+  
+    e
+    E
+    3
+    bar
+  
+  
+    r
+    R
+    4
+    middledot
+  
+  
+    t
+    T
+    5
+  
+  
+    y
+    Y
+    6
+  
+  
+    u
+    U
+    7
+  
+  
+    i
+    I
+    8
+  
+  
+    o
+    O
+    9
+  
+  
+    p
+    P
+    0
+  
+  
+    å
+    Å
+  
+  
+    a
+    A
+    at
+    copyright
+  
+  
+    s
+    S
+    numbersign
+    registeredtrademark
+  
+  
+    d
+    D
+    dollar
+    poundsign
+  
+  
+    f
+    F
+    percent
+    €
+  
+  
+    g
+    G
+    ampersand
+    yensign
+  
+  
+    h
+    H
+    minus
+    asciicircum
+  
+  
+    j
+    J
+    plus
+    degreesign
+  
+  
+    k
+    K
+    parenleft
+    braceleft
+  
+  
+    l
+    L
+    parenright
+    braceright
+  
+  
+    oslash
+    Oslash
+  
+  
+    ae
+    AE
+  
+  
+    Return
+  
+  
+    Shift_L
+    Shift_L
+    Shift_L
+    Shift_L
+  
+  
+    z
+    Z
+    comma
+    backslash
+  
+  
+    x
+    X
+    quotedbl
+    slash
+  
+  
+    c
+    C
+    quoteright
+    less
+  
+  
+    v
+    V
+    colon
+    greater
+  
+  
+    b
+    B
+    semicolon
+    equal
+  
+  
+    n
+    N
+    exclam
+    bracketleft
+  
+  
+    m
+    M
+    question
+    bracketright
+  
+  
+    period
+  
+  
+    show-numbers
+    show-numbers
+    show-letters
+    show-letters
+  
+  
+    preferences
+  
+  
+    space
+  
+  
+    backspace
+  
+
diff --git a/data/squeekboard.gresources.xml b/data/squeekboard.gresources.xml
index 673c1033..c5faaa70 100644
--- a/data/squeekboard.gresources.xml
+++ b/data/squeekboard.gresources.xml
@@ -3,6 +3,7 @@
   
    style.css
    keyboards/geometry/compact.xml
+   keyboards/geometry/extended.xml
    keyboards/keyboards.xml
    keyboards/symbols/ar.xml
    keyboards/symbols/as-inscript.xml
@@ -21,6 +22,7 @@
    keyboards/symbols/ml-inscript.xml
    keyboards/symbols/mr-inscript.xml
    keyboards/symbols/my.xml
+   keyboards/symbols/nb.xml
    keyboards/symbols/or-inscript.xml
    keyboards/symbols/pa-inscript.xml
    keyboards/symbols/ru.xml
diff --git a/eek/eek-xml-layout.c b/eek/eek-xml-layout.c
index 0c4edc8a..9fccb4ab 100644
--- a/eek/eek-xml-layout.c
+++ b/eek/eek-xml-layout.c
@@ -249,7 +249,6 @@ struct _GeometryParseData {
     gchar *name;
     EekOutline outline;
     gchar *oref;
-    gint keycode;
 
     GHashTable *key_oref_hash;
     GHashTable *oref_outline_hash;
@@ -272,7 +271,6 @@ geometry_parse_data_new (EekKeyboard *keyboard)
                                g_str_equal,
                                g_free,
                                (GDestroyNotify)eek_outline_free);
-    data->keycode = 1;
     return data;
 }
 
@@ -398,6 +396,18 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
     }
 
     if (g_strcmp0 (element_name, "key") == 0) {
+        guint keycode;
+
+        attribute = get_attribute (attribute_names, attribute_values,
+                                   "keycode");
+        if (attribute == NULL) {
+            g_set_error (error,
+                         G_MARKUP_ERROR,
+                         G_MARKUP_ERROR_MISSING_ATTRIBUTE,
+                         "no \"keycode\" attribute for \"key\"");
+            return;
+        }
+        keycode = strtol (attribute, NULL, 10);
 
         attribute = get_attribute (attribute_names, attribute_values,
                                    "name");
@@ -411,7 +421,7 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
 
         data->key = eek_section_create_key (data->section,
                                             g_strdup (attribute),
-                                            data->keycode++,
+                                            keycode,
                                             data->num_columns,
                                             data->num_rows - 1);
 
diff --git a/eekboard/eekboard-context-service.c b/eekboard/eekboard-context-service.c
index 1b298223..9fc0787c 100644
--- a/eekboard/eekboard-context-service.c
+++ b/eekboard/eekboard-context-service.c
@@ -156,6 +156,7 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self,
     }
     keyboard->keymap = keymap;
     char *keymap_str = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1);
+    g_debug("%s", keymap_str);
     keyboard->keymap_len = strlen(keymap_str) + 1;
     g_autofree char *path = strdup("/eek_keymap-XXXXXX");
     char *r = &path[strlen(path) - 6];
@@ -293,6 +294,7 @@ settings_update_layout(EekboardContextService *context) {
     g_autofree gchar *keyboard_type = NULL;
     g_autofree gchar *keyboard_layout = NULL;
     settings_get_layout(context->priv->settings, &keyboard_type, &keyboard_layout);
+    g_debug("type=%s, layout=%s", keyboard_type, keyboard_layout);
 
     if (!keyboard_type) {
         keyboard_type = g_strdup("us");