// Path: app/src/main/java/com/vlath/keyboard/latin/utils/XmlParseUtils.java
// public final class XmlParseUtils {
//     private XmlParseUtils() {
//         // This utility class is not publicly instantiable.
//     }
// 
//     @SuppressWarnings("serial")
//     public static class ParseException extends XmlPullParserException {
//         public ParseException(final String msg, final XmlPullParser parser) {
//             super(msg + " at " + parser.getPositionDescription());
//         }
//     }
// 
//     @SuppressWarnings("serial")
//     public static final class IllegalStartTag extends ParseException {
//         public IllegalStartTag(final XmlPullParser parser, final String tag, final String parent) {
//             super("Illegal start tag " + tag + " in " + parent, parser);
//         }
//     }
// 
//     @SuppressWarnings("serial")
//     public static final class IllegalEndTag extends ParseException {
//         public IllegalEndTag(final XmlPullParser parser, final String tag, final String parent) {
//             super("Illegal end tag " + tag + " in " + parent, parser);
//         }
//     }
// 
//     @SuppressWarnings("serial")
//     public static final class IllegalAttribute extends ParseException {
//         public IllegalAttribute(final XmlPullParser parser, final String tag,
//                 final String attribute) {
//             super("Tag " + tag + " has illegal attribute " + attribute, parser);
//         }
//     }
// 
//     @SuppressWarnings("serial")
//     public static final class NonEmptyTag extends ParseException{
//         public NonEmptyTag(final XmlPullParser parser, final String tag) {
//             super(tag + " must be empty tag", parser);
//         }
//     }
// 
//     public static void checkEndTag(final String tag, final XmlPullParser parser)
//             throws XmlPullParserException, IOException {
//         if (parser.next() == XmlPullParser.END_TAG && tag.equals(parser.getName()))
//             return;
//         throw new NonEmptyTag(parser, tag);
//     }
// 
//     public static void checkAttributeExists(final TypedArray attr, final int attrId,
//             final String attrName, final String tag, final XmlPullParser parser)
//                     throws XmlPullParserException {
//         if (attr.hasValue(attrId)) {
//             return;
//         }
//         throw new ParseException(
//                 "No " + attrName + " attribute found in <" + tag + "/>", parser);
//     }
// }


import android.content.res.TypedArray;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.util.Log;
import android.util.SparseArray;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.util.Arrays;
import java.util.HashMap;
import com.vlath.keyboard.R;
import com.vlath.keyboard.latin.utils.XmlParseUtils;
                mStyleAttributes.put(index, a.getInt(index, 0) | styleFlags);
            }
        }

        private void readStringArray(final TypedArray a, final int index) {
            if (a.hasValue(index)) {
                mStyleAttributes.put(index, parseStringArray(a, index));
            }
        }
    }

    public void parseKeyStyleAttributes(final TypedArray keyStyleAttr, final TypedArray keyAttrs,
            final XmlPullParser parser) throws XmlPullParserException {
        final String styleName = keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_styleName);
        if (styleName == null) {
            throw new XmlParseUtils.ParseException(
                    KeyboardBuilder.TAG_KEY_STYLE + " has no styleName attribute", parser);
        }
        if (DEBUG) {
            Log.d(TAG, String.format("<%s styleName=%s />",
                    KeyboardBuilder.TAG_KEY_STYLE, styleName));
            if (mStyles.containsKey(styleName)) {
                Log.d(TAG, KeyboardBuilder.TAG_KEY_STYLE + " " + styleName + " is overridden at "
                        + parser.getPositionDescription());
            }
        }

        final String parentStyleInAttr = keyStyleAttr.getString(
                R.styleable.Keyboard_KeyStyle_parentStyle);
        if (parentStyleInAttr != null && !mStyles.containsKey(parentStyleInAttr)) {
// Path: app/src/main/java/com/vlath/keyboard/latin/utils/XmlParseUtils.java
// public final class XmlParseUtils {
//     private XmlParseUtils() {
//         // This utility class is not publicly instantiable.
//     }
// 
//     @SuppressWarnings("serial")
//     public static class ParseException extends XmlPullParserException {
//         public ParseException(final String msg, final XmlPullParser parser) {
//             super(msg + " at " + parser.getPositionDescription());
//         }
//     }
// 
//     @SuppressWarnings("serial")
//     public static final class IllegalStartTag extends ParseException {
//         public IllegalStartTag(final XmlPullParser parser, final String tag, final String parent) {
//             super("Illegal start tag " + tag + " in " + parent, parser);
//         }
//     }
// 
//     @SuppressWarnings("serial")
//     public static final class IllegalEndTag extends ParseException {
//         public IllegalEndTag(final XmlPullParser parser, final String tag, final String parent) {
//             super("Illegal end tag " + tag + " in " + parent, parser);
//         }
//     }
// 
//     @SuppressWarnings("serial")
//     public static final class IllegalAttribute extends ParseException {
//         public IllegalAttribute(final XmlPullParser parser, final String tag,
//                 final String attribute) {
//             super("Tag " + tag + " has illegal attribute " + attribute, parser);
//         }
//     }
// 
//     @SuppressWarnings("serial")
//     public static final class NonEmptyTag extends ParseException{
//         public NonEmptyTag(final XmlPullParser parser, final String tag) {
//             super(tag + " must be empty tag", parser);
//         }
//     }
// 
//     public static void checkEndTag(final String tag, final XmlPullParser parser)
//             throws XmlPullParserException, IOException {
//         if (parser.next() == XmlPullParser.END_TAG && tag.equals(parser.getName()))
//             return;
//         throw new NonEmptyTag(parser, tag);
//     }
// 
//     public static void checkAttributeExists(final TypedArray attr, final int attrId,
//             final String attrName, final String tag, final XmlPullParser parser)
//                     throws XmlPullParserException {
//         if (attr.hasValue(attrId)) {
//             return;
//         }
//         throw new ParseException(
//                 "No " + attrName + " attribute found in <" + tag + "/>", parser);
//     }
// }


// Path: app/src/main/java/com/vlath/keyboard/keyboard/internal/KeyStylesSet.java
import android.content.res.TypedArray;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.util.Log;
import android.util.SparseArray;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.util.Arrays;
import java.util.HashMap;
import com.vlath.keyboard.R;
import com.vlath.keyboard.latin.utils.XmlParseUtils;

                mStyleAttributes.put(index, a.getInt(index, 0) | styleFlags);
            }
        }

        private void readStringArray(final TypedArray a, final int index) {
            if (a.hasValue(index)) {
                mStyleAttributes.put(index, parseStringArray(a, index));
            }
        }
    }

    public void parseKeyStyleAttributes(final TypedArray keyStyleAttr, final TypedArray keyAttrs,
            final XmlPullParser parser) throws XmlPullParserException {
        final String styleName = keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_styleName);
        if (styleName == null) {
            throw new XmlParseUtils.ParseException(
                    KeyboardBuilder.TAG_KEY_STYLE + " has no styleName attribute", parser);
        }
        if (DEBUG) {
            Log.d(TAG, String.format("<%s styleName=%s />",
                    KeyboardBuilder.TAG_KEY_STYLE, styleName));
            if (mStyles.containsKey(styleName)) {
                Log.d(TAG, KeyboardBuilder.TAG_KEY_STYLE + " " + styleName + " is overridden at "
                        + parser.getPositionDescription());
            }
        }

        final String parentStyleInAttr = keyStyleAttr.getString(
                R.styleable.Keyboard_KeyStyle_parentStyle);
        if (parentStyleInAttr != null && !mStyles.containsKey(parentStyleInAttr)) {
            throw new XmlParseUtils.ParseException(