AdIntegrator.java package com.buildbox; import org.cocos2dx.lib.Cocos2dxAc tivity; import java.lang.ref.WeakReference; public class AdIntegrator { public static native boolean rewardedVideoDidEnd(); private static WeakReference<Cocos2dxAc tivity> activity; public static void initBridge(Cocos2dxActivity act){ activity = new WeakReference<Cocos2dxAc tivity>(act); } public static void initAds(){ } public static void showBanner(){ } public static void hideBanner(){ } public static boolean isBannerVisible(){ return true; } public static boolean isRewardedVideoAvialable(){ return true; } public static void showInterstitial(){ } public static void showRewardedVideo(){ } } PTPlayer.java package com.hhhhhhhh.hhh; import org.cocos2dx.lib.Cocos2dxAc tivity; import org.cocos2dx.lib.Cocos2dxGL SurfaceView; import org.cocos2dx.lib.Cocos2dxRe flectionHelper; import android.os.Build; import android.view.View; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.WindowManag er; import android.widget.Toast; import com.buildbox.AdIntegrator; import com.secrethq.store.PTStoreB ridge; import com.google.android.gms.ga mes.GamesActivityResultCod es; import com.secrethq.ads.*; import com.secrethq.utils.*; import android.content.SharedPrefe rences; import android.content.Context; public class PTPlayer extends Cocos2dxActivity { protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(reque stCode, resultCode, data); try { Log.v("---------","onActivityResult: request: " + requestCode + " result: "+ resultCode); if(PTStoreBridge.iabHelper(). handleActivityResult(request Code, resultCode, data) Log.v("----------", "handled by IABHelper"); } else if(requestCode == PTServicesBridge.RC_SIGN_I N){ SharedPreferences sharedPref = this.getPreferences(Context. MODE_PRIVATE); SharedPreferences.E ditor editor = sharedPref.edit(); if(resultCode == RESULT_OK){ PTServicesBridge.inst ance().onActivityResult(requ estCode, resultCode, data); editor.putBoolean(" GooglePlayServiceSignInError ", false); editor.commit(); } else if(resultCode == GamesActivityResultCodes.R ESULT_SIGN_IN_FAILED){ int duration = Toast.LENGTH_SHORT; Toast toast = Toast.makeText(this, "Google Play Services: Sign in error", duration); toast.show(); editor.putBoolean(" GooglePlayServiceSignInError ", true); editor.commit(); } else if(resultCode == GamesActivityResultCodes.R ESULT_APP_MISCONFIGURE D){ getWindow().addFla gs(WindowManager.LayoutP arams.FLAG_KEEP_SCREEN_ ON); } @Override public void onNativeInit(){ initBridges(); int duration = Toast.LENGTH_SHORT; private void initBridges(){ AdIntegrator.initBridge( this ); toast.show(); PTStoreBridge.initBri dge( this ); e) { Log.v("-----------", "onActivityResult FAIL on iabHelper : " + e.toString()); } } protected void onCreate(Bundle savedInstanceState) { super.onCreate(save dInstanceState); this.hideVirtualButto n(); PTServicesBridge.init Bridge(this, getString( R.string.app_id )); PTAdAdMobBridge.i nitBridge(this); } if (PTJniHelper.isAdNetworkAct ive("kAppLovin")) { } Toast toast = Toast.makeText(this, "Google Play Services: App misconfigured", duration); } } } catch (Exception if (PTJniHelper.isAdNetworkAct ive("kAdMob") || PTJniHelper.isAdNetworkActi ve("kFacebook")) { if (PTJniHelper.isAdNetworkAct ive("kChartboost")) { PTAdChartboostBrid ge.initBridge(this); } if (PTJniHelper.isAdNetworkAct ive("kRevMob")) { PTAdRevMobBridge.i nitBridge(this); } if (PTJniHelper.isAdNetworkAct ive("kInMobi")) { PTAdInMobiBridge.initBridge (this); } PTAdAppLovinBridge .initBridge(this); } if (PTJniHelper.isAdNetworkAct ive("kLeadBolt")) { PTAdLeadBoltBridge. initBridge(this); } if (PTJniHelper.isAdNetworkAct ive("kFacebook")) { PTAdFacebookBridge .initBridge(this); } if (PTJniHelper.isAdNetworkAct ive("kHeyzap")) { PTAdHeyzapBridge.in itBridge(this); } } @Override public Cocos2dxGLSurfaceView onCreateView() { } Cocos2dxGLSurfaceV iew glSurfaceView = new Cocos2dxGLSurfaceView(this ); glSurfaceView.setEG LConfigChooser(8, 8, 8, 0, 0, 0); return glSurfaceView; } static { System.loadLibrary(" player"); } @Override protected void onResume() { } @Override protected void onStart() { final int SYSTEM_UI_FLAG_LAYOUT_ HIDE_NAVIGATION = Cocos2dxReflectionHelper super.onStart(); if (PTJniHelper.isAdNetworkAct ive("kChartboost")) { .<Integer> getConstantValue(viewClass, PTAdChartboostBrid ge.onStart( this ); } } @Override protected void onStop() { n(); super.onStop(); if (PTJniHelper.isAdNetworkAct ive("kChartboost")) { super.onResume(); if (PTJniHelper.isAdNetworkAct ive("kChartboost")) { PTAdChartboostBrid ge.onStop( this ); } } PTAdChartboostBrid ge.onResume( this ); } } @Override protected void onDestroy() { this.hideVirtualButto @Override public void onWindowFocusChanged(bo olean hasFocus) { super.onWindowFoc usChanged(hasFocus); if (hasFocus) { this.hideVirtualButto n(); Class viewClass = View.class; "SYSTEM_UI_FLAG_L AYOUT_HIDE_NAVIGATION") ; final int SYSTEM_UI_FLAG_LAYOUT_F ULLSCREEN = Cocos2dxReflectionHelper .<Integer> getConstantValue(viewClass, "SYSTEM_UI_FLAG_L AYOUT_FULLSCREEN"); final int SYSTEM_UI_FLAG_HIDE_NAV IGATION = Cocos2dxReflectionHelper .<Integer> getConstantValue(viewClass, super.onDestroy(); } protected void hideVirtualButton() { if (Build.VERSION.SDK_INT >= 19) { // use reflection to remove dependence of API level "SYSTEM_UI_FLAG_ HIDE_NAVIGATION"); final int SYSTEM_UI_FLAG_FULLSCRE EN = Cocos2dxReflectionHelper .<Integer> getConstantValue(viewClass, SYSTEM_UI_FLAG_HIDE_NAV IGATION // hide nav bar "SYSTEM_UI_FLAG_F ULLSCREEN"); final int SYSTEM_UI_FLAG_IMMERSIV E_STICKY = Cocos2dxReflectionHelper .<Integer> getConstantValue(viewClass, "SYSTEM_UI_FLAG_I MMERSIVE_STICKY"); final int SYSTEM_UI_FLAG_LAYOUT_S TABLE = Cocos2dxReflectionHelper .<Integer> getConstantValue(viewClass, "SYSTEM_UI_FLAG_L AYOUT_STABLE"); // getWindow().getDecorView() .setSystemUiVisibility(); final Object[] parameters = new Object[] { SYSTEM_UI_FLAG_LAYOUT_S TABLE | SYSTEM_UI_FLAG_LAYOUT_ HIDE_NAVIGATION | SYSTEM_UI_FLAG_LAYOUT_F ULLSCREEN | | SYSTEM_UI_FLAG_FULLSCRE EN // hide status bar | SYSTEM_UI_FLAG_IMMERSIV E_STICKY }; Cocos2dxReflectionH elper.<Void> invokeInstanceMethod(getW indow() .getDecorView(), "setSystemUiVisibility", new Class[] { Integer.TYPE }, parameters); } } } PTAdAdMobBridge.java package com.hhhhhhhh.hhh; import org.cocos2dx.lib.Cocos2dxAc tivity; import org.cocos2dx.lib.Cocos2dxGL SurfaceView; import org.cocos2dx.lib.Cocos2dxRe flectionHelper; import android.os.Build; import android.view.View; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.WindowManag er; import android.widget.Toast; import com.buildbox.AdIntegrator; import com.secrethq.store.PTStoreB ridge; import com.google.android.gms.ga mes.GamesActivityResultCod es; import com.secrethq.ads.*; import com.secrethq.utils.*; import android.content.SharedPrefe rences; import android.content.Context; public class PTPlayer extends Cocos2dxActivity { protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(reque stCode, resultCode, data); try { Log.v("---------","onActivityResult: request: " + requestCode + " result: "+ resultCode); if(PTStoreBridge.iabHelper(). handleActivityResult(request Code, resultCode, data)){ Log.v("-----------", "handled by IABHelper"); } else if(requestCode == PTServicesBridge.RC_SIGN_I N){ SharedPreferences sharedPref = this.getPreferences(Context. MODE_PRIVATE); else if(resultCode == GamesActivityResultCodes.R ESULT_APP_MISCONFIGURE D){ @Override public void onNativeInit(){ initBridges(); SharedPreferences.E ditor editor = sharedPref.edit(); if(resultCode == RESULT_OK){ int duration = Toast.LENGTH_SHORT; Toast toast = Toast.makeText(this, "Google Play Services: App misconfigured", duration); private void initBridges(){ AdIntegrator.initBridge( this ); toast.show(); PTStoreBridge.initBri dge( this ); PTServicesBridge.inst ance().onActivityResult(requ estCode, resultCode, data); editor.putBoolean(" GooglePlayServiceSignInError ", false); editor.commit(); } else if(resultCode == GamesActivityResultCodes.R ESULT_SIGN_IN_FAILED){ int duration = Toast.LENGTH_SHORT; Toast toast = Toast.makeText(this, "Google Play Services: Sign in error", duration); } } } catch (Exception e) { if (PTJniHelper.isAdNetworkAct ive("kChartboost")) { Log.v("-----------", "onActivityResult FAIL on iabHelper : " + e.toString()); } } PTAdChartboostBrid ge.initBridge(this); } protected void onCreate(Bundle savedInstanceState) { super.onCreate(save dInstanceState); this.hideVirtualButto n(); toast.show(); editor.putBoolean(" GooglePlayServiceSignInError ", true); editor.commit(); } } PTServicesBridge.init Bridge(this, getString( R.string.app_id )); getWindow().addFla gs(WindowManager.LayoutP arams.FLAG_KEEP_SCREEN_ ON); } if (PTJniHelper.isAdNetworkAct ive("kRevMob")) { PTAdRevMobBridge.i nitBridge(this); } if (PTJniHelper.isAdNetworkAct ive("kInMobi")) { PTAdInMobiBridge.initBridge (this); } if (PTJniHelper.isAdNetworkAct ive("kAdMob") || PTJniHelper.isAdNetworkActi ve("kFacebook")) { PTAdAdMobBridge.i nitBridge(this); } glSurfaceView.setEG LConfigChooser(8, 8, 8, 0, 0, 0); if (PTJniHelper.isAdNetworkAct ive("kAppLovin")) { glSurfaceView; } PTAdAppLovinBridge .initBridge(this); } if (PTJniHelper.isAdNetworkAct ive("kLeadBolt")) { PTAdLeadBoltBridge. initBridge(this); } if (PTJniHelper.isAdNetworkAct ive("kFacebook")) { PTAdFacebookBridge .initBridge(this); } if (PTJniHelper.isAdNetworkAct ive("kHeyzap")) { PTAdHeyzapBridge.in itBridge(this); } } @Override public Cocos2dxGLSurfaceView onCreateView() { return static { System.loadLibrary(" player"); } @Override protected void onResume() { protected void onStart() { super.onStart(); if (PTJniHelper.isAdNetworkAct ive("kChartboost")) { PTAdChartboostBrid ge.onStart( this ); } } @Override protected void onStop() { n(); super.onStop(); if (PTJniHelper.isAdNetworkAct ive("kChartboost")) { super.onResume(); if (PTJniHelper.isAdNetworkAct ive("kChartboost")) { PTAdChartboostBrid ge.onStop( this ); } } PTAdChartboostBrid ge.onResume( this ); } } @Override protected void onDestroy() { this.hideVirtualButto @Override public void onWindowFocusChanged(bo olean hasFocus) { super.onWindowFoc usChanged(hasFocus); if (hasFocus) { super.onDestroy(); } protected void hideVirtualButton() { if (Build.VERSION.SDK_INT >= 19) { // use reflection to remove dependence of API level this.hideVirtualButto Cocos2dxGLSurfaceV iew glSurfaceView = new Cocos2dxGLSurfaceView(this ); n(); Class } } @Override viewClass = View.class; final int SYSTEM_UI_FLAG_LAYOUT_ HIDE_NAVIGATION = Cocos2dxReflectionHelper .<Integer> getConstantValue(viewClass, SYSTEM_UI_FLAG_IMMERSIV E_STICKY = Cocos2dxReflectionHelper .<Integer> getConstantValue(viewClass, "SYSTEM_UI_FLAG_L AYOUT_HIDE_NAVIGATION") ; final int SYSTEM_UI_FLAG_LAYOUT_F ULLSCREEN = Cocos2dxReflectionHelper "SYSTEM_UI_FLAG_I MMERSIVE_STICKY"); final int SYSTEM_UI_FLAG_LAYOUT_S TABLE = Cocos2dxReflectionHelper .<Integer> getConstantValue(viewClass, .<Integer> getConstantValue(viewClass, "SYSTEM_UI_FLAG_L AYOUT_FULLSCREEN"); final int SYSTEM_UI_FLAG_HIDE_NAV IGATION = Cocos2dxReflectionHelper "SYSTEM_UI_FLAG_L AYOUT_STABLE"); .<Integer> getConstantValue(viewClass, // getWindow().getDecorView() .setSystemUiVisibility(); final Object[] parameters = new Object[] { SYSTEM_UI_FLAG_LAYOUT_S TABLE "SYSTEM_UI_FLAG_ HIDE_NAVIGATION"); final int SYSTEM_UI_FLAG_FULLSCRE EN = Cocos2dxReflectionHelper | SYSTEM_UI_FLAG_LAYOUT_ HIDE_NAVIGATION .<Integer> getConstantValue(viewClass, | SYSTEM_UI_FLAG_HIDE_NAV IGATION // hide nav bar "SYSTEM_UI_FLAG_F ULLSCREEN"); final int | SYSTEM_UI_FLAG_FULLSCRE EN // hide status bar | SYSTEM_UI_FLAG_LAYOUT_F ULLSCREEN | SYSTEM_UI_FLAG_IMMERSIV E_STICKY }; Cocos2dxReflectionH elper.<Void> invokeInstanceMethod(getW indow() .getDecorView(), "setSystemUiVisibility", new Class[] { Integer.TYPE }, parameters); } } } PTAdAppLovinBridge.java package com.secrethq.ads; import org.cocos2dx.lib.Cocos2dxAc tivity; public class PTAdAppLovinBridge { public static void initBridge(Cocos2dxActivity activity){ } public static void startSession( String sdkKey ){ } public static void showFullScreen() { } public static void showPopup() { } public static void showBannerAd(){ } public static void hideBannerAd(){ } } PTAdChartboostBridge.java package com.secrethq.ads; import org.cocos2dx.lib.Cocos2dxAc tivity; import android.app.Activity; public class PTAdChartboostBridge { public static void initBridge(Cocos2dxActivity activity){ } public static void cacheInterstitial(final String location) { } public static void showInterstitial() { } public static void showInterstitial(final String location) { } public static void onResume( Activity act){ } public static void onStart( Activity act){ } public static void onStop( Activity act){ } } PTAdFacebookBridge package com.secrethq.ads; import org.cocos2dx.lib.Cocos2dxAc tivity; public class PTAdFacebookBridge { public static void initBridge(Cocos2dxActivity activity){ } public static void initBanner(){ } public static void initInterstitial(){ } public static void showFullScreen(){ } public static void showBannerAd(){ } public static void hideBannerAd(){ } public static boolean isBannerVisisble() { return false; } } PTAdHeyzapBridge.java package com.secrethq.ads; import org.cocos2dx.lib.Cocos2dxAc tivity; public class PTAdHeyzapBridge { public static void initBridge(Cocos2dxActivity activity){ } public static void initBanner(){ } public static void initInterstitial(){ } public static void initVideo() { } public static void startSession( String sdkKey ){ } public static void showFullScreen(){ } public static void showBannerAd(){ } public static void showRewardedVideo(){ } public static void hideBannerAd(){ } public static boolean isBannerVisisble() { return false; } public static boolean isRewardedVideoAvialable(){ return false; } } PTAdInMobiBridge.java package com.secrethq.ads; import org.cocos2dx.lib.Cocos2dxAc tivity; import android.app.Activity; public class PTAdInMobiBridge { public static void initBridge(Cocos2dxActivity activity){ } public static void showBanner() { } public static void hideBanner() { } public static void showInterstitial() { } } PTAdLeadBoltBridge.java package com.secrethq.ads; import org.cocos2dx.lib.Cocos2dxAc tivity; public class PTAdLeadBoltBridge { public static void hideBannerAd(){ } } PTAdRevMobBridge.java package com.secrethq.ads; import org.cocos2dx.lib.Cocos2dxAc tivity; public class PTAdRevMobBridge { public static void initBridge(Cocos2dxActivity activity){ } public static void startSession( String appid ){ } public static void showFullScreen(){ } public static void initBridge(Cocos2dxActivity activity){ } public static void showPopup(){ } public static void startSession( String sdkKey ){ } public static void showBannerAd(){ } public static void showFullScreen() { } public static void hideBannerAd(){ } public static void showPopup() { } } Base64.java package com.secrethq.ads; import org.cocos2dx.lib.Cocos2dxAc tivity; public static void showBannerAd(){ } public class PTAdRevMobBridge { public static void initBridge(Cocos2dxActivity activity){ } public static void startSession( String appid ){ } public static void showFullScreen(){ } public static void showPopup(){ } public static void showBannerAd(){ } public static void hideBannerAd(){ } } Base64DecoderException.ja va // Copyright 2002, Google, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licen ses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.secrethq.store.util; /** * Exception thrown when encountering an invalid Base64 input character. * * @author nelson */ public class Base64DecoderException extends Exception { public Base64DecoderException() { super(); } public Base64DecoderException(Str ing s) { super(s); } private static final long serialVersionUID = 1L; } IabException.java /* Copyright (c) 2012 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licen ses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.secrethq.store.util; /** * Exception thrown when something went wrong with in-app billing. * An IabException has an associated IabResult (an error). * To get the IAB result that caused this exception to be thrown, * call {@link #getResult()}. */ public class IabException extends Exception { IabResult mResult; public IabException(IabResult r) { this(r, null); } public IabException(int response, String message) { this(new IabResult(response, message)); } public IabException(IabResult r, Exception cause) { super(r.getMessage(), cause); mResult = r; } public IabException(int response, String message, Exception cause) { this(new IabResult(response, message), cause); } /** Returns the IAB result (error) that this exception signals. */ public IabResult getResult() { return mResult; } } IabHelper.java /* Copyright (c) 2012 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licen ses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.secrethq.store.util; import android.app.Activity; import android.app.PendingIntent; import android.content.Component Name; import android.content.Context; import android.content.Intent; import android.content.IntentSende r.SendIntentException; import android.content.ServiceConn ection; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException ; import android.text.TextUtils; import android.util.Log; import com.android.vending.billing.I InAppBillingService; import org.json.JSONException; import java.util.ArrayList; import java.util.List; /** * Provides convenience methods for in-app billing. You can create one instance of this * class for your application and use it to process in-app billing operations. * It provides synchronous (blocking) and asynchronous (non-blocking) methods for * many common in-app billing operations, as well as automatic signature * verification. * * After instantiating, you must perform setup in order to start using the object. * To perform setup, call the {@link #startSetup} method and provide a listener; * that listener will be notified when setup is complete, after which (and not before) * you may call other methods. * * After setup is complete, you will typically want to request an inventory of owned * items and subscriptions. See {@link #queryInventory}, {@link #queryInventoryAsync} * and related methods. * * When you are done with this object, don't forget to call {@link #dispose} * to ensure proper cleanup. This object holds a binding to the in-app billing * service, which will leak unless you dispose of it correctly. If you created * the object on an Activity's onCreate method, then the recommended * place to dispose of it is the Activity's onDestroy method. * * A note about threading: When using this object from a background thread, you may * call the blocking versions of methods; when using from a UI thread, call * only the asynchronous versions and handle the results via callbacks. * Also, notice that you can only call one asynchronous operation at a time; * attempting to start a second asynchronous operation while the first one * has not yet completed will result in an exception being thrown. * * @author Bruno Oliveira (Google) * */ public class IabHelper { // Is debug logging enabled? boolean mDebugLog = false; String mDebugTag = "IabHelper"; // Is setup done? boolean mSetupDone = false; // Has this object been disposed of? (If so, we should ignore callbacks, etc) boolean mDisposed = false; // Are subscriptions supported? boolean mSubscriptionsSupported = false; // Is an asynchronous operation in progress? // (only one at a time can be in progress) boolean mAsyncInProgress = false; // (for logging/debugging) // if mAsyncInProgress == true, what asynchronous operation is in progress? String mAsyncOperation = ""; // Context we were passed during initialization Context mContext; // Connection to the service IInAppBillingService mService; ServiceConnection mServiceConn; // The request code used to launch purchase flow int mRequestCode; // The item type of the current purchase flow String mPurchasingItemType; // Public key for verifying signature, in base64 encoding String mSignatureBase64 = null; // Billing response codes public static final int BILLING_RESPONSE_RESULT_ OK = 0; public static final int BILLING_RESPONSE_RESULT_ USER_CANCELED = 1; public static final int BILLING_RESPONSE_RESULT_ BILLING_UNAVAILABLE = 3; public static final int BILLING_RESPONSE_RESULT_ ITEM_UNAVAILABLE = 4; public static final int BILLING_RESPONSE_RESULT_ DEVELOPER_ERROR = 5; public static final int BILLING_RESPONSE_RESULT_ ERROR = 6; public static final int BILLING_RESPONSE_RESULT_ ITEM_ALREADY_OWNED = 7; public static final int BILLING_RESPONSE_RESULT_ ITEM_NOT_OWNED = 8; // IAB Helper error codes public static final int IABHELPER_ERROR_BASE = 1000; public static final int IABHELPER_REMOTE_EXCEP TION = -1001; public static final int IABHELPER_BAD_RESPONSE = -1002; public static final int IABHELPER_VERIFICATION_F AILED = -1003; public static final int IABHELPER_SEND_INTENT_F AILED = -1004; public static final int IABHELPER_USER_CANCELLE D = -1005; public static final int IABHELPER_UNKNOWN_PUR CHASE_RESPONSE = -1006; public static final int IABHELPER_MISSING_TOKEN = -1007; public static final int IABHELPER_UNKNOWN_ERR OR = -1008; public static final int IABHELPER_SUBSCRIPTIONS_ NOT_AVAILABLE = -1009; public static final int IABHELPER_INVALID_CONSU MPTION = -1010; // Keys for the responses from InAppBillingService public static final String RESPONSE_CODE = "RESPONSE_CODE"; public static final String RESPONSE_GET_SKU_DETAIL S_LIST = "DETAILS_LIST"; public static final String RESPONSE_BUY_INTENT = "BUY_INTENT"; public static final String RESPONSE_INAPP_PURCHAS E_DATA = "INAPP_PURCHASE_DATA"; public static final String RESPONSE_INAPP_SIGNATU RE = "INAPP_DATA_SIGNATURE"; public static final String RESPONSE_INAPP_ITEM_LIST = "INAPP_PURCHASE_ITEM_LI ST"; public static final String RESPONSE_INAPP_PURCHAS E_DATA_LIST = "INAPP_PURCHASE_DATA_LI ST"; public static final String RESPONSE_INAPP_SIGNATU RE_LIST = "INAPP_DATA_SIGNATURE_L IST"; public static final String INAPP_CONTINUATION_TOK EN = "INAPP_CONTINUATION_TO KEN"; // Item types public static final String ITEM_TYPE_INAPP = "inapp"; public static final String ITEM_TYPE_SUBS = "subs"; // some fields on the getSkuDetails response bundle public static final String GET_SKU_DETAILS_ITEM_LIS T = "ITEM_ID_LIST"; public static final String GET_SKU_DETAILS_ITEM_TY PE_LIST = "ITEM_TYPE_LIST"; /** * Creates an instance. After creation, it will not yet be ready to use. You must perform * setup by calling {@link #startSetup} and wait for setup to complete. This constructor does not * block and is safe to call from a UI thread. * * @param ctx Your application or Activity context. Needed to bind to the in-app billing service. * @param base64PublicKey Your application's public key, encoded in base64. * This is used for verification of purchase signatures. You can find your app's base64-encoded * public key in your application's page on Google Play Developer Console. Note that this * is NOT your "developer public key". */ public IabHelper(Context ctx, String base64PublicKey) { mContext = ctx.getApplicationContext(); mSignatureBase64 = base64PublicKey; logDebug("IAB helper created."); } /** * Enables or disable debug logging through LogCat. */ public void enableDebugLogging(boolea n enable, String tag) { checkNotDisposed(); mDebugLog = enable; mDebugTag = tag; } public void enableDebugLogging(boolea n enable) { checkNotDisposed(); mDebugLog = enable; } /** * Callback for setup process. This listener's {@link #onIabSetupFinished} method is called * when the setup process is complete. */ public interface OnIabSetupFinishedListener { /** * Called to notify that setup is complete. * * @param result The result of the setup process. */ public void onIabSetupFinished(IabResul t result); } /** * Starts the setup process. This will start up the setup process asynchronously. * You will be notified through the listener when the setup process is complete. * This method is safe to call from a UI thread. * * @param listener The listener to notify when the setup process is complete. */ public void startSetup(final OnIabSetupFinishedListener listener) { // If already set up, can't do it again. checkNotDisposed(); if (mSetupDone) throw new IllegalStateException("IAB helper is already set up."); // Connection to IAB service logDebug("Starting inapp billing setup."); mServiceConn = new ServiceConnection() { @Override public void onServiceDisconnected(Com ponentName name) { logDebug("Billing service disconnected."); mService = null; } @Override public void onServiceConnected(Compo nentName name, IBinder service) { if (mDisposed) return; logDebug("Billing service connected."); mService = IInAppBillingService.Stub.asI nterface(service); String packageName = mContext.getPackageName() ; try { logDebug("Checking for inapp billing 3 support."); // check for inapp billing v3 support int response = mService.isBillingSupported( 3, packageName, ITEM_TYPE_INAPP); if (response != BILLING_RESPONSE_RESULT_ OK) { if (listener != null) listener.onIabSetupFinished( new IabResult(response, "Error checking for billing v3 support.")); // if in-app purchases aren't supported, neither are subscriptions. "RemoteException while setting up in-app billing.")); } mSubscriptionsSupported = false; return; } logDebug("In-app billing version 3 supported for " + packageName); e.printStackTrace(); return; } // check for v3 subscriptions support response = mService.isBillingSupported( 3, packageName, ITEM_TYPE_SUBS); if (response == BILLING_RESPONSE_RESULT_ OK) { logDebug("Subscriptions AVAILABLE."); mSubscriptionsSupported = true; } else { logDebug("Subscriptions NOT AVAILABLE. Response: " + response); } mSetupDone = true; } catch (RemoteException e) { if (listener != null) { listener.onIabSetupFinished( new IabResult(IABHELPER_REMO TE_EXCEPTION, if (listener != null) { listener.onIabSetupFinished( new IabResult(BILLING_RESPONS E_RESULT_OK, "Setup successful.")); } } }; Intent serviceIntent = new Intent("com.android.vending .billing.InAppBillingService.BI ND"); serviceIntent.setPackage("co m.android.vending"); if (!mContext.getPackageMana ger().queryIntentServices(ser viceIntent, 0).isEmpty()) { // service available to handle that Intent mContext.bindService(servic eIntent, mServiceConn, Context.BIND_AUTO_CREATE ); } else { // no service available to handle that Intent if (listener != null) { listener.onIabSetupFinished( new IabResult(BILLING_RESPONS E_RESULT_BILLING_UNAVAIL ABLE, "Billing service unavailable on device.")); } } } /** * Dispose of object, releasing resources. It's very important to call this * method when you are done with this object. It will release any resources * used by it such as service connections. Naturally, once the object is * disposed of, it can't be used again. */ public void dispose() { logDebug("Disposing."); mSetupDone = false; if (mServiceConn != null) { logDebug("Unbinding from service."); if (mContext != null) mContext.unbindService(mS erviceConn); } mDisposed = true; mContext = null; mServiceConn = null; mService = null; mPurchaseListener = null; } private void checkNotDisposed() { if (mDisposed) throw new IllegalStateException("IabHel per was disposed of, so it cannot be used."); } /** Returns whether subscriptions are supported. */ public boolean subscriptionsSupported() { checkNotDisposed(); return mSubscriptionsSupported; } /** * Callback that notifies when a purchase is finished. */ public interface OnIabPurchaseFinishedListen er { /** * Called to notify that an in-app purchase finished. If the purchase was successful, * then the sku parameter specifies which item was purchased. If the purchase failed, * the sku and extraData parameters may or may not be null, depending on how far the purchase * process went. * * @param result The result of the purchase. * @param info The purchase information (null if purchase failed) */ public void onIabPurchaseFinished(IabRe sult result, Purchase info); } // The listener registered on launchPurchaseFlow, which we have to call back when // the purchase finishes OnIabPurchaseFinishedListen er mPurchaseListener; public void launchPurchaseFlow(Activity act, String sku, int requestCode, OnIabPurchaseFinishedListen er listener) { launchPurchaseFlow(act, sku, requestCode, listener, ""); } public void launchPurchaseFlow(Activity act, String sku, int requestCode, OnIabPurchaseFinishedListen er listener, String extraData) { launchPurchaseFlow(act, sku, ITEM_TYPE_INAPP, requestCode, listener, extraData); } public void launchSubscriptionPurchaseF low(Activity act, String sku, int requestCode, OnIabPurchaseFinishedListen er listener) { launchSubscriptionPurchaseF low(act, sku, requestCode, listener, ""); } public void launchSubscriptionPurchaseF low(Activity act, String sku, int requestCode, OnIabPurchaseFinishedListen er listener, String extraData) { launchPurchaseFlow(act, sku, ITEM_TYPE_SUBS, requestCode, listener, extraData); } /** * Initiate the UI flow for an in-app purchase. Call this method to initiate an in-app purchase, * which will involve bringing up the Google Play screen. The calling activity will be paused while * the user interacts with Google Play, and the result will be delivered via the activity's * {@link android.app.Activity#onActiv ityResult} method, at which point you must call * this object's {@link #handleActivityResult} method to continue the purchase flow. This method * MUST be called from the UI thread of the Activity. * * @param act The calling activity. * @param sku The sku of the item to purchase. * @param itemType indicates if it's a product or a subscription (ITEM_TYPE_INAPP or ITEM_TYPE_SUBS) * @param requestCode A request code (to differentiate from other responses -* as in {@link android.app.Activity#startAct ivityForResult}). * @param listener The listener to notify when the purchase process finishes * @param extraData Extra data (developer payload), which will be returned with the purchase data * when the purchase completes. This extra data will be permanently bound to that purchase * and will always be returned when the purchase is queried. */ public void launchPurchaseFlow(Activity act, String sku, String itemType, int requestCode, OnIabPurchaseFinishedListen er listener, String extraData) { checkNotDisposed(); checkSetupDone("launchPur chaseFlow"); flagStartAsync("launchPurch aseFlow"); IabResult result; if (itemType.equals(ITEM_TYPE _SUBS) && !mSubscriptionsSupported) { IabResult r = new IabResult(IABHELPER_SUBSC RIPTIONS_NOT_AVAILABLE, "Subscriptions are not available."); flagEndAsync(); if (listener != null) listener.onIabPurchaseFinish ed(r, null); return; } try { logDebug("Constructing buy intent for " + sku + ", item type: " + itemType); Bundle buyIntentBundle = mService.getBuyIntent(3, mContext.getPackageName() , sku, itemType, extraData); int response = getResponseCodeFromBundl e(buyIntentBundle); if (response != BILLING_RESPONSE_RESULT_ OK) { logError("Unable to buy item, Error response: " + getResponseDesc(response)) ; flagEndAsync(); result = new IabResult(response, "Unable to buy item"); if (listener != null) listener.onIabPurchaseFinish ed(result, null); return; } PendingIntent pendingIntent = buyIntentBundle.getParcelab le(RESPONSE_BUY_INTENT); logDebug("Launching buy intent for " + sku + ". Request code: " + requestCode); mRequestCode = requestCode; mPurchaseListener = listener; mPurchasingItemType = itemType; act.startIntentSenderForResu lt(pendingIntent.getIntentSe nder(), requestCode, new Intent(), Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0)); } catch (SendIntentException e) { logError("SendIntentExceptio n while launching purchase flow for sku " + sku); e.printStackTrace(); flagEndAsync(); result = new IabResult(IABHELPER_SEND_I NTENT_FAILED, "Failed to send intent."); if (listener != null) listener.onIabPurchaseFinish ed(result, null); } catch (RemoteException e) { logError("RemoteException while launching purchase flow for sku " + sku); e.printStackTrace(); flagEndAsync(); result = new IabResult(IABHELPER_REMO TE_EXCEPTION, "Remote exception while starting purchase flow"); if (listener != null) listener.onIabPurchaseFinish ed(result, null); } } /** * Handles an activity result that's part of the purchase flow in in-app billing. If you * are calling {@link #launchPurchaseFlow}, then you must call this method from your * Activity's {@link android.app.Activity@onActi vityResult} method. This method * MUST be called from the UI thread of the Activity. * * @param requestCode The requestCode as you received it. * @param resultCode The resultCode as you received it. * @param data The data (Intent) as you received it. * @return Returns true if the result was related to a purchase flow and was handled; * false if the result was not related to a purchase, in which case you should * handle it normally. */ public boolean handleActivityResult(int requestCode, int resultCode, Intent data) { IabResult result; if (requestCode != mRequestCode) return false; checkNotDisposed(); checkSetupDone("handleActi vityResult"); // end of async purchase operation that started on launchPurchaseFlow flagEndAsync(); if (data == null) { logError("Null data in IAB activity result."); result = new IabResult(IABHELPER_BAD_R ESPONSE, "Null data in IAB result"); if (mPurchaseListener != null) mPurchaseListener.onIabPur chaseFinished(result, null); return true; } int responseCode = getResponseCodeFromIntent (data); String purchaseData = data.getStringExtra(RESPONS E_INAPP_PURCHASE_DATA); String dataSignature = data.getStringExtra(RESPONS E_INAPP_SIGNATURE); if (resultCode == Activity.RESULT_OK && responseCode == BILLING_RESPONSE_RESULT_ OK) { logDebug("Successful resultcode from purchase activity."); logDebug("Purchase data: " + purchaseData); logDebug("Data signature: " + dataSignature); logDebug("Extras: " + data.getExtras()); logDebug("Expected item type: " + mPurchasingItemType); if (purchaseData == null || dataSignature == null) { logError("BUG: either purchaseData or dataSignature is null."); logDebug("Extras: " + data.getExtras().toString()); result = new IabResult(IABHELPER_UNKN OWN_ERROR, "IAB returned null purchaseData or dataSignature"); if (mPurchaseListener != null) mPurchaseListener.onIabPur chaseFinished(result, null); return true; } Purchase purchase = null; try { purchase = new Purchase(mPurchasingItemT ype, purchaseData, dataSignature); String sku = purchase.getSku(); // Verify signature if (!Security.verifyPurchase(mSi gnatureBase64, purchaseData, dataSignature)) { logError("Purchase signature verification FAILED for sku " + sku); result = new IabResult(IABHELPER_VERIFI CATION_FAILED, "Signature verification failed for sku " + sku); if (mPurchaseListener != null) mPurchaseListener.onIabPur chaseFinished(result, purchase); return true; } logDebug("Purchase signature successfully verified."); } catch (JSONException e) { logError("Failed to parse purchase data."); e.printStackTrace(); result = new IabResult(IABHELPER_BAD_R ESPONSE, "Failed to parse purchase data."); if (mPurchaseListener != null) mPurchaseListener.onIabPur chaseFinished(result, null); return true; } if (mPurchaseListener != null) { mPurchaseListener.onIabPur chaseFinished(new IabResult(BILLING_RESPONS E_RESULT_OK, "Success"), purchase); } } else if (resultCode == Activity.RESULT_OK) { // result code was OK, but in-app billing response was not OK. logDebug("Result code was OK but in-app billing response was not OK: " + getResponseDesc(responseC ode)); if (mPurchaseListener != null) { result = new IabResult(responseCode, "Problem purchashing item."); mPurchaseListener.onIabPur chaseFinished(result, null); } } else if (resultCode == Activity.RESULT_CANCELED) { logDebug("Purchase canceled - Response: " + getResponseDesc(responseC ode)); result = new IabResult(IABHELPER_USER_ CANCELLED, "User canceled."); if (mPurchaseListener != null) mPurchaseListener.onIabPur chaseFinished(result, null); } else { logError("Purchase failed. Result code: " + Integer.toString(resultCode) + ". Response: " + getResponseDesc(responseC ode)); result = new IabResult(IABHELPER_UNKN OWN_PURCHASE_RESPONSE , "Unknown purchase response."); if (mPurchaseListener != null) mPurchaseListener.onIabPur chaseFinished(result, null); } return true; } public Inventory queryInventory(boolean querySkuDetails, List<String> moreSkus) throws IabException { return queryInventory(querySkuDet ails, moreSkus, null); } /** * Queries the inventory. This will query all owned items from the server, as well as * information on additional skus, if specified. This method may block or take long to execute. * Do not call from a UI thread. For that, use the non-blocking version {@link #refreshInventoryAsync}. * * @param querySkuDetails if true, SKU details (price, description, etc) will be queried as well * as purchase information. * @param moreItemSkus additional PRODUCT skus to query information on, regardless of ownership. * Ignored if null or if querySkuDetails is false. * @param moreSubsSkus additional SUBSCRIPTIONS skus to query information on, regardless of ownership. * Ignored if null or if querySkuDetails is false. * @throws IabException if a problem occurs while refreshing the inventory. */ public Inventory queryInventory(boolean querySkuDetails, List<String> moreItemSkus, List<String> moreSubsSkus) throws IabException { checkNotDisposed(); checkSetupDone("queryInve ntory"); try { Inventory inv = new Inventory(); int r = queryPurchases(inv, ITEM_TYPE_INAPP); if (r != BILLING_RESPONSE_RESULT_ OK) { throw new IabException(r, "Error refreshing inventory (querying owned items)."); } if (querySkuDetails) { r= querySkuDetails(ITEM_TYPE_ INAPP, inv, moreItemSkus); if (r != BILLING_RESPONSE_RESULT_ OK) { throw new IabException(r, "Error refreshing inventory (querying prices of items)."); } } // if subscriptions are supported, then also query for subscriptions if (mSubscriptionsSupported) { r= queryPurchases(inv, ITEM_TYPE_SUBS); if (r != BILLING_RESPONSE_RESULT_ OK) { throw new IabException(r, "Error refreshing inventory (querying owned subscriptions)."); } if (querySkuDetails) { r= querySkuDetails(ITEM_TYPE_ SUBS, inv, moreItemSkus); if (r != BILLING_RESPONSE_RESULT_ OK) { throw new IabException(r, "Error refreshing inventory (querying prices of subscriptions)."); } } } return inv; } catch (RemoteException e) { throw new IabException(IABHELPER_RE MOTE_EXCEPTION, "Remote exception while refreshing inventory.", e); } catch (JSONException e) { throw new IabException(IABHELPER_BA D_RESPONSE, "Error parsing JSON response while refreshing inventory.", e); } } /** * Listener that notifies when an inventory query operation completes. */ public interface QueryInventoryFinishedListe ner { /** * Called to notify that an inventory query operation completed. * * @param result The result of the operation. * @param inv The inventory. */ public void onQueryInventoryFinished(Ia bResult result, Inventory inv); } /** * Asynchronous wrapper for inventory query. This will perform an inventory * query as described in {@link #queryInventory}, but will do so asynchronously * and call back the specified listener upon completion. This method is safe to * call from a UI thread. * * @param querySkuDetails as in {@link #queryInventory} * @param moreSkus as in {@link #queryInventory} * @param listener The listener to notify when the refresh operation completes. */ public void queryInventoryAsync(final boolean querySkuDetails, final List<String> moreSkus, final QueryInventoryFinishedListe ner listener) { final Handler handler = new Handler(); checkNotDisposed(); checkSetupDone("queryInve ntory"); flagStartAsync("refresh inventory"); (new Thread(new Runnable() { public void run() { IabResult result = new IabResult(BILLING_RESPONS E_RESULT_OK, "Inventory refresh successful."); Inventory inv = null; try { inv = queryInventory(querySkuDet ails, moreSkus); } catch (IabException ex) { result = ex.getResult(); } flagEndAsync(); final IabResult result_f = result; final Inventory inv_f = inv; if (!mDisposed && listener != null) { handler.post(new Runnable() { public void run() { listener.onQueryInventoryFin ished(result_f, inv_f); } }); } } })).start(); } public void queryInventoryAsync(QueryI nventoryFinishedListener listener) { queryInventoryAsync(true, null, listener); } public void queryInventoryAsync(boolea n querySkuDetails, QueryInventoryFinishedListe ner listener) { queryInventoryAsync(queryS kuDetails, null, listener); } /** * Consumes a given in-app product. Consuming can only be done on an item * that's owned, and as a result of consumption, the user will no longer own it. * This method may block or take long to return. Do not call from the UI thread. * For that, see {@link #consumeAsync}. * * @param itemInfo The PurchaseInfo that represents the item to consume. * @throws IabException if there is a problem during consumption. */ void consume(Purchase itemInfo) throws IabException { checkNotDisposed(); checkSetupDone("consume") ; if (!itemInfo.mItemType.equals (ITEM_TYPE_INAPP)) { throw new IabException(IABHELPER_INV ALID_CONSUMPTION, "Items of type '" + itemInfo.mItemType + "' can't be consumed."); } try { String token = itemInfo.getToken(); String sku = itemInfo.getSku(); if (token == null || token.equals("")) { logError("Can't consume "+ sku + ". No token."); throw new IabException(IABHELPER_MI SSING_TOKEN, "PurchaseInfo is missing token for sku: " + sku + " " + itemInfo); } logDebug("Consuming sku: " + sku + ", token: " + token); int response = mService.consumePurchase( 3, mContext.getPackageName() , token); if (response == BILLING_RESPONSE_RESULT_ OK) { logDebug("Successfully consumed sku: " + sku); } else { logDebug("Error consuming consuming sku " + sku + ". " + getResponseDesc(response)) ; throw new IabException(response, "Error consuming sku " + sku); } } catch (RemoteException e) { throw new IabException(IABHELPER_RE MOTE_EXCEPTION, "Remote exception while consuming. PurchaseInfo: " + itemInfo, e); } } /** * Callback that notifies when a consumption operation finishes. */ public interface OnConsumeFinishedListener { /** * Called to notify that a consumption has finished. * * @param purchase The purchase that was (or was to be) consumed. * @param result The result of the consumption operation. */ public void onConsumeFinished(Purchas e purchase, IabResult result); } /** * Callback that notifies when a multi-item consumption operation finishes. */ public interface OnConsumeMultiFinishedList ener { /** * Called to notify that a consumption of multiple items has finished. * * @param purchases The purchases that were (or were to be) consumed. * @param results The results of each consumption operation, corresponding to each * sku. */ public void onConsumeMultiFinished(Lis t<Purchase> purchases, List<IabResult> results); } /** * Asynchronous wrapper to item consumption. Works like {@link #consume}, but * performs the consumption in the background and notifies completion through * the provided listener. This method is safe to call from a UI thread. * * @param purchase The purchase to be consumed. * @param listener The listener to notify when the consumption operation finishes. */ public void consumeAsync(Purchase purchase, OnConsumeFinishedListener listener) { checkNotDisposed(); checkSetupDone("consume") ; List<Purchase> purchases = new ArrayList<Purchase>(); purchases.add(purchase); consumeAsyncInternal(purch ases, listener, null); } /** * Same as {@link consumeAsync}, but for multiple items at once. * @param purchases The list of PurchaseInfo objects representing the purchases to consume. * @param listener The listener to notify when the consumption operation finishes. */ public void consumeAsync(List<Purchase > purchases, OnConsumeMultiFinishedList ener listener) { checkNotDisposed(); checkSetupDone("consume") ; consumeAsyncInternal(purch ases, null, listener); } /** * Returns a humanreadable description for the given response code. * * @param code The response code * @return A humanreadable string explaining the result code. * It also includes the result code numerically. */ public static String getResponseDesc(int code) { String[] iab_msgs = ("0:OK/1:User Canceled/2:Unknown/" + "3:Billing Unavailable/4:Item unavailable/" + "5:Developer Error/6:Error/7:Item Already Owned/" + "8:Item not owned").split("/"); String[] iabhelper_msgs = ("0:OK/-1001:Remote exception during initialization/" + "1002:Bad response received/" + "1003:Purchase signature verification failed/" + "1004:Send intent failed/" + "1005:User cancelled/" + "1006:Unknown purchase response/" + "1007:Missing token/" + "1008:Unknown error/" + "1009:Subscriptions not available/" + "1010:Invalid consumption attempt").split("/"); if (code <= IABHELPER_ERROR_BASE) { int index = IABHELPER_ERROR_BASE code; if (index >= 0 && index < iabhelper_msgs.length) return iabhelper_msgs[index]; else return String.valueOf(code) + ":Unknown IAB Helper Error"; } else if (code < 0 || code >= iab_msgs.length) return String.valueOf(code) + ":Unknown"; else return iab_msgs[code]; } // Checks that setup was done; if not, throws an exception. void checkSetupDone(String operation) { if (!mSetupDone) { logError("Illegal state for operation (" + operation + "): IAB helper is not set up."); throw new IllegalStateException("IAB helper is not set up. Can't perform operation: " + operation); } } // Workaround to bug where sometimes response codes come as Long instead of Integer int getResponseCodeFromBundl e(Bundle b) { Object o = b.get(RESPONSE_CODE); if (o == null) { logDebug("Bundle with null response code, assuming OK (known issue)"); return BILLING_RESPONSE_RESULT_ OK; } else if (o instanceof Integer) return ((Integer)o).intValue(); else if (o instanceof Long) return (int)((Long)o).longValue(); else { logError("Unexpected type for bundle response code."); logError(o.getClass().getNam e()); throw new RuntimeException("Unexpec ted type for bundle response code: " + o.getClass().getName()); } } // Workaround to bug where sometimes response codes come as Long instead of Integer int getResponseCodeFromIntent (Intent i) { Object o = i.getExtras().get(RESPONSE_ CODE); if (o == null) { logError("Intent with no response code, assuming OK (known issue)"); return BILLING_RESPONSE_RESULT_ OK; } else if (o instanceof Integer) return ((Integer)o).intValue(); else if (o instanceof Long) return (int)((Long)o).longValue(); else { logError("Unexpected type for intent response code."); logError(o.getClass().getNam e()); throw new RuntimeException("Unexpec ted type for intent response code: " + o.getClass().getName()); } } void flagStartAsync(String operation) { if (mAsyncInProgress) throw new IllegalStateException("Can't start async operation (" + operation + ") because another async operation(" + mAsyncOperation + ") is in progress."); mAsyncOperation = operation; mAsyncInProgress = true; logDebug("Starting async operation: " + operation); } void flagEndAsync() { logDebug("Ending async operation: " + mAsyncOperation); mAsyncOperation = ""; mAsyncInProgress = false; } int queryPurchases(Inventory inv, String itemType) throws JSONException, RemoteException { // Query purchases logDebug("Querying owned items, item type: " + itemType); logDebug("Package name: " + mContext.getPackageName() ); boolean verificationFailed = false; String continueToken = null; do { logDebug("Calling getPurchases with continuation token: " + continueToken); Bundle ownedItems = mService.getPurchases(3, mContext.getPackageName() , itemType, continueToken); int response = getResponseCodeFromBundl e(ownedItems); logDebug("Owned items response: " + String.valueOf(response)); if (response != BILLING_RESPONSE_RESULT_ OK) { logDebug("getPurchases() failed: " + getResponseDesc(response)) ; return response; } if (!ownedItems.containsKey(R ESPONSE_INAPP_ITEM_LIST) || !ownedItems.containsKey(RE SPONSE_INAPP_PURCHASE_ DATA_LIST) || !ownedItems.containsKey(RE SPONSE_INAPP_SIGNATURE_ LIST)) { logError("Bundle returned from getPurchases() doesn't contain required fields."); return IABHELPER_BAD_RESPONSE; } ArrayList<String> ownedSkus = ownedItems.getStringArrayLi st( RESPONSE_INAPP_ITEM_LIST ); ArrayList<String> purchaseDataList = ownedItems.getStringArrayLi st( RESPONSE_INAPP_PURCHAS E_DATA_LIST); ArrayList<String> signatureList = ownedItems.getStringArrayLi st( RESPONSE_INAPP_SIGNATU RE_LIST); for (int i = 0; i < purchaseDataList.size(); ++i) { String purchaseData = purchaseDataList.get(i); String signature = signatureList.get(i); String sku = ownedSkus.get(i); if (Security.verifyPurchase(mSi gnatureBase64, purchaseData, signature)) { logDebug("Sku is owned: " + sku); Purchase purchase = new Purchase(itemType, purchaseData, signature); if (TextUtils.isEmpty(purchase. getToken())) { logWarn("BUG: empty/null token!"); logDebug("Purchase data: " + purchaseData); } // Record ownership and token inv.addPurchase(purchase); } else { logWarn("Purchase signature verification **FAILED**. Not adding item."); logDebug(" Purchase data: " + purchaseData); logDebug(" Signature: " + signature); verificationFailed = true; } } continueToken = ownedItems.getString(INAPP _CONTINUATION_TOKEN); logDebug("Continuation token: " + continueToken); } while (!TextUtils.isEmpty(continue Token)); return verificationFailed ? IABHELPER_VERIFICATION_F AILED : BILLING_RESPONSE_RESULT_ OK; } int querySkuDetails(String itemType, Inventory inv, List<String> moreSkus) throws RemoteException, JSONException { logDebug("Querying SKU details."); ArrayList<String> skuList = new ArrayList<String>(); skuList.addAll(inv.getAllOwn edSkus(itemType)); if (moreSkus != null) { for (String sku : moreSkus) { if (!skuList.contains(sku)) { skuList.add(sku); } } } if (skuList.size() == 0) { logDebug("queryPrices: nothing to do because there are no SKUs."); return BILLING_RESPONSE_RESULT_ OK; } Bundle querySkus = new Bundle(); querySkus.putStringArrayList (GET_SKU_DETAILS_ITEM_LI ST, skuList); Bundle skuDetails = mService.getSkuDetails(3, mContext.getPackageName() , itemType, querySkus); if (!skuDetails.containsKey(RES PONSE_GET_SKU_DETAILS_LI ST)) { int response = getResponseCodeFromBundl e(skuDetails); if (response != BILLING_RESPONSE_RESULT_ OK) { logDebug("getSkuDetails() failed: " + getResponseDesc(response)) ; return response; } else { logError("getSkuDetails() returned a bundle with neither an error nor a detail list."); return IABHELPER_BAD_RESPONSE; } } ArrayList<String> responseList = skuDetails.getStringArrayList( RESPONSE_GET_SKU_DETAIL S_LIST); for (String thisResponse : responseList) { SkuDetails d = new SkuDetails(itemType, thisResponse); logDebug("Got sku details: " + d); inv.addSkuDetails(d); } return BILLING_RESPONSE_RESULT_ OK; } void consumeAsyncInternal(final List<Purchase> purchases, final OnConsumeFinishedListener singleListener, final OnConsumeMultiFinishedList ener multiListener) { final Handler handler = new Handler(); flagStartAsync("consume"); (new Thread(new Runnable() { public void run() { final List<IabResult> results = new ArrayList<IabResult>(); for (Purchase purchase : purchases) { try { consume(purchase); results.add(new IabResult(BILLING_RESPONS E_RESULT_OK, "Successful consume of sku " + purchase.getSku())); } catch (IabException ex) { results.add(ex.getResult()); } } flagEndAsync(); if (!mDisposed && singleListener != null) { handler.post(new Runnable() { public void run() { singleListener.onConsumeFin ished(purchases.get(0), results.get(0)); } }); } if (!mDisposed && multiListener != null) { handler.post(new Runnable() { public void run() { multiListener.onConsumeMu ltiFinished(purchases, results); } }); } } })).start(); { * See the License for the specific language governing permissions and * limitations under the License. */ if (mDebugLog) Log.d(mDebugTag, msg); } package com.secrethq.store.util; } void logDebug(String msg) void logError(String msg) { Log.e(mDebugTag, "Inapp billing error: " + msg); } void logWarn(String msg) { Log.w(mDebugTag, "Inapp billing warning: " + msg); } } IabResult.java /* Copyright (c) 2012 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licen ses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. import android.app.Activity; import android.app.PendingIntent; import android.content.Component Name; import android.content.Context; import android.content.Intent; import android.content.IntentSende r.SendIntentException; import android.content.ServiceConn ection; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException ; import android.text.TextUtils; import android.util.Log; import com.android.vending.billing.I InAppBillingService; import org.json.JSONException; import java.util.ArrayList; import java.util.List; /** * Provides convenience methods for in-app billing. You can create one instance of this * class for your application and use it to process in-app billing operations. * It provides synchronous (blocking) and asynchronous (non-blocking) methods for * many common in-app billing operations, as well as automatic signature * verification. * * After instantiating, you must perform setup in order to start using the object. * To perform setup, call the {@link #startSetup} method and provide a listener; * that listener will be notified when setup is complete, after which (and not before) * you may call other methods. * * After setup is complete, you will typically want to request an inventory of owned * items and subscriptions. See {@link #queryInventory}, {@link #queryInventoryAsync} * and related methods. * * When you are done with this object, don't forget to call {@link #dispose} * to ensure proper cleanup. This object holds a binding to the in-app billing * service, which will leak unless you dispose of it correctly. If you created * the object on an Activity's onCreate method, then the recommended * place to dispose of it is the Activity's onDestroy method. * * A note about threading: When using this object from a background thread, you may * call the blocking versions of methods; when using from a UI thread, call * only the asynchronous versions and handle the results via callbacks. * Also, notice that you can only call one asynchronous operation at a time; * attempting to start a second asynchronous operation while the first one * has not yet completed will result in an exception being thrown. * * @author Bruno Oliveira (Google) * */ public class IabHelper { // Is debug logging enabled? boolean mDebugLog = false; String mDebugTag = "IabHelper"; // Is setup done? boolean mSetupDone = false; // Has this object been disposed of? (If so, we should ignore callbacks, etc) boolean mDisposed = false; // Are subscriptions supported? boolean mSubscriptionsSupported = false; // Is an asynchronous operation in progress? // (only one at a time can be in progress) boolean mAsyncInProgress = false; // (for logging/debugging) // if mAsyncInProgress == true, what asynchronous operation is in progress? String mAsyncOperation = ""; // Context we were passed during initialization Context mContext; // Connection to the service IInAppBillingService mService; ServiceConnection mServiceConn; // The request code used to launch purchase flow int mRequestCode; // The item type of the current purchase flow String mPurchasingItemType; // Public key for verifying signature, in base64 encoding String mSignatureBase64 = null; // Billing response codes public static final int BILLING_RESPONSE_RESULT_ OK = 0; public static final int BILLING_RESPONSE_RESULT_ USER_CANCELED = 1; public static final int BILLING_RESPONSE_RESULT_ BILLING_UNAVAILABLE = 3; public static final int BILLING_RESPONSE_RESULT_ ITEM_UNAVAILABLE = 4; public static final int BILLING_RESPONSE_RESULT_ DEVELOPER_ERROR = 5; public static final int BILLING_RESPONSE_RESULT_ ERROR = 6; public static final int BILLING_RESPONSE_RESULT_ ITEM_ALREADY_OWNED = 7; public static final int BILLING_RESPONSE_RESULT_ ITEM_NOT_OWNED = 8; // IAB Helper error codes public static final int IABHELPER_ERROR_BASE = 1000; public static final int IABHELPER_REMOTE_EXCEP TION = -1001; public static final int IABHELPER_BAD_RESPONSE = -1002; public static final int IABHELPER_VERIFICATION_F AILED = -1003; public static final int IABHELPER_SEND_INTENT_F AILED = -1004; public static final int IABHELPER_USER_CANCELLE D = -1005; public static final int IABHELPER_UNKNOWN_PUR CHASE_RESPONSE = -1006; public static final int IABHELPER_MISSING_TOKEN = -1007; public static final int IABHELPER_UNKNOWN_ERR OR = -1008; public static final int IABHELPER_SUBSCRIPTIONS_ NOT_AVAILABLE = -1009; public static final int IABHELPER_INVALID_CONSU MPTION = -1010; // Keys for the responses from InAppBillingService public static final String RESPONSE_CODE = "RESPONSE_CODE"; public static final String RESPONSE_GET_SKU_DETAIL S_LIST = "DETAILS_LIST"; public static final String RESPONSE_BUY_INTENT = "BUY_INTENT"; public static final String RESPONSE_INAPP_PURCHAS E_DATA = "INAPP_PURCHASE_DATA"; public static final String RESPONSE_INAPP_SIGNATU RE = "INAPP_DATA_SIGNATURE"; public static final String RESPONSE_INAPP_ITEM_LIST = "INAPP_PURCHASE_ITEM_LI ST"; public static final String RESPONSE_INAPP_PURCHAS E_DATA_LIST = "INAPP_PURCHASE_DATA_LI ST"; public static final String RESPONSE_INAPP_SIGNATU RE_LIST = "INAPP_DATA_SIGNATURE_L IST"; public static final String INAPP_CONTINUATION_TOK EN = "INAPP_CONTINUATION_TO KEN"; // Item types public static final String ITEM_TYPE_INAPP = "inapp"; public static final String ITEM_TYPE_SUBS = "subs"; // some fields on the getSkuDetails response bundle public static final String GET_SKU_DETAILS_ITEM_LIS T = "ITEM_ID_LIST"; public static final String GET_SKU_DETAILS_ITEM_TY PE_LIST = "ITEM_TYPE_LIST"; /** * Creates an instance. After creation, it will not yet be ready to use. You must perform * setup by calling {@link #startSetup} and wait for setup to complete. This constructor does not * block and is safe to call from a UI thread. * * @param ctx Your application or Activity context. Needed to bind to the in-app billing service. * @param base64PublicKey Your application's public key, encoded in base64. * This is used for verification of purchase signatures. You can find your app's base64-encoded * public key in your application's page on Google Play Developer Console. Note that this * is NOT your "developer public key". */ public IabHelper(Context ctx, String base64PublicKey) { mContext = ctx.getApplicationContext(); mSignatureBase64 = base64PublicKey; logDebug("IAB helper created."); } /** * Enables or disable debug logging through LogCat. */ public void enableDebugLogging(boolea n enable, String tag) { checkNotDisposed(); mDebugLog = enable; mDebugTag = tag; } public void enableDebugLogging(boolea n enable) { checkNotDisposed(); mDebugLog = enable; } /** * Callback for setup process. This listener's {@link #onIabSetupFinished} method is called * when the setup process is complete. */ public interface OnIabSetupFinishedListener { /** * Called to notify that setup is complete. * * @param result The result of the setup process. */ public void onIabSetupFinished(IabResul t result); } /** * Starts the setup process. This will start up the setup process asynchronously. * You will be notified through the listener when the setup process is complete. * This method is safe to call from a UI thread. * * @param listener The listener to notify when the setup process is complete. */ public void startSetup(final OnIabSetupFinishedListener listener) { // If already set up, can't do it again. checkNotDisposed(); if (mSetupDone) throw new IllegalStateException("IAB helper is already set up."); // Connection to IAB service logDebug("Starting inapp billing setup."); mServiceConn = new ServiceConnection() { @Override public void onServiceDisconnected(Com ponentName name) { logDebug("Billing service disconnected."); mService = null; } @Override public void onServiceConnected(Compo nentName name, IBinder service) { if (mDisposed) return; logDebug("Billing service connected."); mService = IInAppBillingService.Stub.asI nterface(service); String packageName = mContext.getPackageName() ; try { logDebug("Checking for inapp billing 3 support."); // check for inapp billing v3 support int response = mService.isBillingSupported( 3, packageName, ITEM_TYPE_INAPP); if (response != BILLING_RESPONSE_RESULT_ OK) { if (listener != null) listener.onIabSetupFinished( new IabResult(response, "Error checking for billing v3 support.")); // if in-app purchases aren't supported, neither are subscriptions. mSubscriptionsSupported = false; return; } logDebug("In-app billing version 3 supported for " + packageName); // check for v3 subscriptions support response = mService.isBillingSupported( 3, packageName, ITEM_TYPE_SUBS); if (response == BILLING_RESPONSE_RESULT_ OK) { logDebug("Subscriptions AVAILABLE."); mSubscriptionsSupported = true; } else { logDebug("Subscriptions NOT AVAILABLE. Response: " + response); } mSetupDone = true; } catch (RemoteException e) { if (listener != null) { listener.onIabSetupFinished( new IabResult(IABHELPER_REMO TE_EXCEPTION, "RemoteException while setting up in-app billing.")); } e.printStackTrace(); return; } if (listener != null) { listener.onIabSetupFinished( new IabResult(BILLING_RESPONS E_RESULT_OK, "Setup successful.")); } } }; Intent serviceIntent = new Intent("com.android.vending .billing.InAppBillingService.BI ND"); serviceIntent.setPackage("co m.android.vending"); if (!mContext.getPackageMana ger().queryIntentServices(ser viceIntent, 0).isEmpty()) { // service available to handle that Intent mContext.bindService(servic eIntent, mServiceConn, Context.BIND_AUTO_CREATE ); } else { // no service available to handle that Intent if (listener != null) { listener.onIabSetupFinished( new IabResult(BILLING_RESPONS E_RESULT_BILLING_UNAVAIL ABLE, "Billing service unavailable on device.")); } } } /** * Dispose of object, releasing resources. It's very important to call this * method when you are done with this object. It will release any resources * used by it such as service connections. Naturally, once the object is * disposed of, it can't be used again. */ public void dispose() { logDebug("Disposing."); mSetupDone = false; if (mServiceConn != null) { logDebug("Unbinding from service."); if (mContext != null) mContext.unbindService(mS erviceConn); } mDisposed = true; mContext = null; mServiceConn = null; mService = null; mPurchaseListener = null; } private void checkNotDisposed() { if (mDisposed) throw new IllegalStateException("IabHel per was disposed of, so it cannot be used."); } /** Returns whether subscriptions are supported. */ public boolean subscriptionsSupported() { checkNotDisposed(); return mSubscriptionsSupported; } /** * Callback that notifies when a purchase is finished. */ public interface OnIabPurchaseFinishedListen er { /** * Called to notify that an in-app purchase finished. If the purchase was successful, * then the sku parameter specifies which item was purchased. If the purchase failed, * the sku and extraData parameters may or may not be null, depending on how far the purchase * process went. * * @param result The result of the purchase. * @param info The purchase information (null if purchase failed) */ public void onIabPurchaseFinished(IabRe sult result, Purchase info); } // The listener registered on launchPurchaseFlow, which we have to call back when // the purchase finishes OnIabPurchaseFinishedListen er mPurchaseListener; public void launchPurchaseFlow(Activity act, String sku, int requestCode, OnIabPurchaseFinishedListen er listener) { launchPurchaseFlow(act, sku, requestCode, listener, ""); } public void launchPurchaseFlow(Activity act, String sku, int requestCode, OnIabPurchaseFinishedListen er listener, String extraData) { launchPurchaseFlow(act, sku, ITEM_TYPE_INAPP, requestCode, listener, extraData); } public void launchSubscriptionPurchaseF low(Activity act, String sku, int requestCode, OnIabPurchaseFinishedListen er listener) { launchSubscriptionPurchaseF low(act, sku, requestCode, listener, ""); } public void launchSubscriptionPurchaseF low(Activity act, String sku, int requestCode, OnIabPurchaseFinishedListen er listener, String extraData) { launchPurchaseFlow(act, sku, ITEM_TYPE_SUBS, requestCode, listener, extraData); } /** * Initiate the UI flow for an in-app purchase. Call this method to initiate an in-app purchase, * which will involve bringing up the Google Play screen. The calling activity will be paused while * the user interacts with Google Play, and the result will be delivered via the activity's * {@link android.app.Activity#onActiv ityResult} method, at which point you must call * this object's {@link #handleActivityResult} method to continue the purchase flow. This method * MUST be called from the UI thread of the Activity. * * @param act The calling activity. * @param sku The sku of the item to purchase. * @param itemType indicates if it's a product or a subscription (ITEM_TYPE_INAPP or ITEM_TYPE_SUBS) * @param requestCode A request code (to differentiate from other responses -* as in {@link android.app.Activity#startAct ivityForResult}). * @param listener The listener to notify when the purchase process finishes * @param extraData Extra data (developer payload), which will be returned with the purchase data * when the purchase completes. This extra data will be permanently bound to that purchase * and will always be returned when the purchase is queried. */ public void launchPurchaseFlow(Activity act, String sku, String itemType, int requestCode, OnIabPurchaseFinishedListen er listener, String extraData) { checkNotDisposed(); checkSetupDone("launchPur chaseFlow"); flagStartAsync("launchPurch aseFlow"); IabResult result; if (itemType.equals(ITEM_TYPE _SUBS) && !mSubscriptionsSupported) { IabResult r = new IabResult(IABHELPER_SUBSC RIPTIONS_NOT_AVAILABLE, "Subscriptions are not available."); flagEndAsync(); if (listener != null) listener.onIabPurchaseFinish ed(r, null); return; } try { logDebug("Constructing buy intent for " + sku + ", item type: " + itemType); Bundle buyIntentBundle = mService.getBuyIntent(3, mContext.getPackageName() , sku, itemType, extraData); int response = getResponseCodeFromBundl e(buyIntentBundle); if (response != BILLING_RESPONSE_RESULT_ OK) { logError("Unable to buy item, Error response: " + getResponseDesc(response)) ; flagEndAsync(); result = new IabResult(response, "Unable to buy item"); if (listener != null) listener.onIabPurchaseFinish ed(result, null); return; } PendingIntent pendingIntent = buyIntentBundle.getParcelab le(RESPONSE_BUY_INTENT); logDebug("Launching buy intent for " + sku + ". Request code: " + requestCode); mRequestCode = requestCode; mPurchaseListener = listener; mPurchasingItemType = itemType; act.startIntentSenderForResu lt(pendingIntent.getIntentSe nder(), requestCode, new Intent(), Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0)); } catch (SendIntentException e) { logError("SendIntentExceptio n while launching purchase flow for sku " + sku); e.printStackTrace(); flagEndAsync(); result = new IabResult(IABHELPER_SEND_I NTENT_FAILED, "Failed to send intent."); if (listener != null) listener.onIabPurchaseFinish ed(result, null); } catch (RemoteException e) { logError("RemoteException while launching purchase flow for sku " + sku); e.printStackTrace(); flagEndAsync(); result = new IabResult(IABHELPER_REMO TE_EXCEPTION, "Remote exception while starting purchase flow"); if (listener != null) listener.onIabPurchaseFinish ed(result, null); } } /** * Handles an activity result that's part of the purchase flow in in-app billing. If you * are calling {@link #launchPurchaseFlow}, then you must call this method from your * Activity's {@link android.app.Activity@onActi vityResult} method. This method * MUST be called from the UI thread of the Activity. * * @param requestCode The requestCode as you received it. * @param resultCode The resultCode as you received it. * @param data The data (Intent) as you received it. * @return Returns true if the result was related to a purchase flow and was handled; * false if the result was not related to a purchase, in which case you should * handle it normally. */ public boolean handleActivityResult(int requestCode, int resultCode, Intent data) { IabResult result; if (requestCode != mRequestCode) return false; checkNotDisposed(); checkSetupDone("handleActi vityResult"); // end of async purchase operation that started on launchPurchaseFlow flagEndAsync(); if (data == null) { logError("Null data in IAB activity result."); result = new IabResult(IABHELPER_BAD_R ESPONSE, "Null data in IAB result"); if (mPurchaseListener != null) mPurchaseListener.onIabPur chaseFinished(result, null); return true; } int responseCode = getResponseCodeFromIntent (data); String purchaseData = data.getStringExtra(RESPONS E_INAPP_PURCHASE_DATA); String dataSignature = data.getStringExtra(RESPONS E_INAPP_SIGNATURE); if (resultCode == Activity.RESULT_OK && responseCode == BILLING_RESPONSE_RESULT_ OK) { logDebug("Successful resultcode from purchase activity."); logDebug("Purchase data: " + purchaseData); logDebug("Data signature: " + dataSignature); logDebug("Extras: " + data.getExtras()); logDebug("Expected item type: " + mPurchasingItemType); if (purchaseData == null || dataSignature == null) { logError("BUG: either purchaseData or dataSignature is null."); logDebug("Extras: " + data.getExtras().toString()); result = new IabResult(IABHELPER_UNKN OWN_ERROR, "IAB returned null purchaseData or dataSignature"); if (mPurchaseListener != null) mPurchaseListener.onIabPur chaseFinished(result, null); return true; } Purchase purchase = null; try { purchase = new Purchase(mPurchasingItemT ype, purchaseData, dataSignature); String sku = purchase.getSku(); // Verify signature if (!Security.verifyPurchase(mSi gnatureBase64, purchaseData, dataSignature)) { logError("Purchase signature verification FAILED for sku " + sku); result = new IabResult(IABHELPER_VERIFI CATION_FAILED, "Signature verification failed for sku " + sku); if (mPurchaseListener != null) mPurchaseListener.onIabPur chaseFinished(result, purchase); return true; } logDebug("Purchase signature successfully verified."); } catch (JSONException e) { logError("Failed to parse purchase data."); e.printStackTrace(); result = new IabResult(IABHELPER_BAD_R ESPONSE, "Failed to parse purchase data."); if (mPurchaseListener != null) mPurchaseListener.onIabPur chaseFinished(result, null); return true; } if (mPurchaseListener != null) { mPurchaseListener.onIabPur chaseFinished(new IabResult(BILLING_RESPONS E_RESULT_OK, "Success"), purchase); } } else if (resultCode == Activity.RESULT_OK) { // result code was OK, but in-app billing response was not OK. logDebug("Result code was OK but in-app billing response was not OK: " + getResponseDesc(responseC ode)); if (mPurchaseListener != null) { result = new IabResult(responseCode, "Problem purchashing item."); mPurchaseListener.onIabPur chaseFinished(result, null); } } else if (resultCode == Activity.RESULT_CANCELED) { logDebug("Purchase canceled - Response: " + getResponseDesc(responseC ode)); result = new IabResult(IABHELPER_USER_ CANCELLED, "User canceled."); if (mPurchaseListener != null) mPurchaseListener.onIabPur chaseFinished(result, null); } else { logError("Purchase failed. Result code: " + Integer.toString(resultCode) + ". Response: " + getResponseDesc(responseC ode)); result = new IabResult(IABHELPER_UNKN OWN_PURCHASE_RESPONSE , "Unknown purchase response."); if (mPurchaseListener != null) mPurchaseListener.onIabPur chaseFinished(result, null); } return true; } public Inventory queryInventory(boolean querySkuDetails, List<String> moreSkus) throws IabException { return queryInventory(querySkuDet ails, moreSkus, null); } /** * Queries the inventory. This will query all owned items from the server, as well as * information on additional skus, if specified. This method may block or take long to execute. * Do not call from a UI thread. For that, use the non-blocking version {@link #refreshInventoryAsync}. * * @param querySkuDetails if true, SKU details (price, description, etc) will be queried as well * as purchase information. * @param moreItemSkus additional PRODUCT skus to query information on, regardless of ownership. * Ignored if null or if querySkuDetails is false. * @param moreSubsSkus additional SUBSCRIPTIONS skus to query information on, regardless of ownership. * Ignored if null or if querySkuDetails is false. * @throws IabException if a problem occurs while refreshing the inventory. */ public Inventory queryInventory(boolean querySkuDetails, List<String> moreItemSkus, List<String> moreSubsSkus) throws IabException { checkNotDisposed(); checkSetupDone("queryInve ntory"); try { Inventory inv = new Inventory(); int r = queryPurchases(inv, ITEM_TYPE_INAPP); if (r != BILLING_RESPONSE_RESULT_ OK) { throw new IabException(r, "Error refreshing inventory (querying owned items)."); } if (querySkuDetails) { r= querySkuDetails(ITEM_TYPE_ INAPP, inv, moreItemSkus); if (r != BILLING_RESPONSE_RESULT_ OK) { throw new IabException(r, "Error refreshing inventory (querying prices of items)."); } } // if subscriptions are supported, then also query for subscriptions if (mSubscriptionsSupported) { r= queryPurchases(inv, ITEM_TYPE_SUBS); if (r != BILLING_RESPONSE_RESULT_ OK) { throw new IabException(r, "Error refreshing inventory (querying owned subscriptions)."); } if (querySkuDetails) { r= querySkuDetails(ITEM_TYPE_ SUBS, inv, moreItemSkus); if (r != BILLING_RESPONSE_RESULT_ OK) { throw new IabException(r, "Error refreshing inventory (querying prices of subscriptions)."); } } } return inv; } catch (RemoteException e) { throw new IabException(IABHELPER_RE MOTE_EXCEPTION, "Remote exception while refreshing inventory.", e); } catch (JSONException e) { throw new IabException(IABHELPER_BA D_RESPONSE, "Error parsing JSON response while refreshing inventory.", e); } } /** * Listener that notifies when an inventory query operation completes. */ public interface QueryInventoryFinishedListe ner { /** * Called to notify that an inventory query operation completed. * * @param result The result of the operation. * @param inv The inventory. */ public void onQueryInventoryFinished(Ia bResult result, Inventory inv); } /** * Asynchronous wrapper for inventory query. This will perform an inventory * query as described in {@link #queryInventory}, but will do so asynchronously * and call back the specified listener upon completion. This method is safe to * call from a UI thread. * * @param querySkuDetails as in {@link #queryInventory} * @param moreSkus as in {@link #queryInventory} * @param listener The listener to notify when the refresh operation completes. */ public void queryInventoryAsync(final boolean querySkuDetails, final List<String> moreSkus, final QueryInventoryFinishedListe ner listener) { final Handler handler = new Handler(); checkNotDisposed(); checkSetupDone("queryInve ntory"); flagStartAsync("refresh inventory"); (new Thread(new Runnable() { public void run() { IabResult result = new IabResult(BILLING_RESPONS E_RESULT_OK, "Inventory refresh successful."); Inventory inv = null; try { inv = queryInventory(querySkuDet ails, moreSkus); } catch (IabException ex) { result = ex.getResult(); } flagEndAsync(); final IabResult result_f = result; final Inventory inv_f = inv; if (!mDisposed && listener != null) { handler.post(new Runnable() { public void run() { listener.onQueryInventoryFin ished(result_f, inv_f); } }); } } })).start(); } public void queryInventoryAsync(QueryI nventoryFinishedListener listener) { queryInventoryAsync(true, null, listener); } public void queryInventoryAsync(boolea n querySkuDetails, QueryInventoryFinishedListe ner listener) { queryInventoryAsync(queryS kuDetails, null, listener); } /** * Consumes a given in-app product. Consuming can only be done on an item * that's owned, and as a result of consumption, the user will no longer own it. * This method may block or take long to return. Do not call from the UI thread. * For that, see {@link #consumeAsync}. * * @param itemInfo The PurchaseInfo that represents the item to consume. * @throws IabException if there is a problem during consumption. */ void consume(Purchase itemInfo) throws IabException { checkNotDisposed(); checkSetupDone("consume") ; if (!itemInfo.mItemType.equals (ITEM_TYPE_INAPP)) { throw new IabException(IABHELPER_INV ALID_CONSUMPTION, "Items of type '" + itemInfo.mItemType + "' can't be consumed."); } try { String token = itemInfo.getToken(); String sku = itemInfo.getSku(); if (token == null || token.equals("")) { logError("Can't consume "+ sku + ". No token."); throw new IabException(IABHELPER_MI SSING_TOKEN, "PurchaseInfo is missing token for sku: " + sku + " " + itemInfo); } logDebug("Consuming sku: " + sku + ", token: " + token); int response = mService.consumePurchase( 3, mContext.getPackageName() , token); if (response == BILLING_RESPONSE_RESULT_ OK) { logDebug("Successfully consumed sku: " + sku); } else { logDebug("Error consuming consuming sku " + sku + ". " + getResponseDesc(response)) ; throw new IabException(response, "Error consuming sku " + sku); } } catch (RemoteException e) { throw new IabException(IABHELPER_RE MOTE_EXCEPTION, "Remote exception while consuming. PurchaseInfo: " + itemInfo, e); } } /** * Callback that notifies when a consumption operation finishes. */ public interface OnConsumeFinishedListener { /** * Called to notify that a consumption has finished. * * @param purchase The purchase that was (or was to be) consumed. * @param result The result of the consumption operation. */ public void onConsumeFinished(Purchas e purchase, IabResult result); } /** * Callback that notifies when a multi-item consumption operation finishes. */ public interface OnConsumeMultiFinishedList ener { /** * Called to notify that a consumption of multiple items has finished. * * @param purchases The purchases that were (or were to be) consumed. * @param results The results of each consumption operation, corresponding to each * sku. */ public void onConsumeMultiFinished(Lis t<Purchase> purchases, List<IabResult> results); } /** * Asynchronous wrapper to item consumption. Works like {@link #consume}, but * performs the consumption in the background and notifies completion through * the provided listener. This method is safe to call from a UI thread. * * @param purchase The purchase to be consumed. * @param listener The listener to notify when the consumption operation finishes. */ public void consumeAsync(Purchase purchase, OnConsumeFinishedListener listener) { checkNotDisposed(); checkSetupDone("consume") ; List<Purchase> purchases = new ArrayList<Purchase>(); purchases.add(purchase); consumeAsyncInternal(purch ases, listener, null); } /** * Same as {@link consumeAsync}, but for multiple items at once. * @param purchases The list of PurchaseInfo objects representing the purchases to consume. * @param listener The listener to notify when the consumption operation finishes. */ public void consumeAsync(List<Purchase > purchases, OnConsumeMultiFinishedList ener listener) { checkNotDisposed(); checkSetupDone("consume") ; consumeAsyncInternal(purch ases, null, listener); } /** * Returns a humanreadable description for the given response code. * * @param code The response code * @return A humanreadable string explaining the result code. * It also includes the result code numerically. */ public static String getResponseDesc(int code) { String[] iab_msgs = ("0:OK/1:User Canceled/2:Unknown/" + "3:Billing Unavailable/4:Item unavailable/" + "5:Developer Error/6:Error/7:Item Already Owned/" + "8:Item not owned").split("/"); String[] iabhelper_msgs = ("0:OK/-1001:Remote exception during initialization/" + "1002:Bad response received/" + "1003:Purchase signature verification failed/" + "1004:Send intent failed/" + "1005:User cancelled/" + "1006:Unknown purchase response/" + "1007:Missing token/" + "1008:Unknown error/" + "1009:Subscriptions not available/" + "1010:Invalid consumption attempt").split("/"); if (code <= IABHELPER_ERROR_BASE) { int index = IABHELPER_ERROR_BASE code; if (index >= 0 && index < iabhelper_msgs.length) return iabhelper_msgs[index]; else return String.valueOf(code) + ":Unknown IAB Helper Error"; } else if (code < 0 || code >= iab_msgs.length) return String.valueOf(code) + ":Unknown"; else return iab_msgs[code]; } // Checks that setup was done; if not, throws an exception. void checkSetupDone(String operation) { if (!mSetupDone) { logError("Illegal state for operation (" + operation + "): IAB helper is not set up."); throw new IllegalStateException("IAB helper is not set up. Can't perform operation: " + operation); } } // Workaround to bug where sometimes response codes come as Long instead of Integer int getResponseCodeFromBundl e(Bundle b) { Object o = b.get(RESPONSE_CODE); if (o == null) { logDebug("Bundle with null response code, assuming OK (known issue)"); return BILLING_RESPONSE_RESULT_ OK; } else if (o instanceof Integer) return ((Integer)o).intValue(); else if (o instanceof Long) return (int)((Long)o).longValue(); else { logError("Unexpected type for bundle response code."); logError(o.getClass().getNam e()); throw new RuntimeException("Unexpec ted type for bundle response code: " + o.getClass().getName()); } } // Workaround to bug where sometimes response codes come as Long instead of Integer int getResponseCodeFromIntent (Intent i) { Object o = i.getExtras().get(RESPONSE_ CODE); if (o == null) { logError("Intent with no response code, assuming OK (known issue)"); return BILLING_RESPONSE_RESULT_ OK; } else if (o instanceof Integer) return ((Integer)o).intValue(); else if (o instanceof Long) return (int)((Long)o).longValue(); else { logError("Unexpected type for intent response code."); logError(o.getClass().getNam e()); throw new RuntimeException("Unexpec ted type for intent response code: " + o.getClass().getName()); } } void flagStartAsync(String operation) { if (mAsyncInProgress) throw new IllegalStateException("Can't start async operation (" + operation + ") because another async operation(" + mAsyncOperation + ") is in progress."); mAsyncOperation = operation; mAsyncInProgress = true; logDebug("Starting async operation: " + operation); } void flagEndAsync() { logDebug("Ending async operation: " + mAsyncOperation); mAsyncOperation = ""; mAsyncInProgress = false; } int queryPurchases(Inventory inv, String itemType) throws JSONException, RemoteException { // Query purchases logDebug("Querying owned items, item type: " + itemType); logDebug("Package name: " + mContext.getPackageName() ); boolean verificationFailed = false; String continueToken = null; do { logDebug("Calling getPurchases with continuation token: " + continueToken); Bundle ownedItems = mService.getPurchases(3, mContext.getPackageName() , itemType, continueToken); int response = getResponseCodeFromBundl e(ownedItems); logDebug("Owned items response: " + String.valueOf(response)); if (response != BILLING_RESPONSE_RESULT_ OK) { logDebug("getPurchases() failed: " + getResponseDesc(response)) ; return response; } if (!ownedItems.containsKey(R ESPONSE_INAPP_ITEM_LIST) || !ownedItems.containsKey(RE SPONSE_INAPP_PURCHASE_ DATA_LIST) || !ownedItems.containsKey(RE SPONSE_INAPP_SIGNATURE_ LIST)) { logError("Bundle returned from getPurchases() doesn't contain required fields."); return IABHELPER_BAD_RESPONSE; } String sku = ownedSkus.get(i); if (Security.verifyPurchase(mSi gnatureBase64, purchaseData, signature)) { logDebug("Sku is owned: " + sku); Purchase purchase = new Purchase(itemType, purchaseData, signature); ArrayList<String> ownedSkus = ownedItems.getStringArrayLi st( logDebug("Purchase data: " + purchaseData); } RESPONSE_INAPP_ITEM_LIST ); ArrayList<String> purchaseDataList = ownedItems.getStringArrayLi st( RESPONSE_INAPP_PURCHAS E_DATA_LIST); ArrayList<String> signatureList = ownedItems.getStringArrayLi st( RESPONSE_INAPP_SIGNATU RE_LIST); for (int i = 0; i < purchaseDataList.size(); ++i) { String purchaseData = purchaseDataList.get(i); String signature = signatureList.get(i); if (TextUtils.isEmpty(purchase. getToken())) { logWarn("BUG: empty/null token!"); // Record ownership and token inv.addPurchase(purchase); } else { logWarn("Purchase signature verification **FAILED**. Not adding item."); logDebug(" Purchase data: " + purchaseData); logDebug(" Signature: " + signature); verificationFailed = true; } } continueToken = ownedItems.getString(INAPP _CONTINUATION_TOKEN); logDebug("Continuation token: " + continueToken); } while (!TextUtils.isEmpty(continue Token)); return verificationFailed ? IABHELPER_VERIFICATION_F AILED : BILLING_RESPONSE_RESULT_ OK; } int querySkuDetails(String itemType, Inventory inv, List<String> moreSkus) throws RemoteException, JSONException { logDebug("Querying SKU details."); ArrayList<String> skuList = new ArrayList<String>(); skuList.addAll(inv.getAllOwn edSkus(itemType)); if (moreSkus != null) { for (String sku : moreSkus) { if (!skuList.contains(sku)) { skuList.add(sku); } } } if (skuList.size() == 0) { logDebug("queryPrices: nothing to do because there are no SKUs."); return BILLING_RESPONSE_RESULT_ OK; } Bundle querySkus = new Bundle(); querySkus.putStringArrayList (GET_SKU_DETAILS_ITEM_LI ST, skuList); Bundle skuDetails = mService.getSkuDetails(3, mContext.getPackageName() , itemType, querySkus); if (!skuDetails.containsKey(RES PONSE_GET_SKU_DETAILS_LI ST)) { int response = getResponseCodeFromBundl e(skuDetails); if (response != BILLING_RESPONSE_RESULT_ OK) { logDebug("getSkuDetails() failed: " + getResponseDesc(response)) ; return response; } else { logError("getSkuDetails() returned a bundle with neither an error nor a detail list."); return IABHELPER_BAD_RESPONSE; } } ArrayList<String> responseList = skuDetails.getStringArrayList( RESPONSE_GET_SKU_DETAIL S_LIST); for (String thisResponse : responseList) { SkuDetails d = new SkuDetails(itemType, thisResponse); logDebug("Got sku details: " + d); inv.addSkuDetails(d); } return BILLING_RESPONSE_RESULT_ OK; } void consumeAsyncInternal(final List<Purchase> purchases, final OnConsumeFinishedListener singleListener, final OnConsumeMultiFinishedList ener multiListener) { final Handler handler = new Handler(); flagStartAsync("consume"); (new Thread(new Runnable() { public void run() { final List<IabResult> results = new ArrayList<IabResult>(); for (Purchase purchase : purchases) { try { consume(purchase); results.add(new IabResult(BILLING_RESPONS E_RESULT_OK, "Successful consume of sku " + purchase.getSku())); } catch (IabException ex) { results.add(ex.getResult()); } } flagEndAsync(); if (!mDisposed && singleListener != null) { handler.post(new Runnable() { public void run() { singleListener.onConsumeFin ished(purchases.get(0), results.get(0)); } }); } if (!mDisposed && multiListener != null) { handler.post(new Runnable() { public void run() { multiListener.onConsumeMu ltiFinished(purchases, results); } }); } } })).start(); } void logDebug(String msg) Log.w(mDebugTag, "Inapp billing warning: " + msg); } } IabResult.java /* Copyright (c) 2012 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licen ses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ { if (mDebugLog) Log.d(mDebugTag, msg); } void logError(String msg) { Log.e(mDebugTag, "Inapp billing error: " + msg); } void logWarn(String msg) { package com.secrethq.store.util; /** * Represents the result of an in-app billing operation. * A result is composed of a response code (an integer) and possibly a * message (String). You can get those by calling * {@link #getResponse} and {@link #getMessage()}, respectively. You * can also inquire whether a result is a success or a failure by * calling {@link #isSuccess()} and {@link #isFailure()}. */ public class IabResult { int mResponse; String mMessage; public IabResult(int response, String message) { mResponse = response; if (message == null || message.trim().length() == 0) { mMessage = IabHelper.getResponseDesc( response); } else { mMessage = message + " (response: " + IabHelper.getResponseDesc( response) + ")"; } } public int getResponse() { return mResponse; } public String getMessage() { return mMessage; } public boolean isSuccess() { return mResponse == IabHelper.BILLING_RESPONS E_RESULT_OK; } public boolean isFailure() { return !isSuccess(); } public String toString() { return "IabResult: " + getMessage(); } } Inventory.java /* Copyright (c) 2012 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licen ses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.secrethq.store.util; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Represents a block of information about in-app items. * An Inventory is returned by such methods as {@link IabHelper#queryInventory}. */ public class Inventory { Map<String,SkuDetails> mSkuMap = new HashMap<String,SkuDetails> (); Map<String,Purchase> mPurchaseMap = new HashMap<String,Purchase>() ; Inventory() { } /** Returns the listing details for an in-app product. */ public SkuDetails getSkuDetails(String sku) { return mSkuMap.get(sku); } /** Returns purchase information for a given product, or null if there is no purchase. */ public Purchase getPurchase(String sku) { return mPurchaseMap.get(sku); } /** Returns whether or not there exists a purchase of the given product. */ public boolean hasPurchase(String sku) { return mPurchaseMap.containsKey( sku); } /** Return whether or not details about the given product are available. */ public boolean hasDetails(String sku) { return mSkuMap.containsKey(sku); } /** * Erase a purchase (locally) from the inventory, given its product ID. This just * modifies the Inventory object locally and has no effect on the server! This is * useful when you have an existing Inventory object which you know to be up to date, * and you have just consumed an item successfully, which means that erasing its * purchase data from the Inventory you already have is quicker than querying for * a new Inventory. */ public void erasePurchase(String sku) { if (mPurchaseMap.containsKey (sku)) mPurchaseMap.remove(sku); } /** Returns a list of all owned product IDs. */ List<String> getAllOwnedSkus() { return new ArrayList<String>(mPurchase Map.keySet()); } /** Returns a list of all owned product IDs of a given type */ List<String> getAllOwnedSkus(String itemType) { List<String> result = new ArrayList<String>(); for (Purchase p : mPurchaseMap.values()) { if (p.getItemType().equals(item Type)) result.add(p.getSku()); } return result; } /** Returns a list of all purchases. */ public List<Purchase> getAllPurchases() { return new ArrayList<Purchase>(mPurch aseMap.values()); } void addSkuDetails(SkuDetails d) { mSkuMap.put(d.getSku(), d); } void addPurchase(Purchase p) { mPurchaseMap.put(p.getSku (), p); } } Purchase.java * Copyright (c) 2012 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licen ses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.secrethq.store.util; import org.json.JSONException; import org.json.JSONObject; /** * Represents an in-app billing purchase. */ public class Purchase { String mItemType; // ITEM_TYPE_INAPP or ITEM_TYPE_SUBS String mOrderId; String mPackageName; String mSku; long mPurchaseTime; int mPurchaseState; String mDeveloperPayload; String mToken; String mOriginalJson; String mSignature; public Purchase(String itemType, String jsonPurchaseInfo, String signature) throws JSONException { mItemType = itemType; mOriginalJson = jsonPurchaseInfo; JSONObject o = new JSONObject(mOriginalJson); mOrderId = o.optString("orderId"); mPackageName = o.optString("packageName"); mSku = o.optString("productId"); mPurchaseTime = o.optLong("purchaseTime"); mPurchaseState = o.optInt("purchaseState"); mDeveloperPayload = o.optString("developerPaylo ad"); mToken = o.optString("token", o.optString("purchaseToken" )); mSignature = signature; } public String getItemType() { return mItemType; } public String getOrderId() { return mOrderId; } public String getPackageName() { return mPackageName; } public String getSku() { return mSku; } public long getPurchaseTime() { return mPurchaseTime; } public int getPurchaseState() { return mPurchaseState; } public String getDeveloperPayload() { return mDeveloperPayload; } public String getToken() { return mToken; } public String getOriginalJson() { return mOriginalJson; } public String getSignature() { return mSignature; } @Override public String toString() { return "PurchaseInfo(type:" + mItemType + "):" + mOriginalJson; } } Security.java /* Copyright (c) 2012 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licen ses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.secrethq.store.util; import android.text.TextUtils; import android.util.Log; import org.json.JSONException; import org.json.JSONObject; import java.security.InvalidKeyExcep tion; import java.security.KeyFactory; import java.security.NoSuchAlgorith mException; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureExcept ion; import java.security.spec.InvalidKey SpecException; import java.security.spec.X509Encod edKeySpec; /** * Security-related methods. For a secure implementation, all of this code * should be implemented on a server that communicates with the * application on the device. For the sake of simplicity and clarity of this * example, this code is included here and is executed on the device. If you * must verify the purchases on the phone, you should obfuscate this code to * make it harder for an attacker to replace the code with stubs that treat all * purchases as verified. */ public class Security { private static final String TAG = "IABUtil/Security"; private static final String KEY_FACTORY_ALGORITHM = "RSA"; private static final String SIGNATURE_ALGORITHM = "SHA1withRSA"; /** * Verifies that the data was signed with the given signature, and returns * the verified purchase. The data is in JSON format and signed * with a private key. The data also contains the {@link PurchaseState} * and product ID of the purchase. * @param base64PublicKey the base64encoded public key to use for verifying. * @param signedData the signed JSON string (signed, not encrypted) * @param signature the signature for the data, signed with the private key */ public static boolean verifyPurchase(String base64PublicKey, String signedData, String signature) { if (TextUtils.isEmpty(signedDat a) || TextUtils.isEmpty(base64Pub licKey) || TextUtils.isEmpty(signature)) { Log.e(TAG, "Purchase verification failed: missing data."); return false; } PublicKey key = Security.generatePublicKey(b ase64PublicKey); return Security.verify(key, signedData, signature); } /** * Generates a PublicKey instance from a string containing the * Base64-encoded public key. * * @param encodedPublicKey Base64encoded public key * @throws IllegalArgumentException if encodedPublicKey is invalid */ public static PublicKey generatePublicKey(String encodedPublicKey) { try { byte[] decodedKey = Base64.decode(encodedPubl icKey); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ FACTORY_ALGORITHM); return keyFactory.generatePublic(n ew X509EncodedKeySpec(decod edKey)); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } catch (InvalidKeySpecException e) { Log.e(TAG, "Invalid key specification."); throw new IllegalArgumentException(e); } catch (Base64DecoderException e) { Log.e(TAG, "Base64 decoding failed."); throw new IllegalArgumentException(e); } } /** * Verifies that the signature from the server matches the computed * signature on the data. Returns true if the data is correctly signed. * * @param publicKey public key associated with the developer account * @param signedData signed data from server * @param signature server signature * @return true if the data and signature match */ public static boolean verify(PublicKey publicKey, String signedData, String signature) { Signature sig; try { sig = Signature.getInstance(SIGNA TURE_ALGORITHM); sig.initVerify(publicKey); sig.update(signedData.getByt es()); if (!sig.verify(Base64.decode(si gnature))) { Log.e(TAG, "Signature verification failed."); return false; } return true; } catch (NoSuchAlgorithmException e) { Log.e(TAG, "NoSuchAlgorithmException. "); } catch (InvalidKeyException e) { Log.e(TAG, "Invalid key specification."); } catch (SignatureException e) { Log.e(TAG, "Signature exception."); } catch (Base64DecoderException e) { Log.e(TAG, "Base64 decoding failed."); } return false; } } SkuDetails.java /* Copyright (c) 2012 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licen ses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.secrethq.store.util; import org.json.JSONException; import org.json.JSONObject; /** * Represents an in-app product's listing details. */ public class SkuDetails { String mItemType; String mSku; String mType; String mPrice; String mTitle; String mDescription; String mJson; public SkuDetails(String jsonSkuDetails) throws JSONException { this(IabHelper.ITEM_TYPE_IN APP, jsonSkuDetails); } public SkuDetails(String itemType, String jsonSkuDetails) throws JSONException { mItemType = itemType; mJson = jsonSkuDetails; JSONObject o = new JSONObject(mJson); mSku = o.optString("productId"); mType = o.optString("type"); mPrice = o.optString("price"); mTitle = o.optString("title"); mDescription = o.optString("description"); } public String getSku() { return mSku; } public String getType() { return mType; } public String getPrice() { return mPrice; } public String getTitle() { return mTitle; } public String getDescription() { return mDescription; } @Override public String toString() { return "SkuDetails:" + mJson; } } PTStoreBridge.java package com.secrethq.store; import java.lang.ref.WeakReference; import java.util.List; import org.cocos2dx.lib.Cocos2dxAc tivity; import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.DialogInterf ace; import android.util.Log; import com.secrethq.store.util.*; import com.secrethq.utils.PTService sBridge; public class PTStoreBridge { private static boolean readyToPurchase = false; private static IabHelper mHelper; private static Cocos2dxActivity activity; private static WeakReference<Cocos2dxAc tivity> s_activity; private static Inventory inventory; private static final String TAG = "PTStoreBridge"; private static native String licenseKey(); public static native void purchaseDidComplete( String productId ); public static native void purchaseDidCompleteRestori ng(String productId); public static native boolean isProductConsumible( String productId ); static public void initBridge(Cocos2dxActivity _activity){ activity = _activity; s_activity = new WeakReference<Cocos2dxAc tivity>(activity); mHelper = new IabHelper(activity, licenseKey()); readyToPurchase = true; } } }); } catch (Exception e) { Log.v(TAG, "IabHelper.startSetup : FAILED : " + e.getMessage()); } } s_activity.get().runO nUiThread( new Runnable() { public void run() { IabHelper.OnIabPurc haseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFini shedListener() { public void onIabPurchaseFinished(IabRe sult result, Purchase purchase) { if (result.isFailure()) { Log.d(TAG, "Error purchasing: " + result); public static IabHelper iabHelper() { return mHelper; } if(result.getResponse() == IabHelper.BILLING_RESPONS E_RESULT_ITEM_ALREADY_O WNED){ try { mHelper.startSetup( new IabHelper.OnIabSetupFinishe dListener() { public static void setInventory( Inventory _inventory){ inventory = _inventory; } public void onIabSetupFinished(IabResul t result) { if (!result.isSuccess()) { Log.d(TAG, "Problem setting up In-app Billing: " + result); readyToPurchase = false; static public void purchase( final String storeId ){ if ( !readyToPurchase ) { Log.e(TAG, "In-app Billing not Ready"); return; } } else { if(!isProductConsumible( storeId )){ Log.v(TAG, "Product alreasdy ownded - restored:" + storeId); purchaseDidComplete( storeId ); } else{ Log.v(TAG, "Product alreasdy ownded consuming:" + storeId); consumeStoreId( storeId ); } } return; } if( isProductConsumible( purchase.getSku() ) ){ Log.v(TAG, "Consuming product: " + purchase.getSku()); consumePurchase( purchase ); } else{ Log.v(TAG, "Purchase did completed:" + purchase.getSku()); purchaseDidComplete( purchase.getSku() ); } Log.e(TAG, "Consuming by StoreID " + storeId); "Inventory: " + purchase.getSku()); inventory // request if(storeId.equals( purchase.getSku() )){ s_activity.get().runO nUiThread( new Runnable() { public void run() { consumePurchase( purchase ); } IabHelper.QueryInve ntoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFin ishedListener() { public void onQueryInventoryFinished(Ia bResult result, } }; Inventory inventory) { try { (result.isFailure()) { if mHelper.launchPurc haseFlow(activity, storeId, 10001, mPurchaseFinishedListener, null); } catch (Exception e) { Log.v(TAG, "launchPurchaseFlow : FAILED : " + e.getMessage()); } } }); } static void consumeStoreId(final String storeId){ Log.v(TAG, "INVENTORY FAILURE: " + result); } else { setInventory( inventory ); List<Purchase> purchases = inventory.getAllPurchases(); for (Purchase purchase : purchases){ Log.v(TAG, } } } }; try { mHelper.queryInvent oryAsync(mGotInventoryList ener); } catch (Exception e) { Log.v(TAG, "queryInventoryAsync : FAILED : " + e.getMessage()); } } }); } static public void restorePurchases(){ if ( !readyToPurchase ) { Log.e(TAG, "In-app Billing not Ready"); return; } s_activity.get().runO nUiThread( new Runnable() { public void run() { final ProgressDialog progress; progress = ProgressDialog.show(activity, null, "Restoring purchases...", true); IabHelper.QueryInve ntoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFin ishedListener() { "Inventory: " + purchase.getSku()); Log.v(TAG, "queryInventoryAsync : FAILED : " + e.getMessage()); } } }); } if( ! isProductConsumible( purchase.getSku() )){ purchaseDidComplet eRestoring( purchase.getSku() ); if ( !readyToPurchase ) { } } } public void onQueryInventoryFinished(Ia bResult result, progress.dismiss(); Inventory inventory) { (result.isFailure()) { AlertDialog.Builder dlgAlert = new AlertDialog.Builder( activity ); Log.v(TAG, "INVENTORY FAILURE: " + result); dlgAlert.setMessage( "Restore purchases complete"); if static public void consumePurchase( final Purchase purchase ){ Log.e(TAG, "In-app Billing not Ready"); return; } } else { dlgAlert.setPositiveB utton("OK", null); setInventory( inventory ); w(); dlgAlert.create().sho s_activity.get().runO nUiThread( new Runnable() { public void run() { Log.v(TAG, "Start Consuming"); final ProgressDialog progress; progress = ProgressDialog.show(activity, null, "Finalizing Purchase ...", true); } }; List<Purchase> purchases = inventory.getAllPurchases(); for (Purchase purchase : purchases){ Log.v(TAG, try { mHelper.queryInvent oryAsync(mGotInventoryList ener); } catch (Exception e) { IabHelper.OnConsum eFinishedListener mConsumeFinishedListener = new IabHelper.OnConsumeFinish edListener() { "consumeAsync : FAILED : " + e.getMessage()); public void onConsumeFinished(Purchas e purchase, IabResult result) { } } } if (result.isSuccess()) { }); } } PTServicesBridge.java package com.secrethq.utils; purchaseDidComplete( purchase.getSku() ); } else { Log.v(TAG, "Error consume: " + result); } progress.dismiss(); } }; if(purchase != null){ try { mHelper.consumeAs ync(purchase, mConsumeFinishedListener); } catch (Exception e) { Log.v(TAG, import java.lang.ref.WeakReference; import java.io.File; import java.io.FileFilter; import java.io.UnsupportedEncoding Exception; import java.security.MessageDigest; import java.security.NoSuchAlgorith mException; import java.util.regex.Pattern; import java.nio.IntBuffer; import org.cocos2dx.lib.Cocos2dxAc tivity; import com.google.android.gms.R; import com.google.android.gms.ads. AdRequest; import com.google.android.gms.co mmon.ConnectionResult; import com.google.android.gms.co mmon.GooglePlayServicesUti l; import com.google.android.gms.co mmon.api.GoogleApiClient; import com.google.android.gms.ga mes.Games; import com.google.android.gms.ga mes.Player; import com.google.android.gms.plus .Plus; import android.app.AlertDialog; import android.os.StrictMode; import android.content.*; import android.content.IntentSende r.SendIntentException; import android.net.Uri; import android.opengl.GLSurfaceVie w; import android.os.Bundle; import android.util.Log; import android.view.View; import android.graphics.Bitmap; import android.os.Environment; import java.io.FileOutputStream; import android.net.Uri; import javax.microedition.khronos.e gl.EGLContext; import javax.microedition.khronos.e gl.EGL10; import javax.microedition.khronos.o pengles.GL10; import android.app.UiModeManage r; import android.content.res.Configur ation; import android.view.ViewGroup; import android.widget.FrameLayout ; public class PTServicesBridge implements GoogleApiClient.Connection Callbacks, GoogleApiClient.OnConnecti onFailedListener{ private static PTServicesBridge sInstance; private static final String TAG = "PTServicesBridge"; private static native String getLeaderboardId(); private static native void warningMessageClicked(bool ean accepted); public static native boolean removeAds(); private static Cocos2dxActivity activity; private static WeakReference<Cocos2dxAc tivity> s_activity; private static final int REQUEST_LEADERBOARD = 5000; public static PTServicesBridge instance() { if (sInstance == null) sInstance = new PTServicesBridge(); return sInstance; } public static void initBridge(Cocos2dxActivity activity, String appId){ Log.v(TAG, "PTServicesBridge -- INIT"); PTServicesBridge.s_a ctivity = new WeakReference<Cocos2dxAc tivity>(activity); PTServicesBridge.acti vity = activity; if(appId == null || appId.length() == 0 || appId.matches("[0-9]+") == false){ return; } private static GoogleApiClient mGoogleApiClient; private static String urlString; private static int scoreValue; public static final int RC_SIGN_IN = 9001; SharedPreferences sharedPref = activity.getPreferences(Cont ext.MODE_PRIVATE); if(sharedPref.getBool ean("GooglePlayServiceSignI nError", false) == true){ Log.v(TAG, "Skipping logging in Google Play services"); return; } // Create a GoogleApiClient instance PTServicesBridge.mG oogleApiClient = new GoogleApiClient.Builder(PTSe rvicesBridge.activity) .addApi(Plus.API).ad dScope(Plus.SCOPE_PLUS_LO GIN) .addApi(Games.API). addScope(Games.SCOPE_GA MES) .addConnectionCallb acks(instance()) .addOnConnectionFa iledListener(instance()) .build(); } public static void openShareWidget( final String message ){ View content = activity.findViewById(androi d.R.id.content); GLSurfaceView glView = null; if(content instanceof ViewGroup){ // Diving one more level deeper to find a proper FrameLayout ViewGroup viewGroup = (ViewGroup)((ViewGroup)co ntent).getChildAt(0); for (int i = 0; i < viewGroup.getChildCount(); i++) { StrictMode.VmPolicy.Builder( ); Bitmap screenshot = createBitmapFromGLSurface (0, 0, width, height, gl); try { File View child = viewGroup.getChildAt(i); if(child instanceof GLSurfaceView){ glView = (GLSurfaceView)child; StrictMode.setVmPolicy(buil der.build()); outputDir = activity.getExternalCacheDir( ); final File file = File.createTempFile("screens hot", ".png", outputDir); // now finally we have screenshot so we need to call Intent and submit message and screenshot together Log.v(TAG, "PTServicesBridge -openShareWidget with text:" + message); break; } } } final int width = glView.getWidth(); final int height = glView.getHeight(); if(glView != null) { //We have to grab GL buffer right after we done rendering FileOutputStream stream = new FileOutputStream(file); screenshot.compress (Bitmap.CompressFormat.PN G, 85, stream); sharingIntent.setTyp e("image/*"); stream.flush(); stream.close(); glView.queueEvent(n ew Runnable() { @Override Intent sharingIntent = new Intent(android.content.Inten t.ACTION_SEND); sharingIntent.putExtr a(android.content.Intent.EXT RA_TEXT, message); activity.runOnUiThre ad(new Runnable() { public void run() { EGL10 egl = (EGL10)EGLContext.getEGL(); @Override GL10 gl = (GL10)egl.eglGetCurrentCont ext().getGL(); public void run() { StrictMode.VmPolicy.Builder builder = new sharingIntent.putExtr a(Intent.EXTRA_STREAM, Uri.fromFile(file)); activity.startActivity(I ntent.createChooser(sharingI ntent, "Share" )); } w, h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, intBuffer); int offset1, offset2; for (int i = 0; i < h; i++) { }); offset1 = i * w; } offset2 = (h - i - 1) * w; catch (Exception e) { for (int j = 0; j < w; j++) { Log.d(TAG, "Screenshot writing Error"); int texturePixel = bitmapBuffer[offset1 + j]; } int blue = (texturePixel >> 16) & 0xff; } }); } } int red = (texturePixel << 16) & 0x00ff0000; private static Bitmap createBitmapFromGLSurface (int x, int y, int w, int h, GL10 gl) { int pixel = (texturePixel & 0xff00ff00) | red | blue; int bitmapBuffer[] = new int[w * h]; int bitmapSource[] = new int[w * h]; IntBuffer intBuffer = IntBuffer.wrap(bitmapBuffer) ; bitmapSource[offset 2 + j] = pixel; } } } catch gl.glReadPixels(x, y, public static int availableProcessors() { int processorsNum = Runtime.getRuntime().availa bleProcessors(); Log.d(TAG, "availableProcessors: " + processorsNum); return processorsNum; } public static int getCoresNumber() { class CpuFilter implements FileFilter { @Override public boolean accept(File pathname) { //Check if filename is "cpu", followed by a single digit number if(Pattern.matches("cpu[09]+", pathname.getName())) { return true; } (Exception e) { return false; Log.e(TAG, "createBitmapFromGLSurfac e: " + e.getMessage(), e); intBuffer.position(0); try { return Bitmap.createBitmap(bitmap Source, w, h, Bitmap.Config.ARGB_8888); } return null; } } } try { //Get directory containing CPU info File dir = new File("/sys/devices/system/cp u/"); public void run() { PTServicesBridge.s_a ctivity.get().runOnUiThread( new Runnable() { try { //Filter to only list the devices we care about File[] files = dir.listFiles(new CpuFilter()); Log.d(TAG, "CPU Count: "+files.length); //Return the number of cores (virtual CPU devices) return files.length; final Intent intent = new Intent(Intent.ACTION_VIEW). setData(Uri.parse(PTServices Bridge.urlString)); PTServicesBridge.acti vity.startActivity(intent); } catch(Exception e) { public void run() { String leaderboardId = PTServicesBridge.getLeaderb oardId(); if(leaderboardId == null || leaderboardId.isEmpty()){ //Print exception return; } catch(Exception e) { //Print Log.d(TAG, "OpenURL: Failed."); } exception Log.d(TAG, "CPU Count: Failed."); e.printStackTrace(); } } e.printStackTrace(); }); PTServicesBridge.acti vity.startActivityForResult(Ga mes.Leaderboards.getLeader boardIntent(PTServicesBridg e.mGoogleApiClient, } //Default to return 1 core return 1; } } public static void openUrl( String url ){ Log.v(TAG, "PTServicesBridge -- Open URL " + url); PTServicesBridge.url String = url; PTServicesBridge.s_a ctivity.get().runOnUiThread( new Runnable() { public static void showLeaderboard( ){ Log.v(TAG, "PTServicesBridge -- Show Leaderboard "); if(PTServicesBridge. mGoogleApiClient == null || PTServicesBridge.mGoogleAp iClient.isConnected() == false){ Log.e(TAG, "Google play Servioces is not sigend"); return; } leaderboardId), REQUEST_LEADERBOARD); } }); } public static void showCustomFullScreenAd() { Log.e(TAG, "PTServicesBridge -showCustomFullScreenAd"); } public static void screenOnEnter(String name){ Log.e(TAG, "PTServicesBridge -screenOnEnter"); } public static void screenOnExit(String name){ Log.e(TAG, "PTServicesBridge -screenOnExit"); } public static void loadingDidComplete() { Log.e(TAG, "PTServicesBridge -loadingDidComplete"); } public static void submitScrore( int score ){ Log.v(TAG, "PTServicesBridge -- Submit Score " + score); if(PTServicesBridge. mGoogleApiClient == null || PTServicesBridge.mGoogleAp iClient.isConnected() == false){ Log.e(TAG, "Google play Servioces is not sigend"); return; } String if ( PTServicesBridge.mGoogleAp iClient.isConnected() ) { Games.Leaderboards .submitScore(PTServicesBrid ge.mGoogleApiClient, leaderboardId, PTServicesBridge.scoreValue) ; } } public static boolean isRunningOnTV(){ null || leaderboardId.isEmpty()){ PTServicesBridge.s_a ctivity.get().runOnUiThread( new Runnable() { public void run() { try { UiModeManager uiModeManager = (UiModeManager)PTServices Bridge.activity.getSystemSer vice( Context.UI_MODE_SERVICE ); if (uiModeManager.getCurrent ModeType() == Configuration.UI_MODE_TYP E_TELEVISION) { Log.d("DeviceTypeRu ntimeCheck", "Running on a TV Device"); return true; leaderboardId = PTServicesBridge.getLeaderb oardId(); if(leaderboardId == public static void showFacebookPage( final String facebookURL, final String facebookID){ Log.v(TAG, "Show facebook page for URL: " + facebookURL + " ID: " + facebookID); } else { Log.d("DeviceTypeRu ntimeCheck", "Running on a non-TV Device"); Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("fb://page/" + facebookID)); PTServicesBridge.acti vity.startActivity(intent); } catch(Exception e) { Log.v(TAG, "Show facebook FAILED going to exception handler : " + e.getMessage()); try { PTServicesBridge.acti vity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse( facebookURL ))); } catch (Exception e2) { return false; return; } } } PTServicesBridge.sco reValue = score; Log.v(TAG, "Show facebook exception handle FAILED : " + e2.getMessage()); DialogInterface.OnClickListen er() { } } } }); public void onClick(DialogInterface dialog, int which) { } public static void showWarningMessage(final String message){ Log.v(TAG, "Show warning with message: " + message); PTServicesBridge.war ningMessageClicked( true ); } }); dlgAlert.setCancelabl PTServicesBridge.s_a ctivity.get().runOnUiThread( new Runnable() { e(true); dlgAlert.create().sho w(); public void run() { } }); AlertDialog.Builder dlgAlert = new AlertDialog.Builder( PTServicesBridge.activity ); dlgAlert.setMessage( message); dlgAlert.setNegative Button("Cancel", new DialogInterface.OnClickListen er() { public void onClick(DialogInterface dialog, int which) { PTServicesBridge.warningMe ssageClicked( false ); } }); } public static void loginGameServices( ){ Log.v(TAG, "PTServicesBridge -- Login Game Services "); if(PTServicesBridge. mGoogleApiClient != null){ PTServicesBridge.mG oogleApiClient.connect(); } } public static boolean isGameServiceAvialable( ){ Log.v(TAG, "PTServicesBridge -- Is Game Service Avialable "); piClient != null && PTServicesBridge.mGoogleAp iClient.isConnected()); } @Override public void onConnected(Bundle arg0) { Log.v(TAG, "PTServicesBridge -- API Client Connected bundle:" + arg0); } @Override public void onConnectionSuspended(int arg0) { Log.v(TAG, "PTServicesBridge -- API Client Connection Suspended "); } @Override public void onConnectionFailed(Connect ionResult connectionResult) { Log.v(TAG, "PTServicesBridge -- API Client Connection FAILED:" + connectionResult); if(connectionResult.h asResolution()){ try { connectionResult.sta rtResolutionForResult(activit y, RC_SIGN_IN); } catch (SendIntentException e) { mGoogleApiClient.co dlgAlert.setPositiveB utton("OK", new return (PTServicesBridge.mGoogleA nnect(); } } } public static void backButtonPressed( ){ Log.v(TAG, "PTServicesBridge -backButtonPressed"); PTServicesBridge.s_a ctivity.get().runOnUiThread( new Runnable() { public void run() { PTServicesBridge.acti vity.moveTaskToBack(true); } }); } public void onActivityResult(int requestCode, int responseCode, Intent intent){ if(requestCode == RC_SIGN_IN && responseCode == -1){ mGoogleApiClient.co nnect(); byte[] sha1hash = md.digest(); return convertToHex(sha1hash); } sb.append(String.for mat("%02x", b)); } public static Object sha1Init() { sb.toString(); } MessageDigest digest = null; try{ private static String convertToHex(byte[] data) { StringBuilder buf = new StringBuilder(); for (byte b : data) { int halfbyte = (b >>> 4) & 0x0F; int two_halfs = 0; do { buf.append((0 <= halfbyte) && (halfbyte <= 9) ? (char) ('0' + halfbyte) : (char) ('a' + (halfbyte - 10))); halfbyte = b & 0x0F; } while (two_halfs++ < 1); } return buf.toString(); } return digest = MessageDigest.getInstance(" SHA-1"); } catch (NoSuchAlgorithmException e){ Log.e(TAG, "PTServicesBridge -NoSuchAlgorithmException") ; } return digest; } public static void sha1Update(Object digest, byte[] data, int length) { } PTJniHelper.java ackage com.secrethq.utils; ((MessageDigest)dig est).update(data, 0, length); } public class PTJniHelper { public static String password() { return "F3f+dc2uslwWfawkmKjjWU p2/XDJ/uBQTCzxIZ+psAgeL/8 nzvyxUBp3/XTOq+RcG3//L5q osQgbefovzqbhCw=="; } public static native boolean isAdNetworkActive( String name ); } } } public static String sha1( byte[] data, int length) throws NoSuchAlgorithmException, UnsupportedEncodingExcept ion { MessageDigest md = MessageDigest.getInstance(" SHA-1"); md.update(data, 0, length); public static String sha1Finish(Object digest) { byte[] hash = ((MessageDigest)digest).dige st(); StringBuilder sb = new StringBuilder(); for (byte b: hash) { Cocos2dxAccelerometer.jav a package org.cocos2dx.lib; import android.content.Context; import android.content.res.Configur ation; import android.hardware.Sensor; import android.hardware.SensorEve nt; import android.hardware.SensorEve ntListener; import android.hardware.SensorMa nager; import android.util.Log; import android.view.Display; import android.view.Surface; import android.view.WindowManag er; import android.os.Build.*; public class Cocos2dxAccelerometer implements SensorEventListener { // ======================== ======================== =========== // Constants // ======================== ======================== =========== private static final String TAG = Cocos2dxAccelerometer.clas s.getSimpleName(); // ======================== ======================== =========== // Fields // ======================== ======================== =========== aultSensor(Sensor.TYPE_ACC ELEROMETER); final Display display = ((WindowManager) this.mContext.getSystemServ ice(Context.WINDOW_SERVI CE)).getDefaultDisplay(); this.mNaturalOrienta private final Context mContext; private final SensorManager mSensorManager; private final Sensor mAccelerometer; private final int mNaturalOrientation; // ======================== ======================== =========== // Constructors // ======================== ======================== =========== public Cocos2dxAccelerometer(final Context pContext) { this.mContext = pContext; this.mSensorManage r = (SensorManager) this.mContext.getSystemServ ice(Context.SENSOR_SERVICE ); this.mAccelerometer = this.mSensorManager.getDef tion = display.getOrientation(); } // ======================== ======================== =========== // Getter & Setter // ======================== ======================== =========== public void enable() { this.mSensorManage r.registerListener(this, this.mAccelerometer, SensorManager.SENSOR_DEL AY_GAME); } public void setInterval(float interval) { // Honeycomb version is 11 if(android.os.Build.VERSION. SDK_INT < 11) { this.mSensorManager.registe rListener(this, this.mAccelerometer, SensorManager.SENSOR_DEL AY_GAME); } else { //convert seconds to microseconds this.mSensorManager.registe rListener(this, this.mAccelerometer, (int)(interval*100000)); } } public void disable() { this.mSensorManage r.unregisterListener(this); } // ======================== ======================== =========== // Methods for/from SuperClass/Interfaces // ======================== ======================== =========== @Override public void onSensorChanged(final SensorEvent pSensorEvent) { if (pSensorEvent.sensor.getTyp e() != Sensor.TYPE_ACCELEROMET ER) { return; } float x = pSensorEvent.values[0]; float y = pSensorEvent.values[1]; final float z = pSensorEvent.values[2]; /* * Because the axes are not swapped when the device's screen orientation * changes. So we should swap it here. In tablets such as Motorola Xoom, * the default orientation is landscape, so should consider this. */ final int orientation = this.mContext.getResources( ).getConfiguration().orientati on; if ((orientation == Configuration.ORIENTATION _LANDSCAPE) && (this.mNaturalOrientation != Surface.ROTATION_0)) { final float tmp = x; x=y; y= tmp; } else if ((orientation == Configuration.ORIENTATION _PORTRAIT) && (this.mNaturalOrientation != Surface.ROTATION_0)) { final float tmp = x; x = y; y=tmp; } Cocos2dxGLSurfaceV iew.queueAccelerometer(x,y, z,pSensorEvent.timestamp); /* if(BuildConfig.DEBUG ){ Log.d(TAG, "x = " + pSensorEvent.values[0] + " y = " + pSensorEvent.values[1] +"z="+ pSensorEvent.values[2]); } */ } @Override public void onAccuracyChanged(final Sensor pSensor, final int pAccuracy) { } // ======================== ======================== =========== // Methods // Native method called from Cocos2dxGLSurfaceView (To be in the same thread) // ======================== ======================== =========== public static native void onSensorChanged(final float pX, final float pY, final float pZ, final long pTimestamp); // ======================== ======================== =========== // Inner and Anonymous Classes // ======================== ======================== =========== } Cocos2dxActivity.java package org.cocos2dx.lib; import org.cocos2dx.lib.Cocos2dxHe lper.Cocos2dxHelperListener; import android.app.Activity; import android.content.Context; import android.os.Build; import android.os.Bundle; import android.os.Message; import android.view.ViewGroup; import android.util.Log; import android.widget.FrameLayout ; public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelperListener { // ======================== ======================== =========== // Constants // ======================== ======================== =========== private static final String TAG = Cocos2dxActivity.class.getSi mpleName(); // Fields // ======================== ======================== =========== private Cocos2dxGLSurfaceView mGLSurfaceView; private Cocos2dxHandler mHandler; private static Context sContext = null; public static Context getContext() { return sContext; } // ======================== ======================== =========== // Constructors // ======================== ======================== =========== @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(save dInstanceState); sContext = this; this.mHandler = new Cocos2dxHandler(this); // ======================== ======================== =========== // Getter & Setter // ======================== ======================== =========== // ======================== ======================== =========== // Methods for/from SuperClass/Interfaces // ======================== ======================== =========== @Override protected void onResume() { super.onResume(); Cocos2dxHelper.onR esume(); this.mGLSurfaceView .onResume(); } @Override protected void onPause() { super.onPause(); this.init(); Cocos2dxHelper.onP // ======================== ======================== =========== ause(); Cocos2dxHelper.init( this, this); } this.mGLSurfaceView .onPause(); } @Override public void showDialog(final String pTitle, final String pMessage) { Message msg = new Message(); msg.what = Cocos2dxHandler.HANDLER_ SHOW_DIALOG; msg.obj = new Cocos2dxHandler.DialogMes sage(pTitle, pMessage); this.mHandler.send Message(msg); } public void runOnGLThread(final Runnable pRunnable) { this.mGLSurfaceView .queueEvent(pRunnable); } // ======================== ======================== =========== // Methods // ======================== ======================== =========== public void init() { ViewGroup.LayoutParams.W RAP_CONTENT); Cocos2dxEditText edittext = new Cocos2dxEditText(this); edittext.setLayoutParams(edi ttext_layout_params); // ...add to FrameLayout framelayout.addView(edittex t); // Cocos2dxGLSurfaceView this.mGLSurfaceView = this.onCreateView(); // FrameLayout // ...add to FrameLayout @Override public void showEditTextDialog(final String pTitle, final String pContent, final int pInputMode, final int pInputFlag, final int pReturnType, final int pMaxLength) { Message msg = new Message(); msg.what = Cocos2dxHandler.HANDLER_ SHOW_EDITBOX_DIALOG; msg.obj = new Cocos2dxHandler.EditBoxMe ssage(pTitle, pContent, pInputMode, pInputFlag, pReturnType, pMaxLength); this.mHandler.send Message(msg); } @Override ViewGroup.LayoutParams framelayout_params = new ViewGroup.LayoutParams(Vi ewGroup.LayoutParams.FILL _PARENT, ViewGroup.LayoutParams.FIL L_PARENT); FrameLayout framelayout = new FrameLayout(this); framelayout.setLayoutParam s(framelayout_params); // Cocos2dxEditText layout ViewGroup.LayoutParams edittext_layout_params = new ViewGroup.LayoutParams(Vi ewGroup.LayoutParams.FILL _PARENT, framelayout.addView(this.m GLSurfaceView); // Switch to supported OpenGL (ARGB888) mode on emulator if (isAndroidEmulator()) this.mGLSurfaceView.setEGL ConfigChooser(8 , 8, 8, 8, 16, 0); this.mGLSurfaceView.setCoc os2dxRenderer(new Cocos2dxRenderer()); this.mGLSurfaceView.setCoc os2dxEditText(edittext); // Set framelayout as the content view setContentView(fra melayout); } import java.util.LinkedList; public Cocos2dxGLSurfaceView onCreateView() { return new Cocos2dxGLSurfaceView(this ); } private final static boolean isAndroidEmulator() { String model = Build.MODEL; Log.d(TAG, "model=" + model); String product = Build.PRODUCT; Log.d(TAG, "product=" + product); boolean isEmulator = false; if (product != null) { isEmulator = product.equals("sdk") || product.contains("_sdk") || product.contains("sdk_"); } Log.d(TAG, "isEmulator=" + isEmulator); return isEmulator; } // ======================== ======================== =========== // Inner and Anonymous Classes // ======================== ======================== =========== } Cocos2dxBitmap.java package org.cocos2dx.lib; import java.nio.ByteBuffer; import java.nio.ByteOrder; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Align; import android.graphics.Paint.Font MetricsInt; import android.graphics.Rect; import android.graphics.Typeface; import android.text.TextPaint; import android.text.TextUtils; import android.util.Log; public class Cocos2dxBitmap { // ======================== ======================== =========== // Constants // ======================== ======================== =========== /* The values are the same as cocos2dx/platform/CCImage. h. */ private static final int HORIZONTALALIGN_LEFT = 1; private static final int HORIZONTALALIGN_RIGHT = 2; private static final int HORIZONTALALIGN_CENTER = 3; private static final int VERTICALALIGN_TOP = 1; private static final int VERTICALALIGN_BOTTOM = 2; private static final int VERTICALALIGN_CENTER = 3; // ======================== ======================== =========== // Fields // ======================== ======================== =========== private static Context sContext; // ======================== ======================== =========== // Constructors // ======================== ======================== =========== // ======================== ======================== =========== // Getter & Setter // ======================== ======================== =========== public static void setContext(final Context pContext) { final Cocos2dxBitmap.sCo ntext = pContext; } int pHeight) { // ======================== ======================== =========== // Methods for/from SuperClass/Interfaces // ======================== ======================== =========== createTextBitmapSha dowStroke( pString, pFontName, pFontSize, 1.0f, 1.0f, 1.0f, // text font and color // ======================== ======================== =========== // Methods // ======================== ======================== =========== private static native void nativeInitBitmapDC(final int pWidth, final int pHeight, final byte[] pPixels); /** * @param pWidth * the width to draw, it can be 0 * @param pHeight * the height to draw, it can be 0 */ public static void createTextBitmap(String pString, final String pFontName, final int pFontSize, final int pAlignment, final int pWidth, final float fontTintG, final float fontTintB, // pAlignment, pWidth, pHeight, // alignment and size final int pAlignment, final int pWidth, final int pHeight, final boolean shadow, final float shadowDX, final float shadowDY, final float shadowBlur, final boolean stroke, false, 0.0f, 0.0f, 0.0f, final float strokeR, final float strokeG, final float strokeB, final float strokeSize) { // no shadow false, 1.0f, 1.0f, 1.0f, 1.0f); // no stroke } public static void createTextBitmapShadowStr oke(String pString, final String pFontName, final int pFontSize, final int horizontalAlignment = pAlignment & 0x0F; final int verticalAlignment = (pAlignment >> 4) & 0x0F; pString = Cocos2dxBitmap.refactorStri ng(pString); final Paint paint = Cocos2dxBitmap.newPaint(p FontName, pFontSize, horizontalAlignment); // set the paint color final float fontTintR, paint.setARGB(255, (int)(255.0 * fontTintR), (int)(255.0 * fontTintG), (int)(255.0 * fontTintB)); final TextProperty textProperty = Cocos2dxBitmap.computeTe xtProperty(pString, pWidth, pHeight, paint); final int bitmapTotalHeight = (pHeight == 0 ? textProperty.mTotalHeight: pHeight); renderTextDeltaX = bitmapPaddingX; } x= Cocos2dxBitmap.computeX(li ne, textProperty.mMaxWidth, horizontalAlignment); if ( shadowDY < 0.0 ) { renderTextDeltaY = bitmapPaddingY; } } canvas.drawText(line , x + renderTextDeltaX, y + renderTextDeltaY, paint); y += textProperty.mHeightPerLine ; } final Bitmap // padding needed when using shadows (not used otherwise) float bitmapPaddingX = 0.0f; float bitmapPaddingY = 0.0f; float renderTextDeltaX = 0.0f; float renderTextDeltaY = 0.0f; bitmap = Bitmap.createBitmap(textPro perty.mMaxWidth + (int)bitmapPaddingX, bitmapTotalHeight + (int)bitmapPaddingY, Bitmap.Config.ARGB_8888); final Canvas canvas = new Canvas(bitmap); if ( shadow ) { // draw again with stroke on if needed if ( stroke ) { final Paint paintStroke = Cocos2dxBitmap.newPaint(p FontName, pFontSize, horizontalAlignment); paintStroke.setStyle( Paint.Style.STROKE); /* Draw string. */ int shadowColor = 0xff7d7d7d; paint.setShadowLaye r(shadowBlur, shadowDX, shadowDY, shadowColor); bitmapPaddingX = Math.abs(shadowDX); bitmapPaddingY = Math.abs(shadowDY); if ( shadowDX < 0.0 ) { final FontMetricsInt fontMetricsInt = paint.getFontMetricsInt(); int x = 0; int y = Cocos2dxBitmap.computeY(f ontMetricsInt, pHeight, textProperty.mTotalHeight, verticalAlignment); final String[] lines = textProperty.mLines; for (final String line : lines) { paintStroke.setStrok eWidth(strokeSize * 0.5f); paintStroke.setARGB (255, (int)strokeR * 255, (int)strokeG * 255, (int)strokeB * 255); x = 0; y= Cocos2dxBitmap.computeY(f ontMetricsInt, pHeight, textProperty.mTotalHeight, verticalAlignment); final String[] lines2 = textProperty.mLines; for (final String line : lines2) { x= Cocos2dxBitmap.computeX(li ne, textProperty.mMaxWidth, horizontalAlignment); canvas.drawText(line , x + renderTextDeltaX, y + renderTextDeltaY, paintStroke); y += textProperty.mHeightPerLine ; /* Set type face for paint, now it support .ttf file. */ if (pFontName.endsWith(".ttf") ){ try { final Typeface typeFace = Cocos2dxTypefaces.get( paint.setTextAlign(Ali gn.CENTER); break; case HORIZONTALALIGN_RIGHT: paint.setTextAlign(Ali gn.RIGHT); break; Cocos2dxBitmap.sCo ntext, pFontName); paint.setTypeface(ty peFace); } catch (final Exception e) { case HORIZONTALALIGN_LEFT: default: paint.setTextAlign(Ali gn.LEFT); break; } } } Log.e("Cocos2dxBitm ap", "error to create ttf type face: " + Cocos2dxBitmap.init NativeObject(bitmap); } private static Paint newPaint(final String pFontName, final int pFontSize, final int pHorizontalAlignment) { final Paint paint = new Paint(); paint.setColor(Color. WHITE); pFontName); /* The file may not find, use system font. */ paint.setTypeface(Ty peface.create(pFontName, Typeface.NORMAL)); } } else { paint.setTypeface(Ty peface.create(pFontName, Typeface.NORMAL)); } paint.setTextSize(pFo ntSize); paint.setAntiAlias(tru e); switch (pHorizontalAlignment) { case HORIZONTALALIGN_CENTER: return paint; } private static TextProperty computeTextProperty(final String pString, final int pWidth, final int pHeight, final Paint pPaint) { final FontMetricsInt fm = pPaint.getFontMetricsInt(); final int h = (int) Math.ceil(fm.bottom fm.top); int maxContentWidth = 0; final String[] lines = Cocos2dxBitmap.splitString(p String, pWidth, pHeight, pPaint); if (pWidth != 0) { ret = pMaxWidth / 2; maxContentWidth = pWidth; } else { /* Compute the max width. */ int temp = 0; for (final String line : lines) { temp = (int) Math.ceil(pPaint.measureTex t(line, 0, break; case HORIZONTALALIGN_RIGHT: ret = pMaxWidth; / 2; break; break; case HORIZONTALALIGN_LEFT: default: break; } return ret; line.length())); y=pFontMetricsInt.top + (pConstrainHeight pTotalHeight) case VERTICALALIGN_BOTTOM: y=pFontMetricsInt.top + (pConstrainHeight pTotalHeight); break; } default: if (temp > maxContentWidth) { maxContentWidth = temp; } } } return new TextProperty(maxContentWi dth, h, lines); } private static int computeX(final String pText, final int pMaxWidth, final int pHorizontalAlignment) { int ret = 0; switch (pHorizontalAlignment) { case HORIZONTALALIGN_CENTER: private static int computeY(final FontMetricsInt pFontMetricsInt, final int pConstrainHeight, final int pTotalHeight, final int pVerticalAlignment) { int y = pFontMetricsInt.top; if (pConstrainHeight > pTotalHeight) { switch (pVerticalAlignment) { case VERTICALALIGN_TOP: y=pFontMetricsInt.top; break; case VERTICALALIGN_CENTER: break; } } return y; } /* * If maxWidth or maxHeight is not 0, split the string to fix the maxWidth * and maxHeight. */ private static String[] splitString(final String pString, final int pMaxWidth, final int pMaxHeight, final Paint pPaint) { final String[] lines = pString.split("\\n"); String[] ret = null; final FontMetricsInt fm = pPaint.getFontMetricsInt(); final int heightPerLine = (int) Math.ceil(fm.bottom fm.top); final int maxLines = pMaxHeight / heightPerLine; if (pMaxWidth != 0) { final LinkedList<String> strList = new LinkedList<String>(); for (final String line : lines) { /* * The width of line is exceed maxWidth, should divide it into * two or more lines. ret = new String[strList.size()]; } /* Should not exceed the max height. */ lines; if (maxLines > 0 && strList.size() >= maxLines) { } return ret; break; } } } /* Remove exceeding lines. */ if (maxLines > 0 && strList.size() > maxLines) { while (strList.size() > maxLines) { */ strList.removeLast(); final int lineWidth = (int) Math.ceil(pPaint strList.toArray(ret); } else { ret = } private static LinkedList<String> divideStringWithMaxWidth( final String pString, final int pMaxWidth, final Paint pPaint) { final int charLength = pString.length(); int start = 0; int tempWidth = 0; final LinkedList<String> strList = new LinkedList<String>(); } .measureText(line)); if (lineWidth > pMaxWidth) { strList.addAll(Cocos2 dxBitmap.divideStringWithM axWidth( line, pMaxWidth, pPaint)); ret = new String[strList.size()]; strList.toArray(ret); } else if (pMaxHeight != 0 && lines.length > maxLines) { /* Remove exceeding lines. */ final LinkedList<String> strList = new LinkedList<String>(); for (int i = 0; i < maxLines; i++) { /* Break a String into String[] by the width & should wrap the word. */ for (int i = 1; i <= charLength; ++i) { tempWidth = (int) Math.ceil(pPaint.measureTex t(pString, start, i)); if (tempWidth >= pMaxWidth) { } else { strList.add(lines[i]); } strList.add(line); final int lastIndexOfSpace = pString.substring(0, i) .lastIndexOf(" "); if (lastIndexOfSpace != -1 && lastIndexOfSpace > start) { /* Remove spaces at the beginning of a new line. */ while (i < charLength && pString.charAt(i) == ' ') { /* Should wrap the word. */ ++i; } strList.add(pString.su bstring(start, lastIndexOfSpace)); start = i; } * example: "\nabc" -> " \nabc" "\nabc\n\n" -> " \nabc\n \n". */ final StringBuilder strBuilder = new StringBuilder(pString); int start = 0; int index = strBuilder.indexOf("\n"); while (index != -1) { if (index == 0 || strBuilder.charAt(index - 1) == '\n') { } i= lastIndexOfSpace + 1; // skip space strBuilder.insert(star /* Add the t, " "); last chars. */ if (start < } else { start = index + 2; } else charLength) { { /* Should not exceed the width. */ strList.add(pString.su bstring(start)); } if (tempWidth > pMaxWidth) { return strList; } strList.add(pString.su bstring(start, i - 1)); /* Compute from previous char. */ --i; private static String refactorString(final String pString) { /* Avoid error when content is "". */ if (pString.compareTo("") == 0) { start = index + 1; } if (start > strBuilder.length() || index == strBuilder.length()) { break; } index = strBuilder.indexOf("\n", start); } } else { return " "; } strList.add(pString.su bstring(start, i)); } } /* * If the font of "\n" is "" or "\n", insert " " in front of it. For return strBuilder.toString(); } private static void initNativeObject(final Bitmap pBitmap) { final byte[] pixels = Cocos2dxBitmap.getPixels(p Bitmap); if (pixels == null) { private static int getFontSizeAccordingHeight(i nt height) { Paint paint = new Paint(); Rect bounds = new Rect(); private static String getStringWithEllipsis(String pString, float width, float fontSize) { if (TextUtils.isEmpty(pString)) { return; } Cocos2dxBitmap.nati veInitBitmapDC(pBitmap.get Width(), paint.setTypeface(Ty peface.DEFAULT); int incr_text_size = 1; boolean found_desired_size = false; pBitmap.getHeight(), pixels); return ""; } TextPaint paint = new TextPaint(); paint.setTypeface(Ty peface.DEFAULT); while (!found_desired_size) { } paint.setTextSize(fon tSize); private static byte[] getPixels(final Bitmap pBitmap) { if (pBitmap != null) { final byte[] pixels = new byte[pBitmap.getWidth() * pBitmap.getHeight() * 4]; final ByteBuffer buf = ByteBuffer.wrap(pixels); buf.order(ByteOrder. nativeOrder()); pBitmap.copyPixelsT oBuffer(buf); paint.setTextSize(inc r_text_size); String text = "SghMNy"; paint.getTextBounds (text, 0, text.length(), bounds); incr_text_size++; if (height - bounds.height() <= 2) { found_desired_size = return null; } TextUtils.TruncateAt. END).toString(); } // ======================== ======================== =========== // Inner and Anonymous Classes // ======================== ======================== =========== true; } return pixels; } return TextUtils.ellipsize(pString, paint, width, Log.d("font size", "incr size:" + incr_text_size); } return incr_text_size; } private static class TextProperty { /** The max width of lines. */ private final int mMaxWidth; /** The height of all lines. */ private final int mTotalHeight; private final int mHeightPerLine; private final String[] mLines; TextProperty(final int pMaxWidth, final int pHeightPerLine, final String[] pLines) { this.mMaxWidth = pMaxWidth; this.mHeightPerLine = pHeightPerLine; this.mTotalHeight = pHeightPerLine * pLines.length; this.mLines = pLines; } } } Cocos2dxEditBoxDialog.java package org.cocos2dx.lib; import android.app.Dialog; import android.content.Context; import android.graphics.drawable.C olorDrawable; import android.os.Bundle; import android.os.Handler; import android.text.InputFilter; import android.text.InputType; import android.util.TypedValue; import android.view.KeyEvent; import android.view.ViewGroup; import android.view.WindowManag er; import android.view.inputmethod.E ditorInfo; import android.view.inputmethod.In putMethodManager; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.TextView.On EditorActionListener; public class Cocos2dxEditBoxDialog extends Dialog { // ======================== ======================== =========== // Constants // ======================== ======================== =========== /** * The user is allowed to enter any text, including line breaks. */ private final int kEditBoxInputModeAny = 0; /** * The user is allowed to enter an e-mail address. */ private final int kEditBoxInputModeEmailAdd r = 1; /** * The user is allowed to enter an integer value. */ private final int kEditBoxInputModeNumeric = 2; /** * The user is allowed to enter a phone number. */ private final int kEditBoxInputModePhoneNu mber = 3; /** * The user is allowed to enter a URL. */ private final int kEditBoxInputModeUrl = 4; /** * The user is allowed to enter a real number value. This extends kEditBoxInputModeNumeric by allowing a decimal point. */ private final int kEditBoxInputModeDecimal = 5; /** * The user is allowed to enter any text, except for line breaks. */ private final int kEditBoxInputModeSingleLin e = 6; /** * Indicates that the text entered is confidential data that should be obscured whenever possible. This implies EDIT_BOX_INPUT_FLAG_SEN SITIVE. */ private final int kEditBoxInputFlagPassword = 0; private final int kEditBoxInputFlagInitialCaps Sentence = 3; /** * Indicates that the text entered is sensitive data that the implementation must never store into a dictionary or table for use in predictive, auto-completing, or other accelerated input schemes. A credit card number is an example of sensitive data. */ private final int kEditBoxInputFlagSensitive = 1; private final int kKeyboardReturnTypeDefaul t = 0; private final int kKeyboardReturnTypeDone = 1; private final int kKeyboardReturnTypeSend = 2; private final int kKeyboardReturnTypeSearch = 3; private final int kKeyboardReturnTypeGo = 4; /** * This flag is a hint to the implementation that during text editing, the initial letter of each word should be capitalized. */ private final int kEditBoxInputFlagInitialCaps Word = 2; /** * This flag is a hint to the implementation that during text editing, the initial letter of each sentence should be capitalized. */ /** * Capitalize all characters automatically. */ private final int kEditBoxInputFlagInitialCaps AllCharacters = 4; // ======================== ======================== =========== // Fields // ======================== ======================== =========== private EditText mInputEditText; private TextView mTextViewTitle; private final int mInputFlag; private final int mReturnType; private final int mMaxLength; private int mInputFlagConstraints; private int mInputModeContraints; private boolean mIsMultiline; // ======================== ======================== =========== // Constructors // ======================== ======================== =========== public Cocos2dxEditBoxDialog(final Context pContext, final String pTitle, final String pMessage, final int pInputMode, final int pInputFlag, final int pReturnType, final int pMaxLength) { super(pContext, android.R.style.Theme_Trans lucent_NoTitleBar_Fullscreen ); // super(context, R.style.Theme_Translucent); this.mTitle = private final String pTitle; mTitle; private final String mMessage; private final int mInputMode; this.mMessage = pMessage; this.mInputMode = pInputMode; this.mInputFlag = pInputFlag; this.mReturnType = pReturnType; this.mMaxLength = pMaxLength; } @Override protected void onCreate(final Bundle pSavedInstanceState) { super.onCreate(pSav edInstanceState); this.getWindow().set BackgroundDrawable(new ColorDrawable(0x80000000)) ; final LinearLayout layout = new LinearLayout(this.getContext ()); layout.setOrientation (LinearLayout.VERTICAL); final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( ViewGroup.LayoutParams.FIL L_PARENT, ViewGroup.LayoutParams.FIL L_PARENT); this.mTextViewTitle = new TextView(this.getContext()); final LinearLayout.LayoutParams textviewParams = new LinearLayout.LayoutParams( ViewGroup.LayoutParams.W RAP_CONTENT, ViewGroup.LayoutParams.W RAP_CONTENT); textviewParams.left Margin = textviewParams.rightMargin = this.convertDipsToPixels(10); this.mTextViewTitle.s etTextSize(TypedValue.COM PLEX_UNIT_DIP, 20); layout.addView(this. mTextViewTitle, textviewParams); this.mInputEditText = new EditText(this.getContext()); final LinearLayout.LayoutParams editTextParams = new LinearLayout.LayoutParams( ViewGroup.LayoutParams.FIL L_PARENT, ViewGroup.LayoutParams.W RAP_CONTENT); editTextParams.left Margin = editTextParams.rightMargin = this.convertDipsToPixels(10); layout.addView(this. mInputEditText, editTextParams); this.setContentView( layout, layoutParams); this.getWindow().ad dFlags(WindowManager.Lay outParams.FLAG_FULLSCREE N); this.mTextViewTitle.s etText(this.mTitle); this.mInputEditText.s etText(this.mMessage); int oldImeOptions = this.mInputEditText.getImeO ptions(); this.mInputEditText.s etImeOptions(oldImeOptions | EditorInfo.IME_FLAG_NO_EX TRACT_UI); oldImeOptions = this.mInputEditText.getImeO ptions(); switch (this.mInputMode) { case kEditBoxInputModeAny: this.mInputModeCon traints = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_ MULTI_LINE; break; case kEditBoxInputModeEmailAdd r: this.mInputModeCon traints = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIA TION_EMAIL_ADDRESS; break; case kEditBoxInputModeNumeric: this.mInputModeCon traints = InputType.TYPE_CLASS_NUM BER | InputType.TYPE_NUMBER_FL AG_SIGNED; traints = InputType.TYPE_CLASS_NUM BER | InputType.TYPE_NUMBER_FL AG_DECIMAL | InputType.TYPE_NUMBER_FL AG_SIGNED; case kEditBoxInputModeSingleLin e: this.mInputModeCon traints = InputType.TYPE_CLASS_TEXT ; case break; case kEditBoxInputModeDecimal: raints = InputType.TYPE_TEXT_FLAG_ NO_SUGGESTIONS; break; case kEditBoxInputFlagInitialCaps Word: break; } if (this.mIsMultiline) { this.mInputModeCon traints |= InputType.TYPE_TEXT_FLAG_ MULTI_LINE; } break; case kEditBoxInputFlagInitialCaps Sentence: this.mInputFlagConst raints = InputType.TYPE_TEXT_FLAG_ CAP_SENTENCES; break; this.mInputEditText.s etInputType(this.mInputMod eContraints | this.mInputFlagConstraints); switch (this.mInputFlag) { case kEditBoxInputFlagPassword: this.mInputFlagConst this.mInputModeCon this.mInputFlagConst this.mInputFlagConst raints = InputType.TYPE_TEXT_FLAG_ CAP_WORDS; default: kEditBoxInputModeUrl: this.mInputModeCon traints = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIA TION_URI; case kEditBoxInputFlagSensitive: break; case kEditBoxInputModePhoneNu mber: break; break; break; break; this.mInputModeCon traints = InputType.TYPE_CLASS_PHO NE; InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIA TION_PASSWORD; raints = case kEditBoxInputFlagInitialCaps AllCharacters: this.mInputFlagConst raints = InputType.TYPE_TEXT_FLAG_ CAP_CHARACTERS; break; default: break; } etImeOptions(oldImeOptions | EditorInfo.IME_ACTION_SEA RCH); og.this.mInputEditText.reque stFocus(); this.mInputEditText.s etInputType(this.mInputFlag Constraints | this.mInputModeContraints); case kKeyboardReturnTypeGo: Cocos2dxEditBoxDial og.this.mInputEditText.setSel ection(Cocos2dxEditBoxDialo g.this.mInputEditText.length( )); switch (this.mReturnType) { this.mInputEditText.s etImeOptions(oldImeOptions | EditorInfo.IME_ACTION_GO); Cocos2dxEditBoxDial og.this.openKeyboard(); } }, 200); case kKeyboardReturnTypeDefaul t: this.mInputEditText.s etImeOptions(oldImeOptions | EditorInfo.IME_ACTION_NO NE); break; case kKeyboardReturnTypeDone: break; break; this.mInputEditText.s etOnEditorActionListener(ne w OnEditorActionListener() { default: this.mInputEditText.s etImeOptions(oldImeOptions | EditorInfo.IME_ACTION_NO NE); break; @Override public boolean onEditorAction(final TextView v, final int actionId, final KeyEvent event) { } this.mInputEditText.s etImeOptions(oldImeOptions | EditorInfo.IME_ACTION_DON E); break; case kKeyboardReturnTypeSend: this.mInputEditText.s etImeOptions(oldImeOptions | EditorInfo.IME_ACTION_SEN D); if (this.mMaxLength > 0) { this.mInputEditText.s etFilters(new InputFilter[] { new InputFilter.LengthFilter(this. mMaxLength) }); } final Handler initHandler = new Handler(); this.mInputEditText.s if (actionId != EditorInfo.IME_NULL || (actionId == EditorInfo.IME_NULL && event != null && event.getAction() == KeyEvent.ACTION_DOWN)) { initHandler.postDela yed(new Runnable() { break; case kKeyboardReturnTypeSearch : /* If user didn't set keyboard type, this callback will be invoked twice with 'KeyEvent.ACTION_DOWN' and 'KeyEvent.ACTION_UP'. */ @Override public void run() { Cocos2dxEditBoxDial Cocos2dxHelper.setE ditTextDialogResult(Cocos2d xEditBoxDialog.this.mInputE ditText.getText().toString()); Cocos2dxEditBoxDial og.this.closeKeyboard(); Cocos2dxEditBoxDial og.this.dismiss(); return true; } private int convertDipsToPixels(final float pDIPs) { final float scale = this.getContext().getResourc es().getDisplayMetrics().dens ity; return Math.round(pDIPs * scale); } return false; } }); } // ======================== ======================== =========== // Getter & Setter // ======================== ======================== =========== // ======================== ======================== =========== // Methods for/from SuperClass/Interfaces // ======================== ======================== =========== // ======================== ======================== =========== // Methods // ======================== ======================== =========== private void openKeyboard() { final InputMethodManager imm = (InputMethodManager) this.getContext().getSystemS ervice(Context.INPUT_METH OD_SERVICE); imm.showSoftInput(t his.mInputEditText, 0); } private void closeKeyboard() { final InputMethodManager imm = (InputMethodManager) this.getContext().getSystemS ervice(Context.INPUT_METH OD_SERVICE); imm.hideSoftInputFr omWindow(this.mInputEditT ext.getWindowToken(), 0); } // ======================== ======================== =========== // Inner and Anonymous Classes // ======================== ======================== =========== } Cocos2dxEditText.java package org.cocos2dx.lib; import android.content.Context; import android.util.AttributeSet; import android.view.KeyEvent; import android.widget.EditText; public class Cocos2dxEditText extends EditText { // ======================== ======================== =========== // Constants // ======================== ======================== =========== // ======================== ======================== =========== // Fields // ======================== ======================== =========== private Cocos2dxGLSurfaceView mCocos2dxGLSurfaceView; // ======================== ======================== =========== // Constructors // ======================== ======================== =========== public Cocos2dxEditText(final Context context) { super(context); } public Cocos2dxEditText(final Context context, final AttributeSet attrs) { super(context, attrs); } public Cocos2dxEditText(final Context context, final AttributeSet attrs, final int defStyle) { super(context, attrs, defStyle); } // ======================== ======================== =========== // Getter & Setter // ======================== ======================== =========== public void setCocos2dxGLSurfaceView(f inal Cocos2dxGLSurfaceView pCocos2dxGLSurfaceView) { this.mCocos2dxGLSu rfaceView = pCocos2dxGLSurfaceView; } // ======================== ======================== =========== // Methods for/from SuperClass/Interfaces // ======================== ======================== =========== ======================== =========== // Inner and Anonymous Classes // ======================== ======================== =========== } Cocos2dxETCLoader.java package org.cocos2dx.lib; @Override public boolean onKeyDown(final int pKeyCode, final KeyEvent pKeyEvent) { import java.io.FileInputStream; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; super.onKeyDown(p KeyCode, pKeyEvent); import android.content.Context; import android.content.res.AssetMa nager; import android.opengl.ETC1Util; import android.util.Log; /* Let GlSurfaceView get focus if back key is input. */ if (pKeyCode == KeyEvent.KEYCODE_BACK) { this.mCocos2dxGLSu rfaceView.requestFocus(); } return true; } // ======================== ======================== =========== // Methods // ======================== ======================== =========== // ======================== public class Cocos2dxETCLoader { private static final String ASSETS_PATH = "assets/"; private static Context context; public static boolean loadTexture(String filePath) { if (! ETC1Util.isETC1Supported()) { return false; } if (filePath.length() == 0) { return false; } // Create ETC1Texture InputStream inputStream = null; ETC1Util.ETC1Textur e texture = null; ETC1Util.createTexture(input Stream); inputStream.close(); } catch (Exception e) { data, length); } Log.d("Cocos2dx", "Unable to create texture for " + filePath); catch (Exception e) { Log.d("invoke native function error", e.toString()); AssetManager assetManager = null; try { if (filePath.charAt(0) == '/') { height, texture = null; } ret = false; } if (texture != null) { // absolute path boolean ret = true; inputStream = new FileInputStream(filePath); } else { final int width = texture.getWidth(); // remove prefix: "assets/" final int height = texture.getHeight(); public static void setContext(Context context) { if (filePath.startsWith(ASSETS_ PATH)) { final int length = texture.getData().remaining( ); Cocos2dxETCLoader. context = context; } filePath = filePath.substring(ASSETS_PA TH.length()); final byte[] data = new byte[length]; } assetManager = context.getAssets(); inputStream = assetManager.open(filePath) ; } try { return ret; } else { final ByteBuffer buf = ByteBuffer.wrap(data); buf.order(ByteOrder.nativeO rder()); buf.put(texture.getData()); nativeSetTextureInfo (width, texture = return false; } } private static native void nativeSetTextureInfo(final int width, final int height, final byte[] data, final int dataLength); } Cocos2dxGLSurfaceView.jav a package org.cocos2dx.lib; import android.content.Context; import android.opengl.GLSurfaceVie w; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.Log; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.inputmethod.In putMethodManager; public class Cocos2dxGLSurfaceView extends GLSurfaceView { // ======================== ======================== =========== // Constants // ======================== ======================== =========== private static final String TAG = Cocos2dxGLSurfaceView.clas s.getSimpleName(); private final static int HANDLER_OPEN_IME_KEYB OARD = 2; private final static int HANDLER_CLOSE_IME_KEYB OARD = 3; // ======================== ======================== =========== // Fields // ======================== ======================== =========== // TODO Static handler -> Potential leak! private static Handler sHandler; this.initView(); } protected void initView() { private static Cocos2dxGLSurfaceView mCocos2dxGLSurfaceView; private static Cocos2dxTextInputWraper sCocos2dxTextInputWraper; this.setEGLContextCli entVersion(2); private Cocos2dxRenderer mCocos2dxRenderer; private Cocos2dxEditText mCocos2dxEditText; Cocos2dxGLSurfaceV iew.mCocos2dxGLSurfaceVie w = this; // ======================== ======================== =========== // Constructors // ======================== ======================== =========== public Cocos2dxGLSurfaceView(fina l Context context) { super(context); this.initView(); } public Cocos2dxGLSurfaceView(fina l Context context, final AttributeSet attrs) { super(context, attrs); this.setFocusableInT ouchMode(true); Cocos2dxGLSurfaceV iew.sCocos2dxTextInputWra per = new Cocos2dxTextInputWraper(t his); Cocos2dxGLSurfaceV iew.sHandler = new Handler() { @Override public void handleMessage(final Message msg) { switch (msg.what) { case HANDLER_OPEN_IME_KEYB OARD: if (null != Cocos2dxGLSurfaceView.this. mCocos2dxEditText && Cocos2dxGLSurfaceView.this. mCocos2dxEditText.requestF ocus()) { Cocos2dxGLSurfaceView.this. mCocos2dxEditText, 0); Log.d("GLSurfaceVie w", "HideSoftInput"); Cocos2dxGLSurfaceV iew.this.mCocos2dxEditText. removeTextChangedListener( Cocos2dxGLSurfaceView.sCo cos2dxTextInputWraper); Log.d("GLSurfaceVie w", "showSoftInput"); } break; break; Cocos2dxGLSurfaceV iew.this.mCocos2dxEditText. setText(""); final String text = (String) msg.obj; Cocos2dxGLSurfaceV iew.this.mCocos2dxEditText. append(text); Cocos2dxGLSurfaceV iew.sCocos2dxTextInputWra per.setOriginText(text); Cocos2dxGLSurfaceV iew.this.mCocos2dxEditText. addTextChangedListener(Coc os2dxGLSurfaceView.sCocos 2dxTextInputWraper); final InputMethodManager imm = (InputMethodManager) Cocos2dxGLSurfaceView.mC ocos2dxGLSurfaceView.getC ontext().getSystemService(C ontext.INPUT_METHOD_SER VICE); imm.showSoftInput( } } } }; case HANDLER_CLOSE_IME_KEYB OARD: if (null != Cocos2dxGLSurfaceView.this. mCocos2dxEditText) { Cocos2dxGLSurfaceV iew.this.mCocos2dxEditText. removeTextChangedListener( Cocos2dxGLSurfaceView.sCo cos2dxTextInputWraper); final InputMethodManager imm = (InputMethodManager) Cocos2dxGLSurfaceView.mC ocos2dxGLSurfaceView.getC ontext().getSystemService(C ontext.INPUT_METHOD_SER VICE); } // ======================== ======================== =========== // Getter & Setter // ======================== ======================== =========== public static Cocos2dxGLSurfaceView getInstance() { return mCocos2dxGLSurfaceView; } public static void queueAccelerometer(final float x, final float y, final float z, final long timestamp) { imm.hideSoftInputFr omWindow(Cocos2dxGLSurf aceView.this.mCocos2dxEdit Text.getWindowToken(), 0); mCocos2dxGLSurfaceView.q ueueEvent(new Runnable() { @Override public void run() { Cocos2dxGLSurfaceV iew.this.requestFocus(); Cocos2dxAccelerometer.onS ensorChanged(x, y, z, timestamp); } }); } public void setCocos2dxRenderer(final Cocos2dxRenderer renderer) { public void onPause() this.mCocos2dxEditT ext.setCocos2dxGLSurfaceVie w(this); this.requestFocus(); } } { this.queueEvent(new Runnable() { @Override public void run() { this.mCocos2dxRend erer = renderer; this.setRenderer(this .mCocos2dxRenderer); } private String getContentText() { return this.mCocos2dxRenderer.get ContentText(); } public Cocos2dxEditText getCocos2dxEditText() { return this.mCocos2dxEditText; } public void setCocos2dxEditText(final Cocos2dxEditText pCocos2dxEditText) { this.mCocos2dxEditT ext = pCocos2dxEditText; if (null != this.mCocos2dxEditText && null != Cocos2dxGLSurfaceView.sCo cos2dxTextInputWraper) { this.mCocos2dxEditT ext.setOnEditorActionListene r(Cocos2dxGLSurfaceView.sC ocos2dxTextInputWraper); // ======================== ======================== =========== // Methods for/from SuperClass/Interfaces // ======================== ======================== =========== @Override public void onResume() { Cocos2dxGLSurfaceV iew.this.mCocos2dxRenderer .handleOnPause(); } }); this.setRenderMode( RENDERMODE_WHEN_DIRTY ); //super.onPause(); } super.onResume(); this.setRenderMode( RENDERMODE_CONTINUOU SLY); this.queueEvent(new Runnable() { @Override public void run() { Cocos2dxGLSurfaceV iew.this.mCocos2dxRenderer .handleOnResume(); } }); } @Override @Override public boolean onTouchEvent(final MotionEvent pMotionEvent) { // these data are used in ACTION_MOVE and ACTION_CANCEL final int pointerNumber = pMotionEvent.getPointerCou nt(); final int[] ids = new int[pointerNumber]; final float[] xs = new float[pointerNumber]; final float[] ys = new float[pointerNumber]; for (int i = 0; i < pointerNumber; i++) { ids[i] = pMotionEvent.getPointerId(i) ; xs[i] = pMotionEvent.getX(i); ys[i] = pMotionEvent.getY(i); } switch (pMotionEvent.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_POINT ER_DOWN: final int indexPointerDown = pMotionEvent.getAction() >> MotionEvent.ACTION_POINT ER_ID_SHIFT; final int idPointerDown = pMotionEvent.getPointerId(i ndexPointerDown); }); Cocos2dxGLSurfaceV iew.this.mCocos2dxRenderer .handleActionDown(idPointe rDown, xPointerDown, yPointerDown); break; case MotionEvent.ACTION_MOVE : } this.queueEvent(new Runnable() { }); break; @Override case MotionEvent.ACTION_DOW N: // there are only one finger on the screen final int idDown = pMotionEvent.getPointerId(0 ); final float xDown = public void run() { Cocos2dxGLSurfaceV iew.this.mCocos2dxRenderer .handleActionMove(ids, xs, ys); } }); xs[0]; break; final float yDown = final float xPointerDown = pMotionEvent.getX(indexPoi nterDown); ys[0]; case MotionEvent.ACTION_POINT ER_UP: this.queueEvent(new Runnable() { final float yPointerDown = pMotionEvent.getY(indexPoi nterDown); @Override public void final int indexPointUp = pMotionEvent.getAction() >> MotionEvent.ACTION_POINT ER_ID_SHIFT; run() { this.queueEvent(new Runnable() { @Override Cocos2dxGLSurfaceV iew.this.mCocos2dxRenderer .handleActionDown(idDown, xDown, yDown); public void run() { } final int idPointerUp = pMotionEvent.getPointerId(i ndexPointUp); final float xPointerUp = pMotionEvent.getX(indexPoi ntUp); final float yPointerUp = pMotionEvent.getY(indexPoi ntUp); this.queueEvent(new Runnable() { run() { } Cocos2dxGLSurfaceV iew.this.mCocos2dxRenderer .handleActionUp(idUp, xUp, yUp); @Override } public void }); run() { break; Cocos2dxGLSurfaceV iew.this.mCocos2dxRenderer .handleActionUp(idPointerU p, xPointerUp, yPointerUp); } } */ return true; public void case MotionEvent.ACTION_CANCE L: /* * This function is called before Cocos2dxRenderer.nativeInit (), so the * width and height is correct. */ @Override protected void onSizeChanged(final int pNewSurfaceWidth, final int pNewSurfaceHeight, final int pOldSurfaceWidth, final int pOldSurfaceHeight) { this.queueEvent(new Runnable() { if(!this.isInEditMode( )) { }); @Override break; public void run() { case MotionEvent.ACTION_UP: // there are only one finger on the screen Cocos2dxGLSurfaceV iew.this.mCocos2dxRenderer .handleActionCancel(ids, xs, ys); final int idUp = pMotionEvent.getPointerId(0 ); } }); this.mCocos2dxRend erer.setScreenWidthAndHeig ht(pNewSurfaceWidth, pNewSurfaceHeight); } } @Override public boolean onKeyDown(final int pKeyCode, final KeyEvent pKeyEvent) { final float xUp = xs[0]; break; } if(pKeyEvent.getRep eatCount() > 0){ final float yUp = ys[0]; /* if (BuildConfig.DEBUG) { this.queueEvent(new Runnable() { @Override Cocos2dxGLSurfaceV iew.dumpMotionEvent(pMot ionEvent); return false; } switch (pKeyCode) { case KeyEvent.KEYCODE_BACK: case KeyEvent.KEYCODE_MENU: case KeyEvent.KEYCODE_DPAD_L EFT: case KeyEvent.KEYCODE_DPAD_C ENTER: case KeyEvent.KEYCODE_DPAD_RI GHT: case KeyEvent.KEYCODE_DPAD_U P: case KeyEvent.KEYCODE_DPAD_D OWN: case KeyEvent.KEYCODE_BUTTON _A: case KeyEvent.KEYCODE_BUTTON _B: case KeyEvent.KEYCODE_BUTTON _X: case KeyEvent.KEYCODE_BUTTON _Y: this.queueEvent(new Runnable() { @Override public void run() { Cocos2dxGLSurfaceV iew.this.mCocos2dxRenderer .handleKeyDown(pKeyCode); Log.v("PTPLAYER", "KEY DOWN" + pKeyCode); } case KeyEvent.KEYCODE_BUTTON _Y: }); return true; this.queueEvent(new Runnable() { default: return super.onKeyDown(pKeyCode , pKeyEvent); } } public boolean onKeyUp(final int pKeyCode, final KeyEvent pKeyEvent){ @Override public void run() { Cocos2dxGLSurfaceV iew.this.mCocos2dxRenderer .handleKeyUp(pKeyCode); switch (pKeyCode) { case KeyEvent.KEYCODE_BACK: case KeyEvent.KEYCODE_MENU: case KeyEvent.KEYCODE_DPAD_C ENTER: case KeyEvent.KEYCODE_DPAD_L EFT: case KeyEvent.KEYCODE_DPAD_RI GHT: case KeyEvent.KEYCODE_DPAD_U P: case KeyEvent.KEYCODE_DPAD_D OWN: case KeyEvent.KEYCODE_BUTTON _A: case KeyEvent.KEYCODE_BUTTON _B: case KeyEvent.KEYCODE_BUTTON _X: Log.v("PTPLAYER", "KEY UP" + pKeyCode); } }); return true; default: return super.onKeyDown(pKeyCode , pKeyEvent); } } // ======================== ======================== =========== // Methods // ======================== ======================== =========== // ======================== ======================== =========== // Inner and Anonymous Classes // ======================== ======================== =========== public static void openIMEKeyboard() { final Message msg = new Message(); msg.what = Cocos2dxGLSurfaceView.HA NDLER_OPEN_IME_KEYBOAR D; msg.obj = Cocos2dxGLSurfaceView.mC ocos2dxGLSurfaceView.getC ontentText(); Cocos2dxGLSurfaceV iew.sHandler.sendMessage( msg); } public static void closeIMEKeyboard() { final Message msg = new Message(); msg.what = Cocos2dxGLSurfaceView.HA NDLER_CLOSE_IME_KEYBOA RD; Cocos2dxGLSurfaceV iew.sHandler.sendMessage( msg); } public void insertText(final String pText) { this.queueEvent(new Runnable() { @Override public void run() { Cocos2dxGLSurfaceV iew.this.mCocos2dxRenderer .handleInsertText(pText); } }); } public void deleteBackward() { final int actionCode = action & MotionEvent.ACTION_MASK; sb.append("event ACTION_").append(names[ac tionCode]); if (actionCode == MotionEvent.ACTION_POINT ER_DOWN || actionCode == MotionEvent.ACTION_POINT ER_UP) { sb.append("(pid ").append(action >> MotionEvent.ACTION_POINT ER_ID_SHIFT); this.queueEvent(new Runnable() { sb.append(")"); } @Override public void run() { Cocos2dxGLSurfaceV iew.this.mCocos2dxRenderer .handleDeleteBackward(); } }); } private static void dumpMotionEvent(final MotionEvent event) { final String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE", "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" }; final StringBuilder sb = new StringBuilder(); final int action = event.getAction(); sb.append("["); for (int i = 0; i < event.getPointerCount(); i++) { sb.append("#").appe nd(i); sb.append("(pid ").append(event.getPointerId (i)); sb.append(")=").app end((int) event.getX(i)); sb.append(",").appen d((int) event.getY(i)); if (i + 1 < event.getPointerCount()) { sb.append(";"); } } sb.append("]"); Log.d(Cocos2dxGLSu rfaceView.TAG, sb.toString()); } } Cocos2dxHandler.java package org.cocos2dx.lib; import java.lang.ref.WeakReference; import android.app.AlertDialog; import android.content.DialogInterf ace; import android.os.Handler; import android.os.Message; public class Cocos2dxHandler extends Handler { // ======================== ======================== =========== // Constants // ======================== ======================== =========== public final static int HANDLER_SHOW_DIALOG = 1; public final static int HANDLER_SHOW_EDITBOX_ DIALOG = 2; // ======================== ======================== =========== // Fields // ======================== ======================== =========== private WeakReference<Cocos2dxAc tivity> mActivity; // ======================== ======================== =========== // Constructors // ======================== ======================== =========== public Cocos2dxHandler(Cocos2dxA ctivity activity) { // ======================== ======================== =========== public void handleMessage(Message msg) { switch (msg.what) { case Cocos2dxHandler.HANDLER_ SHOW_DIALOG: showDialog(msg); break; this.mActivity = new WeakReference<Cocos2dxAc tivity>(activity); } case Cocos2dxHandler.HANDLER_ SHOW_EDITBOX_DIALOG: // ======================== ======================== =========== // Getter & Setter // ======================== ======================== =========== msg); showEditBoxDialog( // ======================== ======================== =========== // Methods for/from SuperClass/Interfaces // ======================== ======================== =========== // ======================== ======================== =========== // Methods break; } } private void showDialog(Message msg) { Cocos2dxActivity theActivity = this.mActivity.get(); DialogMessage dialogMessage = (DialogMessage)msg.obj; new AlertDialog.Builder(theActivit y) .setTitle(dialogMessa ge.titile) .setMessage(dialogM essage.message) public int .setPositiveButton(" Ok", editBoxMessage.inp inputFlag; utFlag, public int returnType; new DialogInterface.OnClickListen er() { editBoxMessage.retu maxLength; editBoxMessage.max Length).show(); } public EditBoxMessage(String title, String content, int inputMode, int inputFlag, int returnType, int maxLength){ @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub } }).create().show(); } private void showEditBoxDialog(Message msg) { EditBoxMessage editBoxMessage = (EditBoxMessage)msg.obj; new Cocos2dxEditBoxDialog(this. mActivity.get(), editBoxMessage.title public int rnType, // ======================== ======================== =========== // Inner and Anonymous Classes // ======================== ======================== =========== public static class DialogMessage { public String titile; public String message; public DialogMessage(String title, String message) { this.titile = title; this.content = content; this.title = title; this.inputMode = inputMode; this.inputFlag = inputFlag; this.returnType = returnType; this.maxLength = maxLength; } } } Cocos2dxHelper.java package org.cocos2dx.lib; this.message = message; } } import java.io.UnsupportedEncoding Exception; import java.util.Locale; public static class EditBoxMessage { public String title; public String content; public int inputMode; import android.app.Activity; import android.content.Context; import android.content.SharedPrefe rences; , editBoxMessage.con tent, editBoxMessage.inp utMode, import android.content.pm.Applicati onInfo; import android.content.res.AssetMa nager; import android.os.Build; import android.util.DisplayMetrics; import android.view.Display; import android.view.WindowManag er; public class Cocos2dxHelper { // ======================== ======================== =========== // Constants // ======================== ======================== =========== private static final String PREFS_NAME = "Cocos2dxPrefsFile"; // ======================== ======================== =========== // Fields // ======================== ======================== =========== private static Cocos2dxMusic sCocos2dMusic; private static Cocos2dxSound sCocos2dSound; private static AssetManager sAssetManager; private static Cocos2dxAccelerometer sCocos2dxAccelerometer; private static boolean sAccelerometerEnabled; private static String sPackageName; private static String sFileDirectory; private static Context sContext = null; private static Cocos2dxHelperListener sCocos2dxHelperListener; // ======================== ======================== =========== // Constructors // ======================== ======================== =========== applicationInfo.packageNam e; Cocos2dxHelper.sFile Directory = pContext.getFilesDir().getAbs olutePath(); Cocos2dxHelper.nati veSetApkPath(applicationInf o.sourceDir); Cocos2dxHelper.sCoc os2dxAccelerometer = new Cocos2dxAccelerometer(pCo ntext); Cocos2dxHelper.sCoc os2dMusic = new Cocos2dxMusic(pContext); Cocos2dxHelper.sCoc os2dSound = new Cocos2dxSound(pContext); public static void init(final Context pContext, final Cocos2dxHelperListener pCocos2dxHelperListener) { final ApplicationInfo applicationInfo = pContext.getApplicationInfo( ); Cocos2dxHelper.sAss etManager = pContext.getAssets(); Cocos2dxHelper.sCo ntext = pContext; Cocos2dxBitmap.set Context(pContext); Cocos2dxHelper.sCoc os2dxHelperListener = pCocos2dxHelperListener; Cocos2dxETCLoader. setContext(pContext); } Cocos2dxHelper.sPac kageName = // ======================== ======================== =========== Cocos2dxHelper.nati veSetContext((Context)pCont ext, Cocos2dxHelper.sAssetMana ger); // Getter & Setter // ======================== ======================== =========== // ======================== ======================== =========== // Methods for/from SuperClass/Interfaces // ======================== ======================== =========== // ======================== ======================== =========== // Methods // ======================== ======================== =========== private static native void nativeSetApkPath(final String pApkPath); private static native void nativeSetEditTextDialogResul t(final byte[] pBytes); private static native void nativeSetContext(final Context pContext, final AssetManager pAssetManager); public static String getCocos2dxPackageName() { return Cocos2dxHelper.sPackageNa me; } public static void onNativeInitStatic(){ Cocos2dxHelper.sCoc os2dxHelperListener.onNativ eInit(); } public static String getCocos2dxWritablePath() { return Cocos2dxHelper.sFileDirector y; } public static String getCurrentLanguage() { return Locale.getDefault().getLangu age(); } public static String getDeviceModel(){ return Build.MODEL; } public static AssetManager getAssetManager() { return Cocos2dxHelper.sAssetMana ger; } public static void setAccelerometerInterval(flo at interval) { Cocos2dxHelper.sCoc os2dxAccelerometer.setInter val(interval); } public static void disableAccelerometer() { Cocos2dxHelper.sAcc elerometerEnabled = false; Cocos2dxHelper.sCoc os2dxAccelerometer.disable( ); } public static void preloadBackgroundMusic(fin al String pPath) { Cocos2dxHelper.sCoc os2dMusic.preloadBackgrou ndMusic(pPath); } public static void playBackgroundMusic(final String pPath, final boolean isLoop) { public static void enableAccelerometer() { Cocos2dxHelper.sCoc os2dMusic.playBackgroundM usic(pPath, isLoop); } Cocos2dxHelper.sAcc elerometerEnabled = true; public static void resumeBackgroundMusic() { Cocos2dxHelper.sCoc os2dxAccelerometer.enable() ; } Cocos2dxHelper.sCoc os2dMusic.resumeBackgroun dMusic(); } } public static void pauseBackgroundMusic() { Cocos2dxHelper.sCoc os2dMusic.pauseBackground Music(); } public static void stopBackgroundMusic() { Cocos2dxHelper.sCoc os2dMusic.stopBackground Music(); } public static void rewindBackgroundMusic() { Cocos2dxHelper.sCoc os2dMusic.rewindBackgroun dMusic(); } public static boolean isBackgroundMusicPlaying() { return Cocos2dxHelper.sCocos2dM usic.isBackgroundMusicPlayi ng(); } public static void preloadEffect(final String path) { Cocos2dxHelper.sCoc os2dSound.preloadEffect(pat h); } public static int playEffect(final String path, final boolean isLoop) { return Cocos2dxHelper.sCocos2dSo und.playEffect(path, isLoop, 1, 0, 1); } public static void resumeEffect(final int soundId) { Cocos2dxHelper.sCoc os2dSound.resumeEffect(sou ndId); } return Cocos2dxHelper.sCocos2dSo und.getEffectsVolume(); } public static void setEffectsVolume(final float volume) { Cocos2dxHelper.sCoc os2dSound.setEffectsVolume (volume); } public static void unloadEffect(final String path) { Cocos2dxHelper.sCoc os2dSound.unloadEffect(pat h); } public static void pauseAllEffects() { Cocos2dxHelper.sCoc os2dSound.pauseAllEffects(); } public static void pauseEffect(final int soundId) { public static void resumeAllEffects() { public static float getBackgroundMusicVolume( ){ return Cocos2dxHelper.sCocos2dM usic.getBackgroundVolume(); } Cocos2dxHelper.sCoc os2dSound.pauseEffect(soun dId); } Cocos2dxHelper.sCoc os2dSound.resumeAllEffects( ); } public static void stopEffect(final int soundId) { public static void stopAllEffects() { public static void setBackgroundMusicVolume( final float volume) { Cocos2dxHelper.sCoc os2dSound.stopEffect(soundI d); } Cocos2dxHelper.sCoc os2dSound.stopAllEffects(); } Cocos2dxHelper.sCoc os2dMusic.setBackgroundVol ume(volume); public static void public static float getEffectsVolume() { end() { } Cocos2dxHelper.sCoc os2dMusic.end(); Cocos2dxHelper.sCoc os2dSound.end(); } public static void onResume() { if (Cocos2dxHelper.sAccelerom eterEnabled) { Cocos2dxHelper.sCoc os2dxAccelerometer.enable() ; } } public static void onPause() { if (Cocos2dxHelper.sAccelerom eterEnabled) { Cocos2dxHelper.sCoc os2dxAccelerometer.disable( ); } } /* Nothing. */ private static void showEditTextDialog(final String pTitle, final String pMessage, final int pInputMode, final int pInputFlag, final int pReturnType, final int pMaxLength) { Cocos2dxHelper.sCoc os2dxHelperListener.showEd itTextDialog(pTitle, pMessage, pInputMode, pInputFlag, pReturnType, pMaxLength); } public static void setEditTextDialogResult(final String pResult) { try { final byte[] bytesUTF8 = pResult.getBytes("UTF8"); } } public static int getDPI() { if (sContext != null) { DisplayMetrics metrics = new DisplayMetrics(); WindowManager wm = ((Activity)sContext).getWind owManager(); if (wm != null) { Display d = wm.getDefaultDisplay(); if (d != null) Cocos2dxHelper.sCoc os2dxHelperListener.runOnG LThread(new Runnable() { { d.getMetrics(metrics public static void terminateProcess() { android.os.Process.ki llProcess(android.os.Process. myPid()); } private static void showDialog(final String pTitle, final String pMessage) { Cocos2dxHelper.sCoc os2dxHelperListener.showDi alog(pTitle, pMessage); @Override ); public void run() { return (int)(metrics.density*160.0f); Cocos2dxHelper.nati veSetEditTextDialogResult(by tesUTF8); } } } } return -1; } }); } catch (UnsupportedEncodingExcep tion pUnsupportedEncodingExcep tion) { // ======================== ======================== =========== // Functions for CCUserDefault // ======================== ======================== =========== public static boolean getBoolForKey(String key, boolean defaultValue) { SharedPreferences settings = ((Activity)sContext).getShare dPreferences(Cocos2dxHelpe r.PREFS_NAME, 0); return settings.getBoolean(key, defaultValue); } public static int getIntegerForKey(String key, int defaultValue) { SharedPreferences settings = ((Activity)sContext).getShare dPreferences(Cocos2dxHelpe r.PREFS_NAME, 0); return settings.getInt(key, defaultValue); } public static float getFloatForKey(String key, float defaultValue) { SharedPreferences settings = ((Activity)sContext).getShare dPreferences(Cocos2dxHelpe r.PREFS_NAME, 0); return settings.getFloat(key, defaultValue); } public static double getDoubleForKey(String key, double defaultValue) { // SharedPreferences doesn't support saving double value SharedPreferences settings = ((Activity)sContext).getShare dPreferences(Cocos2dxHelpe r.PREFS_NAME, 0); return settings.getFloat(key, (float)defaultValue); } public static void setIntegerForKey(String key, int value) { SharedPreferences settings = ((Activity)sContext).getShare dPreferences(Cocos2dxHelpe r.PREFS_NAME, 0); public static String getStringForKey(String key, String defaultValue) { SharedPreferences settings = ((Activity)sContext).getShare dPreferences(Cocos2dxHelpe r.PREFS_NAME, 0); return settings.getString(key, defaultValue); } public static void setFloatForKey(String key, float value) { SharedPreferences settings = ((Activity)sContext).getShare dPreferences(Cocos2dxHelpe r.PREFS_NAME, 0); public static void setBoolForKey(String key, boolean value) { SharedPreferences settings = ((Activity)sContext).getShare dPreferences(Cocos2dxHelpe r.PREFS_NAME, 0); SharedPreferences.E ditor editor = settings.edit(); editor.putBoolean(ke y, value); editor.commit(); } SharedPreferences.E ditor editor = settings.edit(); editor.putInt(key, value); editor.commit(); } SharedPreferences.E ditor editor = settings.edit(); editor.putFloat(key, value); editor.commit(); } public static void setDoubleForKey(String key, double value) { // SharedPreferences doesn't support recording double value SharedPreferences settings = ((Activity)sContext).getShare dPreferences(Cocos2dxHelpe r.PREFS_NAME, 0); SharedPreferences.E ditor editor = settings.edit(); editor.putFloat(key, (float)value); editor.commit(); } public static void setStringForKey(String key, String value) { SharedPreferences settings = ((Activity)sContext).getShare dPreferences(Cocos2dxHelpe r.PREFS_NAME, 0); SharedPreferences.E ditor editor = settings.edit(); editor.putString(key, value); editor.commit(); } // ======================== ======================== =========== // Inner and Anonymous Classes // ======================== ======================== =========== public static interface Cocos2dxHelperListener { public void showDialog(final String pTitle, final String pMessage); public void showEditTextDialog(final String pTitle, final String pMessage, final int pInputMode, final int pInputFlag, final int pReturnType, final int pMaxLength); public void onNativeInit(); public void runOnGLThread(final Runnable pRunnable); } } Cocos2dxLocalStorage.java package org.cocos2dx.lib; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLit eDatabase; import android.database.sqlite.SQLit eOpenHelper; import android.util.Log; public class Cocos2dxLocalStorage { private static final String TAG = "Cocos2dxLocalStorage"; * @return */ public static boolean init(String dbName, String tableName) { if (Cocos2dxActivity.getContext () != null) { DATABASE_NAME = dbName; TABLE_NAME = tableName; mDatabaseOpenHelp er = new DBOpenHelper(Cocos2dxActi vity.getContext()); mDatabase = mDatabaseOpenHelper.getW ritableDatabase(); return true; } return false; } public static void destory() private static String DATABASE_NAME = "jsb.sqlite"; private static String TABLE_NAME = "data"; private static final int DATABASE_VERSION = 1; { private static DBOpenHelper mDatabaseOpenHelper = null; private static SQLiteDatabase mDatabase = null; /** * Constructor * @param context The Context within which to work, used to create the DB public static void setItem(String key, String value) { try { String sql = "replace into "+TABLE_NAME+"(key,value) values(?,?)"; if (mDatabase != null) { mDatabase.close(); } } mDatabase.execSQL( sql, new Object[] { key, value }); } catch (Exception e) { e.printStackTrace(); } mDatabase.execSQL( sql, new Object[] {key}); } catch (Exception e) { } public static String getItem(String key) { String ret = null; try { String sql = "select value from "+TABLE_NAME+" where key=?"; Cursor c = mDatabase.rawQuery(sql, new String[]{key}); while (c.moveToNext()) { // only return the first value if (ret != null) { Log.e(TAG, "The key contains more than one value."); break; } ret = c.getString(c.getColumnInde x("value")); } c.close(); } catch (Exception e) { e.printStackTrace(); } return ret == null ? "" : ret; } public static void removeItem(String key) { try { String sql = "delete from "+TABLE_NAME+" where key=?"; e.printStackTrace(); } } /** * This creates/opens the database. */ private static class DBOpenHelper extends SQLiteOpenHelper { DBOpenHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE IF NOT EXISTS "+TABLE_NAME+"(key TEXT PRIMARY KEY,value TEXT);"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data"); //db.execSQL("DROP TABLE IF EXISTS " + VIRTUAL_TABLE); //onCreate(db); } } } Cocos2dxMusic.java package org.cocos2dx.lib; import java.io.FileInputStream; import android.content.Context; import android.content.res.AssetFile Descriptor; import android.media.MediaPlayer; import android.util.Log; public class Cocos2dxMusic { // ======================== ======================== =========== // Constants // ======================== ======================== =========== private static final String TAG = Cocos2dxMusic.class.getSim pleName(); // ======================== ======================== =========== // Fields // ======================== ======================== =========== private final Context mContext; private MediaPlayer mBackgroundMediaPlayer; private float mLeftVolume; private float mRightVolume; private boolean mPaused; // whether music is paused state. private boolean mIsLoop = false; private boolean mManualPaused = false; // whether music is paused manually before the program is switched to the background. private String mCurrentPath; // ======================== ======================== =========== // Methods for/from SuperClass/Interfaces // ======================== ======================== =========== // ======================== ======================== =========== // Constructors // ======================== ======================== =========== public void preloadBackgroundMusic(fin al String path) { if ((this.mCurrentPath == null) || (!this.mCurrentPath.equals(p ath))) { // preload new background music public Cocos2dxMusic(final Context context) { this.mContext = context; // release old resource and create a new one if (this.mBackgroundMediaPlay er != null) { this.initData(); // ======================== ======================== =========== // Methods // ======================== ======================== =========== } // ======================== ======================== =========== // Getter & Setter // ======================== ======================== =========== this.mBackgroundMediaPlay er.release(); } this.mCurrentPath = path; } } public void playBackgroundMusic(final String path, final boolean isLoop) { if (mCurrentPath == null) { // it is the first time to play background music or end() was called mBackgroundMediaPlayer = createMediaplayer(path); mCurrentPath = path; } else { if (!mCurrentPath.equals(path) ){ // play new background music // release old resource and create a new one if (mBackgroundMediaPlayer != null) { mBackgroundMediaPlayer.re lease(); } mBackgroundMediaPlayer = createMediaplayer(path); // record the path mCurrentPath = path; this.mBackgroundMediaPlay er = this.createMediaplayer(path) ; // record the path } } if (mBackgroundMediaPlayer == null) { } Log.e(Cocos2dxMusic.TAG, "playBackgroundMusic: background media player is null"); } else { try { // if the music is playing or paused, stop it if (mPaused) { mBackgroundMediaPlayer.se ekTo(0); mBackgroundMediaPlayer.st art(); } else if (mBackgroundMediaPlayer.is Playing()) { mBackgroundMediaPlayer.se ekTo(0); } else { mBackgroundMediaPlayer.st art(); } mBackgroundMediaP layer.release(); mBackgroundMediaP layer = createMediaplayer(mCurrent Path); /** * should set the state, if not, the following sequence will be error * play -> pause -> stop -> resume */ this.mPaused = false; } } public void pauseBackgroundMusic() { if (this.mBackgroundMediaPlay er != null && this.mBackgroundMediaPlay er.isPlaying()) { public void rewindBackgroundMusic() { if (this.mBackgroundMediaPlay er != null) { playBackgroundMusi c(mCurrentPath, mIsLoop); } } public boolean isBackgroundMusicPlaying() { boolean ret = false; if (this.mBackgroundMediaPlay er == null) { ret = false; } else { ret = this.mBackgroundMediaPlay er.isPlaying(); } return ret; mBackgroundMediaPlayer.se tLooping(isLoop); mPaused = false; mIsLoop = isLoop; } catch (final Exception e) { Log.e(Cocos2dxMusic.TAG, "playBackgroundMusic: error state"); } } } public void stopBackgroundMusic() { if (this.mBackgroundMediaPlay er != null) { this.mBackgroundMediaPlay er.pause(); this.mPaused = true; this.mManualPaused = true; } } public void resumeBackgroundMusic() { if (this.mBackgroundMediaPlay er != null && this.mPaused) { this.mBackgroundMediaPlay er.start(); this.mPaused = false; this.mManualPaused = false; } } public void end() { if (this.mBackgroundMediaPlay er != null) { this.mBackgroundMediaPlay er.release(); } this.initData(); } public float getBackgroundVolume() { if (this.mBackgroundMediaPlay er != null) { return (this.mLeftVolume + this.mRightVolume) / 2; } else { return 0.0f; } } public void setBackgroundVolume(float volume) { if (volume < 0.0f) { volume = 0.0f; } if (volume > 1.0f) { volume = 1.0f; } if(!this.mManualPaused){ if (this.mBackgroundMediaPlay er != null && this.mPaused) { this.mBackgroundMediaPlay er.start(); this.mPaused = false; } } } private void initData() { this.mLeftVolume = 0.5f; this.mRightVolume = 0.5f; this.mLeftVolume = this.mRightVolume = volume; if (this.mBackgroundMediaPlay er != null) { this.mBackgroundMediaPlay er = null; this.mPaused = false; this.mCurrentPath = null; } this.mBackgroundMediaPlay er.setVolume(this.mLeftVolu me, this.mRightVolume); } } /** * create mediaplayer for music * * @param pPath * the pPath relative to assets * @return */ private MediaPlayer createMediaplayer(final String path) { MediaPlayer mediaPlayer = new MediaPlayer(); public void onEnterBackground(){ if (this.mBackgroundMediaPlay er != null && this.mBackgroundMediaPlay er.isPlaying()) { this.mBackgroundMediaPlay er.pause(); this.mPaused = true; } } public void onEnterForeground(){ try { if (path.startsWith("/")) { final FileInputStream fis = new FileInputStream(path); mediaPlayer.setDataSource(f is.getFD()); fis.close(); } else { final AssetFileDescriptor assetFileDescritor = this.mContext.getAssets().op enFd(path); mediaPlayer.setDataSource( assetFileDescritor.getFileDes criptor(), assetFileDescritor.getStartOf fset(), assetFileDescritor.getLength( )); } mediaPlayer.prepare(); mediaPlayer.setVolume(this. mLeftVolume, this.mRightVolume); } catch (final Exception e) { mediaPlayer = null; Log.e(Cocos2dxMusic.TAG, "error: " + e.getMessage(), e); } return mediaPlayer; } // ======================== ======================== =========== // Inner and Anonymous Classes // ======================== ======================== =========== } Cocos2dxReflectionHelper.ja va Log.e("error", "can not get constant" + constantName); } return null; package org.cocos2dx.lib; import android.util.Log; import java.lang.reflect.InvocationTa rgetException; import java.lang.reflect.Method; } public static <T> T invokeInstanceMethod(final Object instance, final String methodName, final Class[] parameterTypes, final Object[] parameters) { catch (InvocationTargetException e) { Log.e("error", "an exception was thrown by the invoked method when invoking " + methodName); } return null; } } Cocos2dxRenderer.java package org.cocos2dx.lib; import android.util.Log; public class Cocos2dxReflectionHelper { public static <T> T getConstantValue(final Class aClass, final String constantName) { try { return (T)aClass.getDeclaredField(co nstantName).get(null); } catch (NoSuchFieldException e) { Log.e("error", "can not find " + constantName + " in " + aClass.getName()); } catch (IllegalAccessException e) { Log.e("error", constantName + " is not accessable"); } catch (IllegalArgumentException e) { Log.e("error", "arguments error when get " + constantName); } catch (Exception e) { final Class aClass = instance.getClass(); try { final Method method = aClass.getMethod(methodNa me, parameterTypes); return (T)method.invoke(instance, parameters); } catch (NoSuchMethodException e) { Log.e("error", "can not find " + methodName + " in " + aClass.getName()); } catch (IllegalAccessException e) { Log.e("error", methodName + " is not accessible"); } catch (IllegalArgumentException e) { Log.e("error", "arguments are error when invoking " + methodName); } import javax.microedition.khronos.e gl.EGLConfig; import javax.microedition.khronos.o pengles.GL10; import android.opengl.GLSurfaceVie w; public class Cocos2dxRenderer implements GLSurfaceView.Renderer { // ======================== ======================== =========== // Constants // ======================== ======================== =========== private final static long NANOSECONDSPERSECOND = 1000000000L; private final static long NANOSECONDSPERMICROSE COND = 1000000; private static long sAnimationInterval = (long) (1.0 / 60 * Cocos2dxRenderer.NANOSEC ONDSPERSECOND); // ======================== ======================== =========== // Fields // ======================== ======================== =========== private long mLastTickInNanoSeconds; private int mScreenWidth; private int mScreenHeight; // ======================== ======================== =========== // Constructors // ======================== ======================== =========== // ======================== ======================== =========== // Getter & Setter // ======================== ======================== =========== public static void setAnimationInterval(final double pAnimationInterval) { Cocos2dxRenderer.s AnimationInterval = (long) (pAnimationInterval * Cocos2dxRenderer.NANOSEC ONDSPERSECOND); } public void setScreenWidthAndHeight(fi nal int pSurfaceWidth, final int pSurfaceHeight) { this.mScreenWidth = pSurfaceWidth; this.mScreenHeight = pSurfaceHeight; } // ======================== ======================== =========== // Methods for/from SuperClass/Interfaces // ======================== ======================== =========== @Override public void onSurfaceCreated(final GL10 pGL10, final EGLConfig pEGLConfig) { Cocos2dxRenderer.n ativeInit(this.mScreenWidth, this.mScreenHeight); this.mLastTickInNano Seconds = System.nanoTime(); } @Override public void onSurfaceChanged(final GL10 pGL10, final int pWidth, final int pHeight) { Log.d("RENDERER", "Surface changed: " + pWidth + " " + pHeight); Cocos2dxRenderer.n ativeOnSurfaceChanged(pWi dth, pHeight); } @Override public void onDrawFrame(final GL10 gl) { /* * FPS controlling algorithm is not accurate, and it will slow down FPS * on some devices. So comment FPS controlling code. */ /* final long nowInNanoSeconds = System.nanoTime(); final long interval = nowInNanoSeconds this.mLastTickInNanoSecond s; */ // should render a frame when onDrawFrame() is called or there is a // "ghost" Cocos2dxRenderer.n ativeRender(); /* // fps controlling if (interval < Cocos2dxRenderer.sAnimatio nInterval) { try { // because we render it before, so we should sleep twice time interval Thread.sleep((Cocos 2dxRenderer.sAnimationInte rval - interval) / Cocos2dxRenderer.NANOSEC ONDSPERMICROSECOND); } catch (final Exception e) { } } this.mLastTickInNano Seconds = nowInNanoSeconds; */ } // ======================== ======================== =========== // Methods // ======================== ======================== =========== private static native void nativeTouchesBegin(final int pID, final float pX, final float pY); private static native void nativeTouchesEnd(final int pID, final float pX, final float pY); private static native void nativeTouchesMove(final int[] pIDs, final float[] pXs, final float[] pYs); private static native void nativeTouchesCancel(final int[] pIDs, final float[] pXs, final float[] pYs); private static native boolean nativeKeyDown(final int pKeyCode); private static native boolean nativeKeyUp(final int pKeyCode); private static native void nativeRender(); private static native void nativeInit(final int pWidth, final int pHeight); private static native void nativeOnSurfaceChanged(fin al int width, final int height); private static native void nativeOnPause(); private static native void nativeOnResume(); public void handleActionDown(final int pID, final float pX, final float pY) { Cocos2dxRenderer.n ativeTouchesBegin(pID, pX, pY); } public void handleActionUp(final int pID, final float pX, final float pY) { Cocos2dxRenderer.n ativeTouchesEnd(pID, pX, pY); } public void handleActionCancel(final int[] pIDs, final float[] pXs, final float[] pYs) { Cocos2dxRenderer.n ativeTouchesCancel(pIDs, pXs, pYs); } public void handleActionMove(final int[] pIDs, final float[] pXs, final float[] pYs) { Cocos2dxRenderer.n ativeTouchesMove(pIDs, pXs, pYs); } public void handleKeyDown(final int pKeyCode) { Cocos2dxRenderer.n ativeKeyDown(pKeyCode); } public void handleKeyUp(final int pKeyCode) { Cocos2dxRenderer.n ativeKeyUp(pKeyCode); } public void handleOnPause() { Cocos2dxRenderer.n ativeOnPause(); } public void handleOnResume() { Cocos2dxRenderer.n ativeOnResume(); } private static native void nativeInsertText(final String pText); private static native void nativeDeleteBackward(); private static native String nativeGetContentText(); public void handleInsertText(final String pText) { Cocos2dxRenderer.n ativeInsertText(pText); } public void handleDeleteBackward() { Cocos2dxRenderer.n ativeDeleteBackward(); } public String getContentText() { return Cocos2dxRenderer.nativeGet ContentText(); } // ======================== ======================== =========== // Inner and Anonymous Classes // ======================== ======================== =========== } Cocos2dxSound.java package org.cocos2dx.lib; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.Concurre ntHashMap; import android.content.Context; import android.media.AudioManage r; import android.media.SoundPool; import android.util.Log; public class Cocos2dxSound { // ======================== ======================== =========== // Constants // ======================== ======================== =========== private static final String TAG = "Cocos2dxSound"; // ======================== ======================== =========== // Fields // ======================== ======================== =========== private final Context mContext; private SoundPool mSoundPool; private float mLeftVolume; private float mRightVolume; // sound path and stream ids map // a file may be played many times at the same time // so there is an array map to a file path private final HashMap<String, ArrayList<Integer>> mPathStreamIDsMap = new HashMap<String, ArrayList<Integer>>(); private final HashMap<String, Integer> mPathSoundIDMap = new HashMap<String, Integer>(); private ConcurrentHashMap<Integer , SoundInfoForLoadedComplet ed> mPlayWhenLoadedEffects = new ConcurrentHashMap<Integer , SoundInfoForLoadedComplet ed>(); private static final int MAX_SIMULTANEOUS_STRE AMS_DEFAULT = 5; private static final int MAX_SIMULTANEOUS_STRE AMS_I9100 = 3; private static final float SOUND_RATE = 1.0f; private static final int SOUND_PRIORITY = 1; private static final int SOUND_QUALITY = 5; private final static int INVALID_SOUND_ID = -1; private final static int INVALID_STREAM_ID = -1; // ======================== ======================== =========== // Constructors // ======================== ======================== =========== public Cocos2dxSound(final Context context) { this.mContext = context; this.initData(); } private void initData() { if (Cocos2dxHelper.getDevice Model().contains("GTI9100")) { this.mSoundPool = new SoundPool(Cocos2dxSound. MAX_SIMULTANEOUS_STRE AMS_I9100, AudioManager.STREAM_MU SIC, Cocos2dxSound.SOUND_QU ALITY); } else { this.mSoundPool = new SoundPool(Cocos2dxSound. MAX_SIMULTANEOUS_STRE AMS_DEFAULT, AudioManager.STREAM_MU SIC, Cocos2dxSound.SOUND_QU ALITY); } this.mSoundPool.setOnLoad CompleteListener(new OnLoadCompletedListener()) ; this.mLeftVolume = 0.5f; this.mRightVolume = 0.5f; } public int preloadEffect(final String path) { Integer soundID = this.mPathSoundIDMap.get( path); if (soundID == null) { soundID = this.createSoundIDFromAsse t(path); // save value just in case if file is really loaded if (soundID != Cocos2dxSound.INVALID_SO UND_ID) { this.mPathSoundIDMap.put( path, soundID); } } return soundID; } public void unloadEffect(final String path) { // stop effects final ArrayList<Integer> streamIDs = this.mPathStreamIDsMap.get (path); if (streamIDs != null) { for (final Integer steamID : streamIDs) { this.mSoundPool.stop(steamI D); } } this.mPathStreamIDsMap.re move(path); // unload effect final Integer soundID = this.mPathSoundIDMap.get( path); if(soundID != null){ this.mSoundPool.unload(sou ndID); this.mPathSoundIDMap.rem ove(path); } } private static int LOAD_TIME_OUT = 500; public int playEffect(final String path, final boolean loop, float pitch, float pan, float gain){ Integer soundID = this.mPathSoundIDMap.get( path); int streamID = Cocos2dxSound.INVALID_ST REAM_ID; if (soundID != null) { // parameters; pan = 1 for left channel, 1 for right channel, 0 for both channels // play sound streamID = this.doPlayEffect(path, soundID, loop, pitch, pan, gain); } else { // the effect is not prepared soundID = this.preloadEffect(path); if (soundID == Cocos2dxSound.INVALID_SO UND_ID) { // can not preload effect return Cocos2dxSound.INVALID_SO UND_ID; } SoundInfoForLoadedComplet ed info = new SoundInfoForLoadedComplet ed(path, loop, pitch, pan, gain); mPlayWhenLoadedEffects.pu tIfAbsent(soundID, info); synchronized(info) { try { info.wait(LOAD_TIME_OUT); } catch(Exception e) { e.printStackTrace(); } } streamID = info.effectID; mPlayWhenLoadedEffects.re move(soundID); } return streamID; } public void stopEffect(final int steamID) { this.mSoundPool.stop(steamI D); // remove record for (final String pPath : this.mPathStreamIDsMap.ke ySet()) { if (this.mPathStreamIDsMap.ge t(pPath).contains(steamID)) { this.mPathStreamIDsMap.get (pPath).remove(this.mPathSt reamIDsMap.get(pPath).inde xOf(steamID)); break; } } } public void pauseEffect(final int steamID) { this.mSoundPool.pause(stea mID); } public void resumeEffect(final int steamID) { this.mSoundPool.resume(ste amID); } public void pauseAllEffects() { if (!this.mPathStreamIDsMap.is Empty()) { final Iterator<Entry<String, ArrayList<Integer>>> iter = this.mPathStreamIDsMap.en trySet().iterator(); while (iter.hasNext()) { final Entry<String, ArrayList<Integer>> entry = iter.next(); for (final int steamID : entry.getValue()) { this.mSoundPool.pause(stea mID); } } } } public void resumeAllEffects() { // can not only invoke SoundPool.autoResume() here, because // it only resumes all effects paused by pauseAllEffects() if (!this.mPathStreamIDsMap.is Empty()) { final Iterator<Entry<String, ArrayList<Integer>>> iter = this.mPathStreamIDsMap.en trySet().iterator(); while (iter.hasNext()) { final Entry<String, ArrayList<Integer>> entry = iter.next(); for (final int steamID : entry.getValue()) { this.mSoundPool.resume(ste amID); } } } } @SuppressWarnings("unche cked") public void stopAllEffects() { // stop effects if (!this.mPathStreamIDsMap.is Empty()) { final Iterator<?> iter = this.mPathStreamIDsMap.en trySet().iterator(); while (iter.hasNext()) { final Map.Entry<String, ArrayList<Integer>> entry = (Map.Entry<String, ArrayList<Integer>>) iter.next(); for (final int steamID : entry.getValue()) { this.mSoundPool.stop(steamI D); } } } // remove records this.mPathStreamIDsMap.cle ar(); } public float getEffectsVolume() { return (this.mLeftVolume + this.mRightVolume) / 2; } public void setEffectsVolume(float volume) { // volume should be in [0, 1.0] if (volume < 0) { volume = 0; } if (volume > 1) { volume = 1; } this.mPathSoundIDMap.clear (); this.mPlayWhenLoadedEffect s.clear(); this.mLeftVolume = 0.5f; this.mRightVolume = 0.5f; this.initData(); } this.mLeftVolume = this.mRightVolume = volume; // change the volume of playing sounds if (!this.mPathStreamIDsMap.is Empty()) { final Iterator<Entry<String, ArrayList<Integer>>> iter = this.mPathStreamIDsMap.en trySet().iterator(); while (iter.hasNext()) { final Entry<String, ArrayList<Integer>> entry = iter.next(); for (final int steamID : entry.getValue()) { this.mSoundPool.setVolume( steamID, this.mLeftVolume, this.mRightVolume); } } } } public void end() { this.mSoundPool.release(); this.mPathStreamIDsMap.cle ar(); public int createSoundIDFromAsset(fin al String path) { int soundID = Cocos2dxSound.INVALID_SO UND_ID; try { if (path.startsWith("/")) { soundID = this.mSoundPool.load(path, 0); } else { soundID = this.mSoundPool.load(this.m Context.getAssets().openFd( path), 0); } } catch (final Exception e) { soundID = Cocos2dxSound.INVALID_SO UND_ID; Log.e(Cocos2dxSound.TAG, "error: " + e.getMessage(), e); } // mSoundPool.load returns 0 if something goes wrong, for example a file does not exist if (soundID == 0) { soundID = Cocos2dxSound.INVALID_SO UND_ID; } return soundID; if (streamIDs == null) { streamIDs = new ArrayList<Integer>(); this.mPathStreamIDsMap.pu t(path, streamIDs); } } streamIDs.add(streamID); private float clamp(float value, float min, float max) { return Math.max(min, (Math.min(value, max))); } private int doPlayEffect(final String path, final int soundId, final boolean loop, float pitch, float pan, float gain) { float leftVolume = this.mLeftVolume * gain * (1.0f - this.clamp(pan, 0.0f, 1.0f)); float rightVolume = this.mRightVolume * gain * (1.0f - this.clamp(-pan, 0.0f, 1.0f)); float soundRate = this.clamp(SOUND_RATE * pitch, 0.5f, 2.0f); // play sound int streamID = this.mSoundPool.play(soundI d, this.clamp(leftVolume, 0.0f, 1.0f), this.clamp(rightVolume, 0.0f, 1.0f), Cocos2dxSound.SOUND_PRI ORITY, loop ? -1 : 0, soundRate); // record stream id ArrayList<Integer> streamIDs = this.mPathStreamIDsMap.get (path); return streamID; } public void onEnterBackground(){ this.mSoundPool.autoPause( ); } public void onEnterForeground(){ this.mSoundPool.autoResum e(); } // ======================== ======================== =========== // Inner and Anonymous Classes // ======================== ======================== =========== public class SoundInfoForLoadedComplet ed { public int effectID; public boolean isLoop; public float pitch; public float pan; public float gain; public String path; public SoundInfoForLoadedComplet ed(String path, boolean isLoop, float pitch, float pan, float gain) { this.path = path; this.isLoop = isLoop; this.pitch = pitch; this.pan = pan; this.gain = gain; effectID = Cocos2dxSound.INVALID_SO UND_ID; } } public class OnLoadCompletedListener implements SoundPool.OnLoadComplete Listener { @Override public void onLoadComplete(SoundPool soundPool, int sampleId, int status) { if (status == 0) { SoundInfoForLoadedComplet ed info = mPlayWhenLoadedEffects.ge t(sampleId); if (info != null) { info.effectID = doPlayEffect(info.path, sampleId, info.isLoop, info.pitch, info.pan, info.gain); synchronized (info) { info.notifyAll(); } } } } } } Cocos2dxTextInputWraper.j ava package org.cocos2dx.lib; import android.content.Context; import android.text.Editable; import android.text.TextWatcher; import android.util.Log; import android.view.KeyEvent; import android.view.inputmethod.E ditorInfo; import android.view.inputmethod.In putMethodManager; import android.widget.TextView; import android.widget.TextView.On EditorActionListener; public class Cocos2dxTextInputWraper implements TextWatcher, OnEditorActionListener { // ======================== ======================== =========== // Constants // ======================== ======================== =========== private static final String TAG = Cocos2dxTextInputWraper.cl ass.getSimpleName(); // ======================== ======================== =========== // Fields // ======================== ======================== =========== private final Cocos2dxGLSurfaceView mCocos2dxGLSurfaceView; private String mText; private String mOriginText; // ======================== ======================== =========== // Constructors // ======================== ======================== =========== public Cocos2dxTextInputWraper(fi nal Cocos2dxGLSurfaceView pCocos2dxGLSurfaceView) { this.mCocos2dxGLSu rfaceView = pCocos2dxGLSurfaceView; } // ======================== ======================== =========== // Getter & Setter // ======================== ======================== =========== private boolean isFullScreenEdit() { final TextView textField = this.mCocos2dxGLSurfaceVie w.getCocos2dxEditText(); final InputMethodManager imm = (InputMethodManager) textField.getContext().getSys temService(Context.INPUT_ METHOD_SERVICE); return imm.isFullscreenMode(); } public void setOriginText(final String pOriginText) { this.mOriginText = pOriginText; } // ======================== ======================== =========== // Methods for/from SuperClass/Interfaces // ======================== ======================== =========== @Override public void afterTextChanged(final Editable s) { if (this.isFullScreenEdit()) { return; } //if (BuildConfig.DEBUG) { //Log.d(TAG, "afterTextChanged: " + s); //} int nModified = s.length() this.mText.length(); if (nModified > 0) { final String insertText = s.subSequence(this.mText.le ngth(), s.length()).toString(); public void beforeTextChanged(final CharSequence pCharSequence, final int start, final int count, final int after) { /* if (BuildConfig.DEBUG) { this.mCocos2dxGLSu rfaceView.insertText(insertT ext); /* if (BuildConfig.DEBUG) { Log.d(TAG, "beforeTextChanged(" + pCharSequence + ")start: " + start + ",count: " + count + ",after: " + after); } */ this.mText = pCharSequence.toString(); } Log.d(TAG, "insertText(" + insertText + ")"); } */ } else { for (; nModified < 0; ++nModified) { this.mCocos2dxGLSu rfaceView.deleteBackward(); @Override public void onTextChanged(final CharSequence pCharSequence, final int start, final int before, final int count) { } this.mOriginText.length(); i > 0; i--) { this.mCocos2dxGLSu rfaceView.deleteBackward(); /* if (BuildConfig.DEBUG) { Log.d(TAG, "deleteBackward"); } */ } String text = pTextView.getText().toString( ); /* If user input nothing, translate "\n" to engine. */ if (text.compareTo("") == 0) { text = "\n"; /* } if (BuildConfig.DEBUG) { Log.d(TAG, "deleteBackward"); } */ } } this.mText = s.toString(); } @Override @Override public boolean onEditorAction(final TextView pTextView, final int pActionID, final KeyEvent pKeyEvent) { if (this.mCocos2dxGLSurfaceVi ew.getCocos2dxEditText() == pTextView && this.isFullScreenEdit()) { // user press the action button, delete all old text and insert new text for (int i = if ('\n' != text.charAt(text.length() - 1)) { text += '\n'; } final String insertText = text; this.mCocos2dxGLSu rfaceView.insertText(insertT ext); /* if (BuildConfig.DEBUG) { Log.d(TAG, "insertText(" + insertText + ")"); } */ } if (pActionID == EditorInfo.IME_ACTION_DON E) { this.mCocos2dxGLSu rfaceView.requestFocus(); } return false; } // ======================== ======================== =========== // Methods // ======================== ======================== =========== // ======================== ======================== =========== // Inner and Anonymous Classes // ======================== ======================== =========== } Cocos2dxTypefaces.java package org.cocos2dx.lib; import java.util.HashMap; import android.content.Context; import android.graphics.Typeface; // ======================== ======================== =========== public class Cocos2dxTypefaces { // ======================== ======================== =========== // Constants // ======================== ======================== =========== // ======================== ======================== =========== // Methods for/from SuperClass/Interfaces // ======================== ======================== =========== // ======================== ======================== =========== // Fields // ======================== ======================== =========== private static final HashMap<String, Typeface> sTypefaceCache = new HashMap<String, Typeface>(); // ======================== ======================== =========== // Constructors // ======================== ======================== =========== // ======================== ======================== =========== // Getter & Setter // ======================== ======================== =========== // Methods // ======================== ======================== =========== public static synchronized Typeface get(final Context pContext, final String pAssetName) { if (!Cocos2dxTypefaces.sTypefa ceCache.containsKey(pAsset Name)) { Typeface typeface = null; if (pAssetName.startsWith("/") ) { typeface = Typeface.createFromFile(pAs setName); } else { typeface = Typeface.createFromAsset(p Context.getAssets(), pAssetName); } Cocos2dxTypefaces.s TypefaceCache.put(pAssetNa me, typeface); } return Cocos2dxTypefaces.sTypefac eCache.get(pAssetName); } // ======================== ======================== =========== // Inner and Anonymous Classes // ======================== ======================== =========== } Main.xml <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://sche mas.android.com/apk/res/an droid" android:id="@+id/main" android:layout_width="fill_p arent" android:layout_height="fill_p arent" android:orientation="vertical "> <org.cocos2dx.lib.Cocos2dxE ditText android:orientation="vertical " android:id="@+id/textField" android:layout_width="matc h_parent" android:layout_height="wra p_content" android:layout_height="matc h_parent"> android:layout_width="fill_p arent" android:background="@null" /> <com.google.android.gms.ad s.adMobView android:id="@+id/ad View" <org.cocos2dx.lib.Cocos2dxG LSurfaceView android:id="@+id/game_gl_s urfaceview" android:layout_width="fill_p arent" android:layout_height="fill_p arent"/> <LinearLayout android:id="@+id/revMobBa nner" android:layout_width="wrap _content" android:layout_height="wra p_content" android:layout_gravity="bott om" android:orientation="horizon tal" > android:layout_width="matc h_parent" android:layout_height="wra p_content" /> </LinearLayout> <!-<com.mopub.mobileads.Mo PubView android:id="@+id/adview" android:layout_width="fill_p arent" android:layout_height="50d p" android:layout_gravity="bott om" > </com.mopub.mobileads.Mo PubView> <com.applovin.adview.AppLo vinAdView </LinearLayout> xmlns:applovin="http://sche <LinearLayout mas.applovin.com/android/1 .0" android:icon="@drawable/ic on" android:id="@+id/ALadview" android:allowBackup="true" android:layout_width="wrap _content" android:layout_height="wra p_content" android:layout_gravity="bott om" android:visibility="visible" applovin:loadAdOnCreate="t rue" /> --> </FrameLayout> Strings.xml <?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">Dawn Woods</string> <string name="app_id"></string> </resources> AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://sche mas.android.com/apk/res/an droid" package="com.hhhhhhhh.hh h" android:versionCode="1" android:versionName="1.0"> <application android:label="@string/app_ name" android:name="android.sup port.multidex.MultiDexAppli cation"> <meta-data android:name="com.google. android.gms.version" android:value="@integer/go ogle_play_services_version" /> <meta-data android:name="com.google. android.gms.games.APP_ID" android:value="@string/app _id" /> <activity android:name=".PTPlayer" android:label="@string/app_ name" android:screenOrientation="l andscape" android:theme="@android:s tyle/Theme.NoTitleBar.Fullsc reen" android:configChanges="orie ntation"> <intent-filter> <action android:name="android.inte nt.action.MAIN" /> <category android:name="android.inte nt.category.LAUNCHER" /> </intent-filter> </activity> <!-- FACEBOOK SDK --><!-<activity android:name="com.faceboo k.ads.InterstitialAdActivity" android:configChanges="key boardHidden|orientation" android:screenOrientation=" portrait"/> --><!-- FACEBOOK SDK --> <!-- ADMOB --><!-<activity android:name="com.google. android.gms.ads.AdActivity" android:configChanges="key board|keyboardHidden|orie ntation|screenLayout|uiMod e|screenSize|smallestScreen Size" android:theme="@android:s tyle/Theme.Translucent" /> --><!-- ADMOB --> <!-- VUNGLE --><!-<activity android:name="com.vungle. publisher.FullScreenAdActivit y" android:configChanges="key boardHidden|orientation|scr eenSize" android:theme="@android:s tyle/Theme.NoTitleBar.Fullsc reen"/> --><!-- VUNGLE --> <!-- HEYZAP --><!-<activity android:name="com.heyzap. sdk.ads.HeyzapInterstitialActi vity" android:configChanges="key boardHidden|orientation|scr eenSize|smallestScreenSize" /> <activity android:name="com.heyzap. sdk.ads.HeyzapVideoActivity " android:configChanges="key boardHidden|orientation|scr eenSize|smallestScreenSize" /> <activity android:name="com.heyzap. sdk.ads.HeyzapProxyActivity" /> <activity android:name="com.heyzap. sdk.ads.VASTActivity" android:configChanges="key boardHidden|orientation|scr eenSize|smallestScreenSize" /> <activity android:name="com.heyzap. sdk.ads.MediationTestActivit y" /> <receiver android:name="com.heyzap. sdk.ads.PackageAddedReceiv er"> <intent-filter> <data android:scheme="package"/ > <action android:name="android.inte nt.action.PACKAGE_ADDED"/ > </intent-filter> </receiver> --><!-- HEYZAP --> <!-- APPLOVIN SDK --><!-<activity android:name="com.applovi n.adview.AppLovinInterstitial Activity" /> <activity android:name="com.applovi n.adview.AppLovinConfirmat ionActivity" /> <meta-data android:name="applovin.sdk. key" android:value="{{AppLovin_S DK_key}}" /> --><!-- APPLOVIN SDK --> <!-- REVMOB --><!-<activity android:name="com.revmob .FullscreenActivity" android:theme="@android:s tyle/Theme.Translucent" android:configChanges="key boardHidden|orientation"> </activity> <meta-data android:name="com.revmob .app.id" android:value="{{RevMobMe diaID}}"/> --><!-- REVMOB --> android:hardwareAccelerate d="true" /> --><!-- INMOBI --> <!-- CHARTBOOST -><!-<activity android:name="com.chartbo ost.sdk.CBImpressionActivity " android:excludeFromRecents ="true" android:theme="@android:s tyle/Theme.Translucent.NoTi tleBar.Fullscreen" android:configChanges="key boardHidden|orientation|scr eenSize"/> --><!-- CHARTBOOST --> </application> <supports-screens android:largeScreens="true" android:smallScreens="true" android:anyDensity="true" <!-- INMOBI --><!-<activity android:name="com.inmobi. rendering.InMobiAdActivity" android:configChanges="key boardHidden|orientation|ke yboard|smallestScreenSize|s creenSize" android:theme="@android:s tyle/Theme.Translucent.NoTi tleBar" android:normalScreens="tru e"/> <!-- INMOBI --><!-<uses-permission android:name="android.per mission.READ_LOGS" /> <uses-permission android:name="android.per mission.VIBRATE"/> <uses-permission android:name="android.per mission.CALL_PHONE" /> <uses-permission android:name="android.per mission.READ_CALENDAR"/> <uses-permission android:name="android.per mission.WRITE_CALENDAR"/ > <uses-permission android:name="android.per mission.RECORD_AUDIO"/> <uses-permission android:name="android.per mission.GET_TASKS" /> <uses-permission android:name="android.per mission.ACCESS_FINE_LOCAT ION" /> <uses-permission android:name="com.google. android.gms.permission.ACTI VITY_RECOGNITION"/> --><!-- INMOBI --> <uses-permission android:name="android.per mission.INTERNET" /> <uses-permission android:name="com.android .vending.BILLING" /> <uses-permission android:name="android.per mission.ACCESS_NETWORK_ STATE" /> <uses-permission android:name="android.per mission.ACCESS_WIFI_STATE "/> <uses-permission android:name="android.per mission.ACCESS_COARSE_LO CATION" /> <uses-permission android:name="android.per mission.WRITE_EXTERNAL_S TORAGE" /> <uses-permission android:name="android.per mission.READ_PHONE_STAT E"/> </manifest> Build.gradle apply plugin: 'com.android.application' android { compileSdkVersion 26 buildToolsVersion "28.0.3" defaultConfig { applicationId "com.hhhhhhhh.hhh" minSdkVersion 16 targetSdkVersion 26 multiDexEnabled true ndk { moduleName "player_shared" } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('prog uard-android.txt'), 'proguardrules.txt' } } dexOptions { javaMaxHeapSize "4g" } } dependencies { implementation 'com.google.android.gms:pla y-services:+' implementation 'com.android.support:multid ex:1.0.3' implementation fileTree(dir: 'libs', include: ['*.jar']) // More deps here // } Lint.xml <?xml version="1.0" encoding="utf-8"?> <lint> </lint> gradle-wrapper.properties #Mon Nov 19 22:22:06 PST 2018 distributionBase=GRADLE_U SER_HOME distributionPath=wrapper/di sts zipStoreBase=GRADLE_USER _HOME zipStorePath=wrapper/dists distributionUrl=https\://servi ces.gradle.org/distributions/ gradle-4.6-all.zip main.ccp #include "PTPAppDelegate.h" #include "cocos2d.h" #include "PTPConfig.h" #include "models/PTModelController. h" #include "PTPSettingsController.h" #include "platform/android/jni/JniHel per.h" #include <jni.h> #include <android/log.h> #include "models/screens/PTModelSc reen.h" #include "models/PTModelAtlas.h" #include "models/PTModelGeneralSet tings.h" #include "models/objects/PTModelAs setCharacter.h" #include "models/objects/PTModelOb jectButtonPurchase.h" #define LOG_TAG "main" #define LOGD(...) __android_log_print(ANDROI D_LOG_DEBUG,LOG_TAG,__ VA_ARGS__) #define ARCHIVE_PASSWORD PTJniHelper_passwordJNI() using namespace cocos2d; extern "C" { jint JNI_OnLoad(JavaVM *vm, void *reserved){ JniHelper::setJavaVM(vm); return JNI_VERSION_1_4; } std::string PTJniHelper_passwordJNI(){ JniMethodInfo methodInfo; if (! JniHelper::getStaticMethodIn fo(methodInfo, "com/secrethq/utils/PTJniHel per", "password", "()Ljava/lang/String;")){ return ""; } jstring returnString = (jstring) methodInfo.env>CallStaticObjectMethod(me thodInfo.classID, methodInfo.methodID); methodInfo.env>DeleteLocalRef(methodInfo. classID); const char *out = methodInfo.env- >GetStringUTFChars(returnSt ring, NULL); methodInfo.env>DeleteLocalRef(returnString ); std::string outString(out); return outString; } void Java_com_secrethq_utils_PT JniHelper_updateScreenGeo metry(JNIEnv* env, jobject thiz, jstring adNetworkNameString ){ PTPAppDelegate::updateScre enGeometry(); } jboolean Java_com_secrethq_utils_PT JniHelper_isAdNetworkActiv e(JNIEnv* env, jobject thiz, jstring adNetworkNameString ){ const char* adNetworkName = env>GetStringUTFChars(adNetw orkNameString, 0); std::string platformName = "Google Play Store"; PTModelController *mc = PTModelController::shared(); PTPSettingsController* sc = PTPSettingsController::share d(); std::vector<PTModelScreenP tr> screensArray = mc>getModels<PTModelScreen >(); if(screensArray.empty() || sc->removeAds()){ return false; } for(int i=0; i < screensArray.size(); i++){ PTModelScreenPtr model = screensArray.at( i ); if(model>adNetworkFullscreen() == adNetworkName){ return true; } if(model>adNetworkBanner() == adNetworkName){ return true; } } // check if this network in backup list // banner std::list<std::string> bannerList = PTModelGeneralSettings::sh ared()->adBannersList( platformName ); std::list<std::string>::const_it erator bannerIterator; for (bannerIterator = bannerList.begin(); bannerIterator != bannerList.end(); ++bannerIterator) { if(strcmp((*bannerIterator).c _str(), adNetworkName) == 0){ PTLog("ad Network (%s) in backup list (banner)", adNetworkName); return true; } } // interstitials std::list<std::string> interstitialList = PTModelGeneralSettings::sh ared()->adInterstitialsList( platformName ); std::list<std::string>::const_it erator interstittialsIterator; for (interstittialsIterator = interstitialList.begin(); interstittialsIterator != interstitialList.end(); ++interstittialsIterator) { if(strcmp((*interstittialsIterat or).c_str(), adNetworkName) == 0){ PTLog("ad Network (%s) in backup list (interstitials)", adNetworkName); return true; } } // check if network is used as reward video std::vector<PTModelObjectB uttonPurchasePtr> buttonsArray = mc>getModels<PTModelObject ButtonPurchase>(); if ( !buttonsArray.empty() ){ for(int i=0; i < buttonsArray.size(); i++){ PTModelObjectButtonPurcha sePtr model = buttonsArray.at( i ); if ( model>purchaseMethod() == "kRewardedVideos" && model>rewardedVideoAdNetwork( ) == adNetworkName) { return true; } } } // check if network is used as reward video std::vector<PTModelAssetCh aracterPtr> charsArray = mc>getModels<PTModelAssetC haracter>(); if ( !charsArray.empty() ){ for(int i=0; i < charsArray.size(); i++){ PTModelAssetCharacterPtr model = charsArray.at( i ); if ( model>purchaseMethod() == "kRewardedVideos" && model>rewardedVideoAdNetwork( ) == adNetworkName) { return true; } } } return false; } void Java_org_cocos2dx_lib_Coco s2dxRenderer_nativeInit(JNI Env* env, jobject thiz, jint w, jint h){ PTModelController *mc = PTModelController::shared(); if (!CCDirector::sharedDirector( )->getOpenGLView()){ CCEGLView *view = CCEGLView::sharedOpenGLVi ew(); view->setFrameSize(w, h); /////////////////////////////// ////// bool bRet = false; unsigned long size = 0; char* pBuffer = (char*)CCFileUtils::sharedFile Utils()>getFileData("data/data.pkg" , "rb", &size); if (pBuffer != NULL && size > 0){ PTLog("data.pkg size: (%lu)", size); mc>setUsingDataEncryption( true ); } std::string path = CCFileUtils::sharedFileUtils()>getWritablePath(); std::string filePath = path + std::string("data.pkg"); FILE *fp = fopen(filePath.c_str(), "wb"); if (! fp){ PTLog("can not create file %s", path.c_str()); return; } fwrite(pBuffer, 1, size, fp); fclose(fp); if ( CCFileUtils::sharedFileUtils()>isFileExist(filePath) ) { PTLog("pkg file is good"); } //loading general info mc->clean(); mc>loadDataForSplashScreen(fil ePath, ARCHIVE_PASSWORD.c_str()) ; PTPAppDelegate *pAppDelegate = new PTPAppDelegate(); pAppDelegate>setDataArchiveProcessor(A RCHIVE_PASSWORD); CCApplication::sharedApplica tion()->run(); //clean up main model controller before starting loading Objects form XML files mc->clean(); } else { PTLog("NATIVE RE INIT"); ccGLInvalidateStateCache(); CCShaderCache::sharedShad erCache()>reloadDefaultShaders(); ccDrawInit(); s2dxRenderer_nativeOnSurfa ceChanged(JNIEnv* env, jobject thiz, jint w, jint h){ auto models = PTModelController::shared()>getModels(PTModelGeneral Settings::staticType()); if(models.size() != 0){ //Checking if there is no PTModelGeneralSettings then we are not ready for reshape (meains we are in the middle of loading process) CCEGLView *glView = CCEGLView::sharedOpenGLVi ew(); CCDirector::sharedDirector()>reshapeProjection(CCSizeM ake(w,h)); glView->setFrameSize(w, h); PTPAppDelegate::updateScre enGeometry(); } } } Android.mk LOCAL_PATH := $(call my-dir) CCTextureCache::reloadAllTe xtures(); include $(CLEAR_VARS) CCNotificationCenter::shared NotificationCenter()>postNotification(EVNET_CO ME_TO_FOREGROUND, NULL); LOCAL_MODULE := player_shared CCDirector::sharedDirector()>setGLDefaultValues(); LOCAL_SRC_FILES := main.cpp } } void Java_org_cocos2dx_lib_Coco LOCAL_WHOLE_STATIC_LIBR ARIES := core_static cocos2dx_static box2d_static LOCAL_MODULE_FILENAME := libplayer GOOGLE_PLAY_STORE := true include $(BUILD_SHARED_LIBRARY) $(call import-module, box2D) $(call import-module, core) $(call import-module, cocos2dx) Application.mk APP_OPTIM := release NDK_TOOLCHAIN_VERSION := clang APP_STL := c++_static APP_CPPFLAGS := -frtti fexceptions -Wformat=0 std=c++11 DGOOGLE_PLAY_STORE fsigned-char -Wnononportable-include-path APP_LDFLAGS := -latomic APP_ABI := armeabi armeabiv7a APP_PLATFORM := android14 dagger-2.7.jar 0000 0000 0000 0000 0000 0900 0000 4d45 5441 2d49 4e46 2f50 4b03 0414 0008 0008 006d 572d 4900 0000 0000 0000 0000 0000 0014 0000 004d 4554 412d 494e 462f 4d41 4e49 4645 5354 2e4d 4645 cdb1 0ac2 3010 80e1 3d90 77b8 1748 8888 28dd 5ab7 42c1 c9fd 68ce 2618 72e5 9206 7d7b 5111 d7ff 1bfe 0973 bc51 a9e6 4a52 22e7 0e76 d669 d5cb 1c62 23f9 e74b a2c7 56e0 075a 9d85 b092 37c3 b383 7ec5 3910 4cd8 28c3 de3a 7bd0 6ad8 62aa 1f15 ce25 e01a 85bf d59b d1df dfa3 9375 6661 5e12 9976 d44a ab17 504b 0708 92ab 04aa 7700 0000 8e00 0000 504b 0304 0a00 0000 0000 6d57 2d49 0000 0000 0000 0000 0000 0000 0700 0000 6461 6767 6572 2f50 4b03 040a 0000 0000 006d 572d 4900 0000 0000 0000 0000 0000 0010 0000 0064 6167 6765 722f 696e 7465 726e 616c 2f50 4b03 040a 0000 0000 006d 572d 4900 0000 0000 0000 0000 0000 0015 0000 0064 6167 6765 722f 6d75 6c74 6962 696e 6469 6e67 732f 504b 0304 1400 0800 0800 6d57 2d49 0000 0000 0000 0000 0000 0000 1500 0000 6461 6767 6572 2f52 6575 7361 626c 652e 636c 6173 7385 8fcd 4a43 410c 854f 5adb a9d5 da2e 74e1 4add 74e9 805b 5782 1604 ffb8 55f7 d369 b84c 99ce 48ef 4cd1 5773 e103 f850 626e 41bb 2934 909c 907c 49c8 f7cf e717 800b 0c14 7a0a 070a 7d42 771c f3c2 f2c8 7926 f40a ce95 9978 3e9f 99a5 211c 1739 2437 e757 5739 a95e 8510 9349 2e86 8a70 7657 33da 9b50 6af3 dfd0 d7d1 e639 87c4 d34b c2e9 66a6 e024 8464 82b4 96c6 6739 3ddc 823e 45ef ec87 0ca8 e2e5 e1f9 f6fe 8670 b81a 79d7 2ecc d826 3db6 f18d 05e8 4f4d 59f2 42ff fd42 18ac 573f 4e6a 9670 b2f1 dafa c121 81d0 106f a2b6 0676 56b1 85b6 e891 5495 6847 fabb 8c2e f6b0 0ffc 0250 4b07 08a7 93c4 0ee0 0000 005f 0100 0050 4b03 0414 0008 0008 006d 572d 4900 0000 0000 0000 0000 0000 0016 0000 0064 6167 6765 722f 436f 6d70 6f6e 656e 742e 636c 6173 7385 925d 4b02 4114 86cf a4b6 6966 5a96 da07 5684 5417 2d74 5b04 a506 421f a25b 105e 8dbb a765 6476 5676 7704 ff5a 17fd 807e 5474 5642 2316 ba98 d9f3 f13e ef30 67f6 f3eb fd03 002e 60cf 80aa 0135 0376 0cd8 6560 dc6a 211d 0c18 e43b 4a61 d094 3c0c 31a4 86e7 3b5a c651 f9e4 7470 3fe2 136e 4aae 5c73 a6b8 6450 ba51 ca8f 7824 7cd5 c237 ae65 c420 db17 aee2 910e 9041 2501 bb3a bb26 32ef e018 9583 ca16 b17f aeef ebc0 c63b 2189 2a34 7d6f ec2b 54d1 79cc 32a8 f5b4 8a84 872f 2214 4389 8b43 893c f8e5 cfe7 0db3 8711 f114 d159 9909 979a 7c1b ff48 bbbe 14f6 9400 a3f7 fc68 751e da0c f693 118b 072e 46a4 3c4a eeb7 257a e469 4dc7 48a2 b4f5 da25 afc3 646d cbb7 752c 4687 a445 87bb 2e06 e67c 0254 5a50 4fc3 11da 54aa 271a 2dc6 c2a0 fad7 e7f8 e78d 1b0c 182c d14a d19f b094 a6bb c20a e559 ca52 03da 7271 1956 a991 4f6c 10b7 368b 0ab0 4edf 3ae5 4572 2b21 6cc0 2694 e370 000c 610b b6a1 4282 e519 4a33 a095 6964 bf01 504b 0708 20bb 6ac8 6501 0000 8302 0000 504b 0304 1400 0800 0800 6d57 2d49 0000 0000 0000 0000 0000 0000 1500 0000 6461 6767 6572 2f50 726f 7669 6465 732e 636c 6173 7385 91df 4a02 5110 c6bf 63ea 9669 6a99 6911 5684 d44d 0bdd 7653 a491 e0bf 6ced a6ab a34e cbca 7a36 76cf 0abe 5a17 3d40 0f15 cd06 26c4 4617 c39c 6fe6 c7cc f09d 8fcf b777 0097 3830 b067 a062 a06a 605f 2069 2d5e 4920 db52 8afc 5b57 0601 055c d5df d5ca d979 7b22 6d9b 7cb3 ef7b 7367 42c1 69c4 5f09 146f 94f2 b4d4 8ea7 1af4 2243 570b 94ff 82d3 c36e eb61 d814 c83c 7aa1 3fa6 3bc7 e5e9 b925 7631 9573 2950 1d84 4a3b 337a 7202 67e4 d26a 011f 74dc 8e18 d395 ca36 e54f c36c 78e3 7046 4ad3 84b7 1cc6 3396 f46d d2dc 4fcd a51b f2de 9378 aee9 5234 6a79 72a7 69dd f71a 0247 f1f4 8034 c3fc 62b6 fe0f d2f7 5c67 bc60 d018 0cbb 56ab c346 e47f 3925 5058 cde8 8da6 3466 3f6b b163 57be 0894 e20c af0b 0824 38d6 f8c3 4592 d762 9dd5 06ab 1421 834d 6e64 5924 90c3 16e7 1aeb 3ce7 0243 c567 08c2 3676 508a 1461 1765 a4b9 9961 99e4 485d 57bf 0050 4b07 08af 188f 3446 0100 004b 0200 0050 4b03 0414 0008 0008 006d 572d 4900 0000 0000 0000 0000 0000 001c 0000 0064 6167 6765 722f 4d65 6d62 6572 7349 6e6a 6563 746f 722e 636c 6173 733b f56f d73e 0606 0623 061e 7606 2e76 066e 4606 decc bcac d4e4 12df d4dc a4d4 a262 4606 510d 9fac c4b2 44fd 9cc4 bc74 7dff 2490 9cb5 6618 2303 6770 667a 5e62 4969 512a 2303 9b46 4808 5850 c326 c40a 53b9 1da6 1023 0357 707e 6951 72aa 5b66 0ed0 0011 a875 9e60 bbf3 8bf4 401a 1819 c452 12d3 d353 8bf4 d164 1919 04d0 0d64 6364 6064 6062 0001 4616 4606 6606 1620 9f15 c863 6260 0362 088b 9d81 034c 7302 0050 4b07 08e1 7cd9 60a0 0000 00f6 0000 0050 4b03 0414 0008 0008 006d 572d 4900 0000 0000 0000 0000 0000 001e 0000 0064 6167 6765 722f 436f 6d70 6f6e 656e 7424 4275 696c 6465 722e 636c 6173 736d 8f4d 4bc3 4010 86df e987 6b63 adf5 e3a0 0711 457a 34e0 b527 ad15 0441 d120 88a7 6d32 8494 cd6e 4936 05ff 9a07 7f80 3f4a 9c5c 5290 2ccc 0733 cfcc 3bfb f3fb f50d e01a 870a bb0a 6385 7d42 f0ea aa22 e6fb cc30 6134 73f9 ca59 b6fe 6aa9 d79a 70f2 5259 9fe5 fc96 95d9 c2f0 8db5 ce6b 9f39 5b12 4e1f 6b26 34da a6a1 6e1a 61a4 8b94 fd94 d05f 6b53 c9d2 8b76 6e6e 3817 a1e8 73c5 02f7 a2f7 e739 e1bc 9dbd 7371 55c3 9c4c 150e 08c7 894e 532e c2e6 dccb db2a 3309 1704 d564 c307 6bb9 9819 5d96 2ce7 8e37 9b9f 164b 8e3d e1ac 556c f349 19fa 2f34 2110 3a62 5dd4 af8b 9ef8 0efa d892 7824 9992 def6 0788 3140 801d a9ee 8905 a8e7 8618 4d06 7f50 4b07 08aa ea05 89f8 0000 0086 0100 0050 4b03 0414 0008 0008 006d 572d 4900 0000 0000 0000 0000 0000 0021 0000 0064 6167 6765 722f 5375 6263 6f6d 706f 6e65 6e74 2442 7569 6c64 6572 2e63 6c61 7373 6d8f 4d4b 0331 1086 dfe9 87b1 6bd5 d67a 1111 51a4 4717 7aed c98f 0a82 a0d8 4510 4fd9 dd61 4949 93b2 9b14 fc6b 1efc 01fe 2831 7b69 3dec c09b 0c99 27f3 cefc fc7e 7d03 9860 24b0 2f30 1018 12a2 b9f5 65c6 0f4a 3361 38f7 6966 972b 6bd8 b8eb 855c 4bc2 c9ab 374e 2df9 4d55 2ad5 7c63 8c75 d229 6b2a c2d9 53cd c45a 9a22 969b 429c c8b2 6037 2574 d752 fbd0 f7b2 999b 695e 06a3 e473 c501 ee24 ef2f 33c2 4533 7b6f 335f c39c 4f05 8e08 a7b9 2c0a 2ee3 ff13 5fdd 7aa5 732e 0962 93f5 1f8d e1f2 4ecb aae2 30f1 60db fc39 5d70 e608 e78d 7edb 3d09 a306 af31 81d0 0a6a a38e 363a e16c a18b 9d70 1f87 4c84 daee 0788 d143 84bd f07a 1814 a1fe d7c7 c1b8 f707 504b 0708 d9cb 77cd fc00 0000 8f01 0000 504b 0304 1400 0800 0800 6d57 2d49 0000 0000 0000 0000 0000 0000 1100 0000 6461 6767 6572 2f4c 617a 792e 636c 6173 733b f56f d73e 0606 0623 061e 7606 2e76 066e 4606 e6f4 d412 4606 110d 4d9f acc4 b244 fd9c c4bc 747d ffa4 acd4 e412 6b46 06ce e0cc f4bc c492 d2a2 5446 0656 0dcd 9010 a098 864d 8815 a65a 3b6c dab9 82f3 4b8b 9253 dd32 7380 fa39 7d12 ab2a f540 aa18 19b8 5312 d3d3 538b f441 428c 0c02 e85a d918 1918 1998 1840 8091 05e8 4406 1620 9f15 c863 6260 0362 088b 9d81 034c 7302 0050 4b07 08e5 eb58 8392 0000 00d4 0000 0050 4b03 0414 0008 0008 006d 572d 4900 0000 0000 0000 0000 0000 0013 0000 0064 6167 6765 722f 4d61 704b 6579 2e63 6c61 7373 8590 4f4b 0251 14c5 cff5 4f53 9aa9 fd83 1661 b590 da34 d0b6 95a0 8194 a3d8 2464 8b78 8eb7 6164 7c23 e31b c3af d6a2 0fd0 878a ae09 b919 68f1 b8f7 727e e7f0 385f df1f 9f00 6e70 6ce1 c0c2 a185 2342 31d1 efb1 9a0d 5498 3021 7b79 3524 541b 5a47 4699 20d2 4d7e 5349 68b2 e223 42e1 314a 628f ef82 50d8 6247 cdee 7979 3d51 0b45 38e9 27da 0453 1e04 f360 14f2 2661 4e38 7f58 3176 a8b4 6fab 3fc1 6e46 5e32 656d 787c 4b38 4d67 5c15 fb6c 44cf 2fd6 3fbc 48e7 5a21 afa2 dce5 8c05 2e37 1ca7 eb36 dc76 d779 759f 7b2d c259 baad cf46 5cb2 89a9 fe0f d28b c2c0 5b0a 68f5 9f1c b7dd 91d4 d258 f93e c7f6 ba09 4265 93d0 1d4d d833 845a 6ae8 a69e 3a81 9091 f75b 718e 9043 5eae 2db9 b243 5822 6dcb 9ac1 0e0a 326b 8215 65ee 0a52 7a01 31f6 5046 6575 31aa d8ff 0150 4b07 084c 14e3 b025 0100 00e3 0100 0050 4b03 0414 0008 0008 006d 572d 4900 0000 0000 0000 0000 0000 0019 0000 0064 6167 6765 722f 5375 6263 6f6d 706f 6e65 6e74 2e63 6c61 7373 8592 4d4f c240 1086 67f9 b082 a820 2822 31a8 3144 3dd8 c4ab c644 0513 123f 08a0 89e1 b4b4 6353 b2dd 25ed 2e09 7fcd 833f c01f 659c 1223 1c9a 7898 ee4c e779 df76 76f7 ebfb e313 002e a06e 41d5 825d 0b6a 16ec 31b0 6e8d 2f5c 0c19 143a 5262 7827 7814 6144 8d40 b946 c459 e5e4 74f8 30e6 536e 0b2e 3d7b 4e5c 3228 dd48 a934 d7be 922d 7ce7 4668 06b9 beef 49ae 4d88 0caa 09b2 abb3 6b52 e6fb ca84 0ede fb82 b052 df8c 1c15 4c94 44a9 cf63 9e41 ad67 a4f6 037c f523 7f24 70f1 21fa 9b83 254f fed7 b07b a849 4f19 f967 a75c 18b2 6efe 8376 95f0 9d19 09ac decb d3a0 f3d8 66b0 9f2c 19f0 d043 4de4 5172 bf2d 3020 cfc1 6c82 0465 066f 5df2 3a4c 665b ca31 318c 2ea1 6597 7b1e 86f6 f226 3028 2e84 cfa3 313a f4aa 91e8 b5d8 1906 f504 abe3 dfd3 6d32 6090 a248 d31d 6019 9a18 56a9 ce51 951e d223 4f91 8235 6a17 e6d9 3a6c d0da a07a 9344 4584 126c 4139 4e87 c010 2ab0 0d3b 04ac cca5 3430 45b6 99fb 0150 4b07 08f2 ed6e 4d5b 0100 0064 0200 0050 4b03 0414 0008 0008 006d 572d 4900 0000 0000 0000 0000 0000 001a 0000 0064 6167 6765 722f 5072 6f76 6964 6573 2454 7970 652e 636c 6173 737d 526b 4f13 5110 3d97 6ebb db65 4ba1 f661 11f1 85da 16a5 5241 d436 0424 3521 a980 d982 69fc 6096 76ad 4b96 add9 b624 26fe 2829 8918 8d86 cffe 28e3 cca5 18aa c5bb c94c ce9d 3333 6766 efcf 5f5f 7f00 28a0 1486 827b 3aee 634e 455a c503 1de3 9867 53d0 30a1 53b0 c08c 871a 12ec 1734 24d9 2f6a 48b1 7fa4 6249 20b4 bdb1 fe72 bb2c a054 3fbc b705 8c75 cfb3 fd35 d76a b7ed b640 b2d2 b09a 4ddb cf6f f9ad 03a7 61b7 6798 5614 0898 e5aa 804e f6cd ce6a 65bb 6cd2 d58b d52d 0175 e60c a75e 5f94 1c3a b0dc 2e97 4f67 b217 9294 b556 8304 452b 8e67 6f74 f777 6dbf 6aed ba74 a3ca eccd b702 b94c 65cf 3ab0 f2ae e535 f366 c777 bc66 317b 51bd 58a5 55b7 dc1d cb77 b84c bf96 e259 fb36 c7fe a943 2a4b 8ee7 7496 6909 43da ac67 7728 bbf3 cea1 29c2 a6d3 f4ac 4ed7 a74a 810c 07b4 52dd ed27 9fcf 2d7b ddfd d270 7dcb 45de 66ab ebd7 ede7 0e2b 8b9c c5e7 38df c065 fec5 6903 8ff1 44c5 5381 f8b0 3206 a651 3470 0b33 0626 1037 9060 9364 9342 5c60 6c50 8b40 b0ee b63c ea16 cf64 cfe9 dcdc ddb3 eb1d 5214 fdab 89c0 e2f9 79e4 3329 0efb 0783 7d8a 2bf3 f4e0 c6e9 d506 57d2 2c0c 209f e8fb 64df a7d8 8f4f f2a4 c454 10c6 24ae 4060 8ad0 4df2 7cf4 1ec4 678c 9c20 f089 90c0 55b2 2119 2b10 7f1a d7fa fc05 8cc8 5b3d a6e4 be20 7802 85f9 2303 fceb 648d 5316 6e50 078e d3e6 c872 8579 04e8 03d4 dcec d431 4287 ff49 5771 9ba5 e38e e4dc 8586 0cd9 5321 1f69 103e d56f 506a 3135 700c ed08 6109 7445 8251 098c a004 1109 c642 1244 d5ef 8402 3d7a 6035 a587 51b3 16ec 2162 d642 3d44 cd23 88c3 3f2b 4822 4876 0911 3ca3 a555 a8fb 2b5a 4181 0638 d594 454e fa59 5c92 e3d2 d345 1eb1 95f4 6f50 4b07 0812 ab33 3460 0200 004d 0400 0050 4b03 0414 0008 0008 006d 572d 4900 0000 0000 0000 0000 0000 0013 0000 0064 6167 6765 722f 4d6f 6475 6c65 2e63 6c61 7373 8591 4d4b 0331 1086 27fd 70fb 61b5 d56a 1111 c543 510f 2e78 5504 d10a 82d5 b25d 05d9 53ba 1d97 946c 5276 9342 ff9a 077f 803f 4a9c 5570 3d2c 7848 f24e 66de 6798 e4e3 f3ed 1d00 cea0 e740 d781 2d07 b619 d484 0aa5 9d62 caa0 7b74 1cdc cff8 82bb 92ab c8bd 963c 4dcf 1974 ae94 d286 1ba1 d50d be72 2b0d 83fa 5844 8a1b 9b20 835e 81ed e2e4 929c add4 4e42 1dcf b542 65a8 4163 ac6d 12e2 ad90 646b 0ef5 d44a 3ccd 9c0c 763c ab8c 88f1 59a4 6222 316f 49b6 833f 74fe 9b70 3d34 8425 459d aa0b 2e2d 41fb ff94 8eb4 14e1 920c 8ef7 f4e0 df0d 070c f68a 2d3e 4f22 3454 7958 9c1f 488c 89e9 2fe7 4845 15ff 6544 acd6 9447 1126 eecf 680c dab9 f571 32c3 905e 6ebf 9096 cfdb 67c0 a044 ab4c 5f55 aa10 1aaa 14af 5054 0e68 73b2 6ba8 51a2 5e98 a0d5 f856 4d58 a573 9754 8b68 6b08 ebd0 864e 2603 6008 1bb0 f905 504b 0708 09f5 1b5c 3601 0000 1002 0000 504b 0304 1400 0800 0800 6d57 2d49 0000 0000 0000 0000 0000 0000 1a00 0000 6461 6767 6572 2f69 6e74 6572 6e61 6c2f 4265 7461 2e63 6c61 7373 858f bb6a 0251 1086 fff1 b66a 6e06 6c52 a98d 650e a44d a531 a904 c38a e9c7 7558 8e1c cf81 f5ac e0ab a5f0 01f2 5021 b329 6223 6460 e61f 986f 6e5f df9f 2700 4fb8 4b70 9de0 26c1 2da1 bb0c 6591 c99b 7542 e84c 25f2 e396 0f4c 7848 4b1f ed4e 3eec deae 9d4c bc0f 91a3 0d7e 4f18 cd2b c638 f6b9 e1bf 8299 85ac dc89 8fb2 7926 0c2f 33a9 4425 3453 a479 6057 eada f13f e87b 7036 3b6a 436b b958 a52f af84 fe86 f35c 0a63 7559 e1d9 99ea 7042 ef3c 67b1 de4a 1609 838b a3cf df8c 0984 9a7a 1d95 d5d0 f88d 4db4 54ef 354b 54db 5aef 08ba b8fa 0150 4b07 08da e884 49d1 0000 0044 0100 0050 4b03 0414 0008 0008 006d 572d 4900 0000 0000 0000 0000 0000 0022 0000 0064 6167 6765 722f 696e 7465 726e 616c 2f53 6574 4661 6374 6f72 7924 312e 636c 6173 738d 52db 4ac3 4010 3d6b 5353 63b4 555b eff7 0bb4 828d fada 2248 5110 ea05 2abe 6fd3 255d 891b 49b7 827f a52f 2a3e f801 7e94 3889 11a5 5531 b033 3b67 cedc b2f3 faf6 fc02 6017 6b16 d298 b130 8b39 0b06 e64d 2c98 5834 b1c4 3058 954a ea3d 8654 b174 c160 d482 9660 c8d6 a512 27dd aba6 08cf 79d3 2764 bc1e b8dc bfe0 a18c ec04 3474 5b76 18ec 23a5 4458 f379 a723 c85c acb7 b8e7 89d0 914a 8b50 71df 6908 7dc8 5d1d 84b7 eb3b 152a e509 cd30 562c d52f f90d 77ba 5ac6 14f2 0c35 a4a7 b8ee 8694 7ca3 d75f fd30 7dae 3ce7 b479 295c 5dd9 a398 fc27 efbb 83e1 ac1f eceb 2b69 aafa 8f3a 5125 ab11 7443 571c ca68 f6ec d750 e588 4fc8 8172 fda0 2395 772c 743b 6899 58b6 6122 6362 c5c6 2a72 36b2 c831 ccff f577 1872 bdc5 19a6 7ee9 9b61 f6f7 5c0c 85af a96a 81ef 532a 1928 7a9f 8cb8 bad6 b7c4 c436 2d43 1ab4 04b4 2529 3ad4 2c59 4374 7348 33d2 e9cd 47b0 7bba 0cc0 2239 1883 9b18 2669 7f10 488f 9266 d170 c48a 82cb 49b0 f184 81bb 9ed8 ad6f b146 123b 1673 c673 fb94 63a2 af81 07a4 7a93 fcd4 8091 a4c9 a310 eb49 4cc5 e834 c911 3a16 b10d 445f e61d 504b 0708 c05b 0eeb 9501 0000 1803 0000 504b 0304 1400 0800 0800 6d57 2d49 0000 0000 0000 0000 0000 0000 2400 0000 6461 6767 6572 2f69 6e74 6572 6e61 6c2f 5072 6f76 6964 6572 4f66 4c61 7a79 2e63 6c61 7373 9554 d952 1351 103d 37db 8461 3021 ac92 208b 8049 5082 881b c448 4cf0 c508 5625 4515 bc58 c364 0c03 6386 9a4c 28f1 1ffc 017e c057 7101 4aaa d437 abfc 28b5 6732 0959 b17c b94b 77df 734e 77df 7b7f fdfe fa0d c002 5679 f4e0 5617 38cc 7188 f170 5636 f33c 6e63 81c3 1d1e 8bb8 cbe1 1e4f c6fb e6f0 80c7 432c 7158 66f0 eeeb da81 9297 7586 a1cc ae78 20be 8929 c55d 5932 622f 6c07 0575 6595 4251 34ca bacc 106a 1f15 cfe5 9613 14da 3725 964a b26e 285a b194 564a e2b6 2ae7 19d8 1683 27ae 1415 23c1 3012 ee40 14d9 6070 a5b4 3cb1 f832 4a51 5e2b bfde 96f5 9c89 c110 c868 92a8 6e88 ba62 ee6d a3cb d851 4a0c e399 bc58 28c8 3a21 1ab2 5e14 d51a e6fa ab8c f8f6 9074 0d36 1e3f dcaf 424c ffe3 6c35 b19e ac21 4a7b cfc5 7deb 1c55 950a ca30 d621 97ca 2933 2167 4136 289f 70a4 ca63 0bea 6fb4 5469 3c92 2e8b 06e9 9aef 58a5 8e6d 7a19 cf2d 59ce 982a 160b b1f5 6d33 6039 71b9 c40e ce56 6d09 5b74 0b01 5da2 b8a4 dacd 7586 cda4 b3ed 95b4 9afe 8b9d cf6a 655d 929f 2a66 dffa 1adb 3467 0209 e847 4440 007d 0cc3 175c c9ea 8d5c d575 4d17 7005 3e0e 7101 8f40 82af 5dde 7e0e 8f05 ac20 c930 d056 aa49 3920 6002 931c 9e08 4821 cde0 6f4e 9321 d8cc 92d6 ca74 8d52 3bb2 b447 d758 2526 8699 ce2d 6fbc 3ba3 ad9a 6549 2be6 15eb d931 0892 89bb a619 6b65 55ad e136 14be 6d1f 7d17 b694 4aef 989e 4d5e 2e29 ba9c af95 905e 8151 2e59 7dde a2ef 85a3 9f87 fe07 38a8 e854 565a fbe9 4b72 a0d7 3f6c b681 d66e da51 8968 1ca4 dd3b 9a1d 3487 a2a7 601f e138 826f f627 bacf e1dc 3c85 eb7b 74f6 0bdc c7e4 7761 88c6 00cd c018 8de3 747a 0241 4c62 982c 8315 0c5c c508 60ad 2adc c106 5fa8 e6eb 25df 28ad 29e6 8f19 c0e1 1a47 b0b0 c58e 939b 1a68 4b4c d38e d1ec 8d7e 86fb 0c9e 0fb4 765a 723c 963d 6a49 102a 31b6 8460 8325 5443 be4e a599 c2b4 8dfc 8c70 cc18 df39 b8cd e819 bc3f d075 0abe 9960 b18e c067 6556 4fe0 b3f2 a912 ccf8 9324 fd06 794c 82a4 2ddd 1d3d 4177 336c b00e d6dd a2db 6deb f622 8c88 0db7 6879 80de 0077 02e1 089c eb3d 5cce 4f70 1c5b dcf5 d0a3 954e 0b2b 8c1c 1569 51cc 5af3 cdbf 504b 0708 313f d9d1 0003 0000 a806 0000 504b 0304 1400 0800 0800 6d57 2d49 0000 0000 0000 0000 0000 0000 1d00 0000 6461 6767 6572 2f69 6e74 6572 6e61 6c2f 4661 6374 6f72 792e 636c 6173 733b f56f d73e 0606 0623 066e 7606 0e76 064e 7606 2e46 06ce e0cc f4bc c492 d2a2 5446 0617 9b10 2b9f acc4 b244 fd9c c4bc 747d ffa4 acd4 e412 6b3b 4c21 b048 857e 661e 88a7 1f50 945f 9699 925a 6413 1262 6d67 cdc8 c015 9c5f 5a94 9cea 9699 0334 93c7 2d31 b924 bfa8 520f a485 9141 3c25 313d 3db5 08a8 b524 b528 2f31 471f 2acd c820 806e 0b23 8328 566b d818 1918 1998 8098 9901 0498 1858 c024 2b03 1b98 6607 0050 4b07 0835 13b6 5ba0 0000 00e7 0000 0050 4b03 0414 0008 0008 006d 572d 4900 0000 0000 0000 0000 0000 0020 0000 0064 6167 6765 722f 696e 7465 726e 616c 2f53 6574 4661 6374 6f72 792e 636c 6173 73ad 57db 5354 751c fffc f6c2 81dd a320 b828 ac98 575c 5610 41a5 c495 4404 5de3 9610 8495 7ad8 3dc2 91c3 593c 7b56 c1ca 7ba6 99dd 7b68 9ae9 c187 7c6a 462b 4372 a669 7a6c a687 7aeb a519 7be9 a57f c0a6 b4ef ef9c b307 f602 d84c 30fb 3bbf dff7 f2f9 7def 7bf6 c747 df7e 07a0 111f f910 c42b 45b4 1c11 70d4 0737 8ef9 b00a 12a7 0cf3 25e6 471c b280 e33e 1461 841f 4605 287e 8838 2160 cc8f a590 3951 f561 1c9a 0f09 4cf8 7112 2a67 e87e 2461 f025 e5c3 299c e657 4d0a 98f2 a102 9280 3302 5e15 f01a 83b0 37a5 a871 5967 10a3 9a26 eb6d aa94 4cca 4986 25ed 5dbd fd43 473b 5adb fa7b 0e0d 3154 74c6 a591 1159 af57 3443 d635 49ad ef90 6246 429f dac5 50d4 a78c 6892 91d2 6586 96f9 e422 9d27 a453 527d ca50 d4fa 3ed9 b08f aaa4 8dd4 f70c 9f90 63c6 ae16 fa67 2853 b4b8 724a 89a7 24b5 574f d046 d6c9 9c92 39da 9d4a d220 c12d 5924 0b71 922e e668 f569 e548 7f7f 1a39 9650 5562 2909 6d0e 72c7 13c2 cc11 6b73 70d2 e01c de2b 8f4f 1853 0cc1 50cd 02b1 f2b4 25e2 14a6 e24e 4593 bb53 e3c3 b2de 2f0d ab44 d91f e96f ce13 93f9 c1b2 03ea f829 0ca7 731a 0a45 a3b9 fa24 6c43 6cb0 b34f 4aa5 9d89 98a4 0e48 bac2 cdb1 6d2a cfcd 459f 7286 182c 4acc dc70 5acc b679 3c79 325b 2c3f 180a 228a a618 2d0c eb43 d9b9 cf3e d70c 505c 8d51 85b2 b96a 811b 08b4 3cd3 cba9 89b4 a76b 17d0 4b5b 743a db90 452a eeff 292c ee9c 7b44 3618 9651 2d64 a49c a76d c282 89cf aa72 2ff3 4192 3453 e813 a30a 9155 795c d60c 9ef6 9c44 512c 9366 1ecb 72b1 29c2 4bd3 d401 494d f149 519c 6354 7001 97c8 197a 32d4 e58d ce7c 6160 589e afda 694c f519 526c ac4b 9a30 f368 0eb6 d705 9c15 708e c290 1daf b4d2 f234 23d3 edd6 450b 6da1 f26d 3033 e59a dcca 9706 be34 32ac 5e58 83a1 3012 53ed 3a77 8738 c060 fee6 c925 fde7 b1e0 eb4b a4f4 98dc a1f0 7a2f 9eb5 630b 9717 b103 4d22 d660 2dc3 bac5 9b94 8b9f e7cb 9088 0dd8 2862 1336 52e4 45ec c305 2a9c 590b 5a75 5d9a e2b1 e3c2 1745 4470 8921 90b7 1138 f310 2527 5f1d 88b8 8c37 045c 11f1 26ae 0ab8 26e2 2d5c a73c 8b78 1b37 28d9 22de c1bb 22de c321 01ef 8bf8 001f 72b4 dd34 0f16 8a3f 43e5 fc6c face c98e 39c3 8a79 824e 6d91 592a 5499 1969 a04e 9b3d 4749 5922 353e dba2 d1c5 8b8a 2a83 e6ad 2714 e587 003d f255 af5b 8ac7 3937 9757 7398 e65b f625 fbcc 7346 6757 6af2 e903 5272 94ee 1f54 8cd1 f6c9 0962 c971 6ba8 973b d79a 2ed8 7274 6f55 3672 af2e c712 f4bd 61a3 8ab1 5139 36d6 9d30 ba53 aaca 509d cfc0 7cfe 142a 4e94 321b 391d 3dfe 4d37 2a25 bbe5 49c3 0c11 79e9 d1cc 4320 5f09 f149 95d2 c613 71e5 b839 fccd a4ac 0965 0daf ec09 8b06 7a71 5a05 7293 5ecf 2a79 7fd0 7e1d bdbe b9b0 1ea5 bcf6 9d73 359d 37cd 3987 20d0 6b5b 0dc2 b4df 4c14 8ec2 ff3c 5fc2 759b 9e0c b5b4 1698 d46d b64e 1d69 6c41 bdad f12c bcb4 03fc f7e1 1eaa 0cb2 6978 6e9b 62b3 8a11 6ca5 b5dc 1223 631b cd2b fc04 d8e8 18b2 9d3e d4dd 36e8 397a bae9 591c 9e86 37bc f92e 0ac2 b577 21dc 2192 db04 2e85 87d6 315a 55b2 669c 5e26 35f3 9235 961a 9ec6 33e6 25c5 b6f7 7cc7 fd76 6167 8654 b323 55ed 4885 48ca 326a 17d1 a843 2da3 5c3b 49ab 90e8 7f86 bf46 c10c 0a89 771f 4543 7412 ccd3 347c 5dee 16e7 d8e4 a90a 786e 621b 2754 cdc0 efc2 f710 67b0 84d1 7369 b337 58e1 9d41 31c3 b148 2ddf 95b8 3078 d9cd 6e3d fe29 780f cbba dd4d 1ee7 9626 6fc0 13f0 de44 751d 2705 3c19 58f7 503a 8332 aeec 21e5 5f49 af36 4369 77ad a3b0 7406 cb19 9a0b 2a08 36c0 f009 827c 574e 24a1 ae42 7080 6e3d 7e60 62fd 5077 0f2b 782a 3d66 c40f 52cc 8129 f870 9676 e7a8 e2ce 5315 5c40 3b2e a207 97f0 229d 8fe0 0a62 34fd 2671 151f d3f3 539a 805f e03a 7ea1 09f8 1b6e e001 9dff a001 c833 7586 7e21 b4a3 0c2d 6605 55a1 157b a81c dc14 fd26 da37 d2ad c7a9 20f6 98bb 9354 9f9c e625 2411 7bd1 4655 fb19 a236 f773 e259 5cca 8d9d 791f 7ea7 31cf cb2b 889f e91e 9ef9 18ae a103 fbe9 0e5e 03db 49de baff 8083 1b25 5c0b 83d7 85a5 79d0 d17c 8e34 3b89 de80 c2c7 64a6 5740 1713 d0cd a86e 1e62 c723 940a e861 ec21 6afe 818f b1bf b152 40ef 5f58 fb90 e0ad 727a bea4 957f 7d90 51bc c65b e9c9 4bce 1bfe 062b 6f3b 956d b54c c88c 9168 09d8 3eed cca0 9085 25a0 08f5 d970 12e9 f39e 10c2 9b6b a7c1 eee4 050c 5b22 4e7b 08e8 b7db 43c0 0b66 90f8 6e00 8376 9044 9b67 05a4 9092 3c64 5fb7 de94 35db be62 681a 955f c175 276b 5ed4 1088 e5f8 61bc 643e 5fc6 5366 eff2 e60e 6235 fdcc ab30 410a ff05 504b 0708 f2ad fb42 4906 0000 6f0e 0000 504b 0304 1400 0800 0800 6d57 2d49 0000 0000 0000 0000 0000 0000 2700 0000 6461 6767 6572 2f69 6e74 6572 6e61 6c2f 4461 6767 6572 436f 6c6c 6563 7469 6f6e 732e 636c 6173 738d 544d 531b 4710 7d8b 8416 2dcb 9730 b22d ec04 9b7c 20d9 41c1 4970 8c14 0116 10cb 08e4 448a 8873 2183 b405 6baf 57aa d52a 09b9 e496 4b7e 40aa 7249 1517 5f74 c027 ecb8 2a3f 20bf 2915 fc66 25ac 2f5c 71a9 6a5b d3dd f35e cfeb 9ef9 e7bf bffe 0670 0b0f 54dc d110 c292 8604 922a bed0 e047 6a18 cb58 51b1 aa41 c5dd 61a4 b1a2 6114 6b72 9952 b1ae 4197 76c3 b742 0cff 32bf be5f 4e4f 4f55 7ca9 607c 6bf5 dbdd 07b9 9df5 af77 731b bb85 9d9c 0225 a360 245d b16b aeb0 dda2 b0ea 8682 40d2 b44d 37a5 c037 172d 2af0 a72b 657a c7b2 a66d 6cd7 9fec 194e 41ec 59f4 84b2 9592 b08a c231 e5ba e5f4 bb07 664d c16c b62c f6f7 0d27 6eda aee1 d8c2 8aaf 79eb 74c5 b28c 926b 9231 a140 af3a 46cd fcd9 2867 cd9a ab60 722e 13cd 3e12 3f88 78dd 35ad b874 32c9 2f33 5865 de15 a5c7 5ba2 da22 0ae6 cd7d 5bb8 7587 ffe7 9385 a5e6 464b d8fb f1dc de23 7224 52fd 70c9 4221 9122 e6c8 81a8 add5 ab96 5912 ae51 93cc bdbc d1ef c86c 7965 8df7 d734 286a 79c3 95a2 b443 7430 12ee 16e5 b07a 26cc 646f 2931 59c8 6c37 40f2 9c53 2454 dc23 6e6f 8572 bf2c 3262 1b3f de13 b503 eede 31dd 83f5 9faa dc65 94f3 9e68 e16e 095a 7952 79a3 2b6f e16d 046c ed3e d370 86c4 9c89 c746 5906 d898 7efa 2bbd 1de8 c826 c276 72f3 1cd6 e2db b4b2 0328 59d8 4c14 8a5e 4997 287d a96e b1a7 194e b029 acb4 a88a 92e9 1eb2 9744 e0ac 6bf9 4add 2919 1ba6 6c49 b86f 26e7 2587 8289 7601 19ce 2f73 7484 7151 4546 c77d 6cb2 99ed 5a56 1d47 1cca 86c8 94ac 8a2d 1def 62fb 0ca3 5338 9990 6333 757c 8645 0517 df70 1e05 d7fe f7ee 7028 7b35 e250 778d 9282 a9f6 ba6b 6bd0 7852 750f 9b57 2e34 77de 8da3 56bc f8a3 dd01 ef3d a084 973b 27b1 0d9c 8816 b1c0 9728 c477 8753 8949 5ca0 9de2 6a00 6308 f04b 05e9 b944 4f9c 56a1 1d8c 9d60 e099 9772 99df 80e7 7c8f 9bc1 57cc 4bc0 34ae d006 7115 ef30 4b6e cec2 e7c5 2622 7f40 7d0e dff1 4bf8 1f46 4e30 784c a7cf 031a a505 6ef2 b9fc 0843 646b 034e b039 1768 67bc 5c65 08d7 3cf6 eb64 9825 7393 e177 8606 6863 b117 08f0 b21f 61d0 d778 09f5 21cb 1dca 369d 375e 20a8 e04f a8fe a7f0 fb1a f2b1 f5a8 43b4 c022 34dc 26e5 1d0a b0e4 d187 9b88 781f 1fd0 4ef1 f721 e658 52b4 2b16 7b1d bbc1 982c 7218 3efd 5f4c abb8 b9a2 b48a 9567 9ae7 a99a c52e b6e4 d065 8191 e7d0 4e30 7cdc 23e9 dd0e 0574 7cec 29d0 c45a 20d6 2d7c d28f a5b7 b046 7ab1 eebf 11eb 531e 9a93 ddea f12e 3d32 673a 1238 821a f17f df88 84c6 8ea0 477e 0d8d dbfa de6f 8dd0 44e3 75c3 c2ec 34b0 cd6f 8e9d f88a 03f3 0d41 763a a8a6 5b54 339e d203 c151 7a6f 7bb4 9fbf 0250 4b07 08c6 1067 7faa 0300 0031 0700 0050 4b03 0414 0008 0008 006d 572d 4900 0000 0000 0000 0000 0000 0026 0000 0064 6167 6765 722f 696e 7465 726e 616c 2f4d 656d 6265 7273 496e 6a65 6374 6f72 732e 636c 6173 7395 545d 4f13 4114 3dd3 16fa c162 1168 c50a 8808 b51f 42a5 020f 9634 1a84 a449 5d4c daf0 e6c3 763b 2983 cb2c d96e 4dfc 57ea 8b1f 0fc6 677f 94f1 ee74 2bf6 636d 6cd2 999d 7bef 39e7 ce99 d9fd f9eb db77 0065 1cce 2182 4771 c490 4b20 8f42 14c5 04a2 781c c54e 14bb 5194 1896 74fb ecfa 15bf 6a71 a75b 9397 dc74 6d87 41ab 49c9 9d63 cbe8 7679 9761 5ea8 8c5f c650 cdd5 db46 a7c3 9dd2 08b2 52bf 34de 1925 cb90 9dd2 59cb 8b55 f2e3 2186 c8b1 dde6 0cc9 ba90 5cef 7914 4da3 6551 64b1 6e9b 8675 6e38 c25b fbc1 e4d5 687f 2b41 fa0c 3121 bbae 214d 4536 413a 3dac f0fe 7aa0 b216 c079 d46c 56aa 040c d3cc 106f 888e 34dc 9e43 88ca 51f3 d9b8 44a0 397d 221a f28a 2922 c979 864c 2e1f bc99 8300 8520 c8a0 57ad cd2d de31 5c21 3b4d 9ba1 1c78 5eff d08e f91c b4d1 f520 b91d 5faf f19f 4ef4 71d3 7631 7b24 a470 ab64 7d2e 7f4e 86b9 1782 2edf e600 25a4 cb1d 6958 a3f0 2e41 130d bbe7 98fc 5478 279b 1a2d d8f5 5ad5 3087 271a f650 8ee2 a986 7d1c d0e5 98dc 9086 07d8 64d8 9826 ccb0 306a 02c3 fe34 d4d6 c457 3095 9bf0 2e91 0bb1 9ade 68be d08f 4f18 0ea7 3a31 899a dc59 1bc5 bd76 b869 cbb6 7085 2d69 179a 79c1 cdb7 baed ea3d cb62 c84e 6a65 3c44 56ce d2d7 c5fb 4510 2777 3584 304f ab37 3487 688e 178a 5fc1 4228 7ea0 4518 b768 4ca8 c436 c1b2 48d2 53ba 5f88 05dc 5644 712c 6209 0ccb 43b9 d49f 5c9a 7277 e839 8415 5adf 45c6 975c a5b8 6ae4 1342 9e1a 536a b32a bae7 23ee 1162 156b 3ee2 25e5 bc6c acf0 05e1 1f88 dcf4 d847 9daa feb4 7e0d d655 7fcb 4391 fb34 f799 37e8 4f37 8632 1e73 c967 9e29 7cc6 cc47 5570 435b fb8b 7606 0fb1 a5f2 db6a cc92 3d9e 4574 e854 1d7f 9ef9 0d50 4b07 0811 b043 bc60 0200 00d9 0500 0050 4b03 0414 0008 0008 006d 572d 4900 0000 0000 0000 0000 0000 0025 0000 0064 6167 6765 722f 696e 7465 726e 616c 2f47 7774 496e 636f 6d70 6174 6962 6c65 2e63 6c61 7373 3bf5 6fd7 3e06 0606 2306 4e76 0636 7606 7676 060e 4606 aee0 fcd2 a2e4 54b7 cc9c 5446 0611 f7f2 12cf bce4 fcdc 82c4 92cc a49c 54bd acc4 b244 4606 f994 c4f4 f4d4 22fd ccbc 92d4 a2bc c41c 7d34 658c 0c02 2085 fa39 8979 e9fa fe49 59a9 c925 404d 08a1 c4bc bcfc 12a0 d2fc 3c7d 4738 538d 9181 9181 0988 9919 4080 9181 0548 3231 b002 0050 4b07 0876 1346 0883 0000 00a6 0000 0050 4b03 0414 0008 0008 006d 572d 4900 0000 0000 0000 0000 0000 0020 0000 0064 6167 6765 722f 696e 7465 726e 616c 2f4d 6170 4661 6374 6f72 792e 636c 6173 739d 566b 531b 5518 7e0e b92c 4996 5b80 2015 9502 d690 14d2 8b6d 6913 514a c146 02ad 0483 add7 4d72 9a2c 2cbb cc66 53a9 ffc4 5fe0 579d b1b6 d199 8e9f fde8 477f 8a33 5ede 7372 5d92 30ad c370 de73 deeb f35e cec9 fefe cf2f 2f00 5cc1 6110 1348 05f1 1e56 03f0 e3fd 10c6 f081 8235 05b7 8374 5e0f c187 3b41 6c60 53ec 3e0c e12e d221 7c84 2db1 6414 6c87 308c 1db1 dc53 705f e87c 2cec 7615 6415 ec31 8c14 2cd3 b1f5 7cd5 d1cd d2b6 764c 9ccc 81f6 584b 10c3 4810 23c9 10c8 ea25 5373 aa36 67b8 e496 a6f6 b692 9273 92d0 cd03 5e70 12f7 6deb b15e e476 6a2f 975c a53f 067f 4a37 7567 9521 1c3d e57a 31c7 e05d b78a 5c44 d54d be53 3dca 737b 4fcb 1bc4 0967 ac82 66e4 345b 17e7 06d3 eb94 f50a c34c a6a8 954a dca6 a00e b74d 4dba dbd4 0a8e 653f a188 9e23 9148 c4ed e0c9 71d3 c9c2 19d6 2221 899c e16a f455 7315 f9f8 0b36 d71c 8a72 2dda 5b39 b978 36f8 3081 6fea 36b8 0c53 7d7c 31a4 fb40 7a55 ec22 e3ef 525b b7ea 7686 6696 12f7 f242 3399 ebc1 5bed 93dc ff08 7b56 393a bae1 2971 8761 2cba d835 9e3e 4e13 4c35 f26d d4a9 9a36 4d6e af1b 5aa5 c269 5626 dd06 0b52 4b8c a5cd 2b55 837c 5eef a5f0 3283 3dd5 9d6c 03ec 50d6 d10a 87c4 9313 27af eb27 0cd3 a7c1 7758 4c34 659d 5566 305f be23 ddac aec2 36ab da07 85c0 11cc 5a55 bbc0 3775 7151 46da 9d58 1626 2ace 21a7 605f c5a7 78a0 2282 2915 71ac 50be 2e87 0ce7 fab7 54f8 785d c543 7ca6 e073 155f e04b 155f e16b 05e4 3d8f 0215 4a45 115c c523 e178 bc47 6b54 94b0 a2a2 2ce4 933d 5ba4 42c7 8180 7691 61f4 7459 a86f 7dea 4277 af1d 2e4d 328d b834 7951 71af 27db a275 cb30 c891 6e99 345e 2355 f3c8 2aea 8fe4 2323 939f ed7a e6ba 46d6 5bd1 bfe5 d273 9ae1 fc69 3877 e4d9 1565 d6e4 dfd0 0b79 c88b 77b5 4a99 9cec eb4e 79e3 e498 1478 312b 9dcd 44d3 9d81 5cda 1472 50de 926c f725 2256 d2d5 41a9 33a8 b7f2 8fb8 d49b 7521 1ba5 ac55 76f8 8923 1379 4859 99f2 e0a7 9bba c5a9 9a83 b4c9 6946 5564 7a5c 25c9 4ab4 c790 7671 7a5c 045c a6df ac09 5017 e83f 2c06 8fe8 6bf4 0339 8069 7869 a599 a275 8638 9ce8 00d1 a1d8 33b0 58fc 3906 9ec2 f323 313c 7883 d661 a2c0 db64 7401 2ade c19b 748a d40d f016 6601 b93b 2f03 ccb9 64f3 2dd9 742b f802 02e4 eb42 2374 897c 0bed f158 0d5e 86df e0cb fc0a ff83 f833 283f b400 04a5 ca12 d1e5 8ee0 e304 252a a581 aee0 42b6 d892 b583 c768 4723 de08 fe27 f9f7 12dd 8dfd 044f 0d83 0ccf 11c8 d40f 4186 1a42 0cdb 176b 50e9 9947 9c36 4302 e1f0 4e7c a986 1106 5a47 0563 4c42 af21 ecc1 fef7 fffe 21ea 27b0 7b25 f608 7d3e 0037 a808 2b48 e026 7d61 dcc2 3692 328f 598a 9fa0 2e2c e192 2cf1 6ea3 9c43 f46d 72b9 9551 5beb 4a4b 6bbe a575 95b4 de95 4d1a f81b 330a ae29 b8fe 17f9 abe7 7b63 744d bc36 a423 f25d 23ca 88fa 623f 63bc 5d5e bf64 ce49 486a 5da1 0164 cec5 9997 1675 c737 290d 4193 044d 9499 1100 1f96 fd81 ff00 504b 0708 f24b 808a 1504 0000 8609 0000 504b 0304 1400 0800 0800 6d57 2d49 0000 0000 0000 0000 0000 0000 2500 0000 6461 6767 6572 2f69 6e74 6572 6e61 6c2f 4465 6c65 6761 7465 4661 6374 6f72 792e 636c 6173 7385 525b 6f12 4114 fe86 db16 d896 5a29 0856 1154 caa5 4af4 d112 9246 2531 c14b 0269 e2e3 b08c ebd6 ed2e d90e 4dfb 2bfc 2b36 d134 6aa2 6f9a f8a3 8c67 9605 0b94 f461 e6cc 9c73 e6bb 9ccc 9fbf df7e 0078 8c9d 04e2 28c5 b182 bb1a ee25 1046 2989 fb28 6bd8 4e20 8692 868a 86aa 861a c3ca 40d8 c2e4 5230 643b 07fc 989f 342c e740 18b2 f1c6 738f ad81 f076 19e2 5dcb 74b8 1c79 d4b5 7579 57b3 d7db 6d51 6bac 6939 966c 3184 2bd5 7d86 c853 7740 8f52 1dcb 11af 4687 7de1 f578 dfa6 cc46 c735 b8bd cf3d 4bdd 8364 44be b78e 188a 9d01 374d e111 8714 9ec3 edc6 b340 649b 1bd2 f54e 8927 33fb fe74 38c1 285f f578 a234 6c0a c990 ae54 7d43 0d9b 3b66 e375 5f99 a2e2 6a57 72e3 c34b 3e0c 50a3 952a 3da3 f623 2127 7883 8977 867c 65c9 ecd4 0c0a 4b8a 6321 aaa3 ddec 3d59 54d1 5a4c 2d78 9bf3 94e8 ba23 cf10 6d4b 694e cf19 7fa8 e074 a4b0 ae23 099d 84fd c77f 61ab 569b 5c4b f1fc c410 4369 b98e 86ba 8e1b c831 9416 3af7 3c73 7428 1c39 6d26 b82b 06cf b03e 6f88 3edd 1247 0c9b 970e 0d8f e857 c741 5669 8594 0f8a abf4 eb43 58a3 7fce 943d daaf 5166 8f22 a318 ad9d 839d d121 8c0d da63 7e32 8feb b4eb e306 a4b1 4931 3393 c952 64ca 3e41 2bb8 7714 552d 57fb 8cd0 6f24 bf23 fcf6 1c91 9fea fa15 5186 4f54 8cf8 144a 0950 8086 3ba4 a774 812a b740 950b a8f2 be40 960a ccdc a4e2 166e 05dc 1f29 8628 16eb 3e71 8c88 359f f8d7 051d f52f 089d 4d35 e4c9 2850 a6db 3631 5549 438d 4077 48d1 035f 4f66 0c18 e851 a7f1 2c33 33b5 ecb4 b646 b5bc 8f1e d2d7 0291 b769 8d4f 05c2 55b1 f80f 504b 0708 3aae 138a 3902 0000 8404 0000 504b 0304 1400 0800 0800 6d57 2d49 0000 0000 0000 0000 0000 0000 2800 0000 6461 6767 6572 2f69 6e74 6572 6e61 6c2f 4d61 7050 726f 7669 6465 7246 6163 746f 7279 2e63 6c61 7373 9555 eb4e 1341 14fe a6b7 6d6b 9582 828a a8c8 cd52 9452 4445 a828 5650 1495 44d2 c8cf 6d59 eb9a 6597 6cb7 067c 015f 07bc 6134 f101 7c28 e337 bb4b ed05 e3d2 a43b 3367 cef9 ce39 df39 33f3 ebf7 f79f 00a6 f138 8904 6e2a b895 4408 b713 5ccc 2671 0277 9298 c3bc 5c16 a4c2 5d05 0b52 724f c17d 058b 0a1e 08a4 564c 53b3 8b86 5aab 6935 01e5 415d 3736 355b 20ba f46c 6d7d 4360 6475 53ad 5635 3ba7 9b8e 669b aa91 7ba6 6eaf d9d6 3b9d 6acb 6ac5 b1ec dd79 81c4 4bbd 6aaa 4edd d604 9e04 3029 acbe 55df a939 4335 abb9 17e5 b75a c599 ef94 2c10 b8ab 6299 8ead 97eb 8e6e 5689 4389 a748 810b 4c9d a956 4961 fda9 07b6 c308 2450 eed0 7961 bd44 5009 ab94 0f13 cd65 56c6 0304 3ce2 3343 db48 d1da d464 1cba a93d af6f 9535 7b5d 2d1b 94f4 ac5a 15d5 28a9 b62e d7be 3052 d3df 7310 2b02 6ae1 e95c 6796 a523 640b c70b 4a66 eca6 c6ba 695b dbce aec0 5826 0800 0d5e 1d23 a820 904d b1c4 0aba a93b 0b24 26d3 56b3 f112 8971 dee8 6cb9 be56 d276 b70f 89bb 763c 6737 32c7 ed02 1944 b8aa 3902 ddcc acbd a9a6 db65 41da eacc a151 336f 02b3 edf9 07a9 6dde 0d30 b433 253f 7956 3498 9140 bc50 317c e2c3 1989 f121 7889 8f38 96ed 5e5b 4f70 7076 243f c997 56dd ae68 cbba 2cf0 d9ce f827 2542 0a43 1816 c806 ef7f 6951 4c21 8d6e 39cb 2b78 98c2 1296 5338 83de 1432 1817 18fa 3f5a 0a8f a466 ba9d 0246 fa0f 0e78 3d06 a909 73c9 ac04 2f79 ef5f 628b 9661 3002 dd32 7952 baea e696 b5a9 bf76 0f8a 7b15 0e76 9cab 8e36 8ebb f701 e7c8 f309 3801 5ef9 7c23 fa25 579c f7f0 f908 e134 4732 d558 f741 a1ee 599c e3fc 3c25 3388 700f 48fe 4068 a35f 1c20 bce7 eaf5 f31b 7377 aee3 02bf 294f 0b03 b8c8 d1c3 ba44 a4cb 18f4 9106 5c0d 20f2 1111 8921 9a30 6efa 1657 f867 03f8 161a c710 c793 d903 44b3 13df 10fb 0265 9f82 b06b 7a8a 2330 cb00 efd0 fd9c 1b46 9f67 8011 a608 77e6 2537 dab2 37d6 d8eb 6b24 7e95 3376 8bef 7a91 2b19 5834 fb19 ca5e c3a5 176d b129 e3a8 ef6a b445 32d6 e020 9b5e 24ec 0477 5a61 bf22 de0e 3b1c 0436 0d12 74cd 872b d181 e420 969d 3880 d83f 126f d0d3 6830 1263 c17a ddfd 1826 9123 c25f 1f31 3ff4 38a6 d832 9e8f 49d7 9e6c ff40 62e3 1b92 74f4 0991 fd46 01bd 2a8c b00a a32e b761 3ff1 69dc 70c7 196a 4832 42dc e52f 1de7 2c81 2e9c ff03 504b 0708 a0a4 4ef7 3c03 0000 c208 0000 504b 0304 1400 0800 0800 6d57 2d49 0000 0000 0000 0000 0000 0000 2800 0000 6461 6767 6572 2f69 6e74 6572 6e61 6c2f 5365 7446 6163 746f 7279 2442 7569 6c64 6572 2e63 6c61 7373 9555 6d77 1257 107e 2e01 9690 252f c490 5795 681a 09d4 90a4 d6b6 42a2 1192 06c5 4485 4693 b6d6 05f6 90b5 db85 2e8b 47fb b17f a19f ea1f e8d7 6a5f 62eb 39fa b1e7 f447 f574 ee65 8184 158c 8773 eede b933 f3cc 3373 e70e fffe f7f7 6b00 2b28 fa31 8c75 3f46 70dd 8f14 d2fd 246e f065 932f 9f4b d8f2 21e3 8784 1b03 b889 2cb7 b9e5 c3b6 841d 3f02 b8ed c71d dc95 9093 9067 18d5 8c92 f658 2bd5 15fd b659 a18d 6ad6 1886 b38f 94c7 4abc 6e69 7a3c abd5 ac04 437f 4e2b 1b8a 5537 5586 c50e 7552 c84f e29a f148 2d5a f126 5032 9f4f acd1 8fa2 142b ba4e 2aad 621c 89b2 7942 9823 66a9 164e 135c c0cf 29b5 9a6a f2e3 5a5a ab29 055d 2d31 b07d 066f 5233 346b 8dc1 13c9 6416 7619 dca9 4a89 3218 ca6a 86ba 5dff aea0 9a79 6ece 10cc 568a 8abe ab98 1a97 ed43 b775 a011 51e9 7a5d d389 0983 9c31 0cd5 4ce9 3c1e 29e6 b225 a55c 564d a26c a9a6 a1e8 f19c 6a6d 2a45 ab62 3e9d b39d 885f c859 e49c f603 e1b3 0c29 9db5 6928 43c7 193d ad36 592d 9c20 6aa3 3c0c 034a a9d4 8465 588d bcbd c489 9340 125a d099 08c3 7817 4c86 d35d 2e34 6693 0be4 2ca5 f8ed 2da5 6a27 b6d5 859e edf0 3e79 8f51 de29 4761 2903 67b5 192e 770b fbf6 ce8b b5fa 5ae9 4ab8 b7e7 fb64 e229 7099 e14c a497 1719 9eef 69d0 8093 f005 37cc 647a 1158 4ef0 97e2 7ab2 c497 65be ac50 f8de 1e0c be64 51b7 1f5b 5f84 0344 92f9 2b8d 32e8 8a51 8eef 1478 8912 6bce 2306 7fae 5237 8bea a6c6 bb60 a80d bcc8 6d65 4c61 9a2f ab12 7665 dcc3 7d19 418c ca08 f165 0293 0c13 6dcc f5e6 24d8 30cd 0add ed0c 7ff0 65d5 08ab 5cbe 1ade aeeb 7ab8 6adf 1347 dd93 b02f e34b 7c25 e36b 3c60 8877 3884 d3f5 aaae 1515 4bad 8535 236c 1da8 2df7 b04e 538b 61aa 7b65 7880 6f24 3c94 a1a0 c070 eedd d74e c3b7 b340 9444 afda 33cc 76aa d342 6e37 1e8d 2ab9 6aaa 359a 2ba5 ace0 3c1a c92c 3887 fc58 c479 3bfc 2a07 8f5b d20d d3f3 ea62 4e53 3770 a0d4 da55 e3c1 3a43 71ab 75c7 a943 7e67 930e b5e3 8ba1 4c53 b344 699a 6aa9 d507 3463 ac7a 4d34 e53e 96e9 0f72 84fe 44fb a883 a887 c070 8a24 17c6 480a 1d91 c787 2778 67d1 de4b 12f5 1f69 6648 fa9e a43e fa8e 450f e18a 4ebf 44df 1f70 4767 c4d7 f35c 009f a635 0837 ad5b b466 20e3 0681 dec4 193a 0937 9c71 16e7 00b1 3b8f 3982 e6bb 0f68 e7c2 3ced 65fb e42c 2ed0 971e 1216 48c3 c3ff 48fe 2efa cebe 80f7 1946 62ff 20f0 0ad2 5ed0 7788 fe37 d1df e18e fd05 bf0b f7a2 bf92 915b 5019 1421 7788 c21d 02bc 2b68 841a 202d 1ab3 8822 4681 e68f e92e b474 1f92 eea2 488e 9db2 0bb4 4847 f113 f3f2 74e3 759f e0f6 28d6 7e17 5e4b 3d78 2dd1 6d3a 78ad d0d1 47b8 64f3 fa09 1e51 cb0d c16b 9c57 e825 067e b6d9 c99c 5d4b e3e9 d4bc 4260 8f7b 701d 3bc4 6027 f707 d417 0f29 5451 706f 5cda 86cd 7dfe d809 677c 5178 bba6 266d a21f 0f83 fc3f b1fb 4a21 44de 3252 747a e610 acdd 495e 0192 1621 a20d 9356 7924 7c6a 778f 84cf 44f7 f0dd 1524 c8b7 4d40 b209 f890 c4aa 1dee 92d0 0023 c1c0 9f18 7a06 c9fd 0bdc 7dbf c1fb 5c70 3b1a 98f3 f6c0 255f a317 6453 5fc3 55f1 bd46 97c0 7bdd 458f 2a40 bd3d 89cb 02d5 f73f 504b 0708 9e2b ca13 5804 0000 aa0a 0000 504b 0304 1400 0800 0800 6d57 2d49 0000 0000 0000 0000 0000 0000 2100 0000 6461 6767 6572 2f69 6e74 6572 6e61 6c2f 5369 6e67 6c65 4368 6563 6b2e 636c 6173 7385 55db 5213 4110 3d93 8b4b 360b 41c0 8002 a280 1816 25de 6fc4 c855 4d55 8c94 44aa e06d d98c 6175 dda5 361b 4bfd 0bdf 940f d057 efa8 5479 79b2 ca6f b2d4 9e49 c235 c197 9e9d 3ed3 dda7 fb4c 26bf fe7c f90a e00c 322a 6238 1341 0467 8539 27cc 7905 1754 842b ee8b 5168 b8a4 e0b2 822b 2ac6 9052 7055 257f 5ac5 358c 2b98 5030 c9d0 7c37 97c9 65f2 9989 6c66 7166 9aa1 2d7b df78 6424 6dc3 2926 6f2f dde7 a63f c6d0 b4e2 b98f ac02 f718 3a25 fe38 6939 024b ce56 013a 1499 b38a 8ee1 973d ced0 53ff 542a 9f1f 4b8b 7c96 53f2 0dc7 a493 ed83 46a9 c43d df72 9dd2 b455 3296 6c5e 6060 8b0c fb52 9663 f969 8643 8906 3587 e719 4253 6e81 d2c4 b296 c373 e587 4bdc cb8b 1ca2 11d7 34ec 79c3 b3c4 beea 0cf9 cb56 89a1 375b 308a 45ee 5146 9f7b 8e61 27e7 2ca7 68f3 a965 6e3e 207e f1ed b14f 566a f1fd 7b05 d6ba 6b9e f30d f3c1 2d63 4506 4901 ae32 f435 e8a2 1225 5a09 16b9 cfd0 9118 ae27 c1fe 9a04 77f8 3dee 7139 bb70 6298 8219 4e35 1c50 43b1 6653 f92b bbcb a4f7 e6f8 1f51 53a6 5d55 2c98 10fd ccd7 afb1 dbb5 57de dac0 b3c6 d327 b54a ea9c 5bf6 4c7e dd12 92b4 6e51 6054 24d2 7008 a31a f6a3 4d43 a730 5d38 c8d0 b559 75a2 76e1 663c cff5 34b4 a343 c371 2418 baf7 50b7 0e3a ed96 97aa a882 290d d398 6138 50b7 1941 aa5b c175 0d37 7093 48ef 9c01 4374 4ba3 7443 77d6 9af5 b8e9 3a05 4bfe 5018 3453 54cd b97e ae6c db0c 4389 dd53 ad7b 8d62 9bbe 299b 7e79 74d7 0bbc 6479 bcb0 3115 babd 7eb9 2445 5cc4 697a 3062 08d0 4bd2 8a10 f540 53a5 d767 52cc 0cd4 2b7d 0710 a77d a7f0 b776 8959 932f 445e ea97 6c0f ed9e d31a a075 405f 03d3 df22 f001 c1b7 08ad 2236 f213 d175 8417 d6b0 ef9b 3ef2 01ca 1b19 dc4b 364e cf18 d04f bb23 8862 807c 83b4 3b86 c312 93e9 d047 18e4 5785 ced1 6d58 ff06 1627 6c80 be63 607f 2951 40c1 a042 a950 e53f 4430 c95f 65fb 6c83 ed7b 2859 32c4 35f0 126d fac8 6734 3110 779d 1153 01bc dec1 7694 6c92 aa9c a221 9c25 a6e7 ebb0 0d93 6fb8 01db 0a56 63db 04f6 1b87 05d1 0a4d 9da4 68c7 4895 e643 04e9 1cd0 a7ff 4064 152a 2dea 0b84 f5d7 eb88 2ce8 9f10 fd0e 6d0d cd9b 145b 2800 f437 d082 1469 9996 d4b4 4a0a 393e 4842 9b9e b824 26b5 6ca9 297d 8248 9da4 3699 a430 29c9 03dd 6d91 8f68 5985 127a 8550 f01d 42eb 8891 a4ec 1d02 6f64 9828 afca c33d 54ba 57a6 0d23 a08d 3372 5632 2769 6862 3dfd 0f50 4b07 08cb cfd5 135a 0300 00e0 0600 0050 4b03 0414 0008 0008 006d 572d 4900 0000 0000 0000 0000 0000 0030 0000 0064 6167 6765 722f 696e 7465 726e 616c 2f4d 6170 5072 6f76 6964 6572 4661 6374 6f72 7924 4275 696c 6465 722e 636c 6173 7395 566d 4f13 5914 7e6e 5b3a 30db 22a2 c22a 8885 451d 0a52 f15d dac5 5d11 d64a 0593 6289 51a3 433b 9691 71a6 994e 11fc 497e d2c4 5d36 9aec 7e34 d91f 65f6 b9d3 6929 54b4 86e4 de39 e79e f33c e7ed def2 df97 8fff 00b8 849c 8a18 aea8 88e3 aa8a 6bb8 de43 f186 829b 2aba 30ab 20dd 8d8c 0a05 bf76 634e c52d fca6 e077 05b7 05d4 577a e576 cdb4 4a86 2b70 32f7 52df d253 35cf b452 39d3 de34 4a77 f5ea c67d bd92 16e8 c99b 655b f76a ae21 307b 985d 6675 29ed 9f6d a74c fba5 51f4 520f 5c67 cb24 7866 b590 9ee3 9f40 3463 daa6 3727 10d1 b213 056e f34e 8998 4708 642c d75e ad1b eeaa be6e 51d3 9f73 8aba 55d0 5d53 ca81 32e2 6d98 5501 a519 732c 6bdb 863b 6fe9 d5aa c183 a95c 492f 970d 97fc 9ee1 daba 9562 588d 2016 f5a2 e7b8 3be3 8133 8389 54cd 3744 1559 8181 fd74 3b95 06e5 951f 8094 05f0 3315 e85a 972a 8173 da44 0700 7498 eec8 b085 215c a979 026b 5abd 1b96 6e97 532b ebb2 ea87 f420 dd09 7e4b 71c2 9bc6 8e6c 431b 3cbb 5509 bc56 5e14 74ab c62a 0d1e c249 1846 2c30 fcad b910 88e7 3dbd b8c9 7082 a23f d4be 334a 3f92 4bb3 660a e605 925a b613 df99 b49c ced0 f645 b9cc b08f 9d39 0964 324b b3ed 352b 7c45 37f7 b5d2 aa79 a7e6 168d 4553 9661 b09d 635a fac4 d08f 6372 b9a3 6021 8645 fc11 432f 8e08 8c7d 3f48 e976 5760 648f 7bb9 6659 0f1c df65 61bb 6854 3cd3 b1d9 e3d5 0d23 c111 4898 d584 4d0b e9c7 7b32 2ad5 8df6 279c 1709 8ff2 961c 8286 a182 7b31 8c61 89a5 eebc 4702 7d07 8b21 30de 49c9 3961 9a6c d5e8 41e3 3bbe 3cef 5816 c198 129f 8784 6dbc def7 62ad 99de c6c2 7685 0646 29ef bf05 c37c 96be f10e ded0 5a0e a5aa f359 3ad1 7a53 f39e 6bda 655f 3f78 08db 1e59 dbdd dea7 9968 5761 86ef 7f9c bf0c bcbf 7230 b8f7 510a e128 225c 393c d41c a7e6 31a5 10f7 7872 17a1 e4d0 df08 ff89 c87b 2ac2 38c1 b597 3b90 a3d3 3201 5730 4069 a0ee 8041 9c02 fcaf 210c 13ee 34bf 63dc eb67 233e f919 2468 2d89 b2c4 f0cf 3ea1 eb51 f203 2262 17d1 774d a2a8 7ff8 d027 d803 9104 edb0 f54c 46a9 1bc3 2f01 fc5b e2c8 50b5 c9cf 9242 79d4 dfbd 8b9e 7fa7 1a92 2a25 493b 39f5 177e 5a4b 4ae6 88cf 7c8a dcc0 134a 4f99 ee33 d6e6 39d3 29e2 1c4a 7e34 893a 6e33 5d0d e338 ebc7 a3d1 e63c f94f efb3 1a69 5a69 4dab 095a 257d c650 6f3c 887f 925b 3f2e 047d 2850 2311 a2c9 a15d 88f7 07ea 926d 8924 da8c 248a 69bf f0f2 2b85 8b41 24b1 4053 8f24 1cb0 cdf0 7f04 b95f c649 48de 10ed baf0 33a5 2909 d5d7 fd3f 504b 0708 afd7 a3c4 7903 0000 4a08 0000 504b 0304 1400 0800 0800 6d57 2d49 0000 0000 0000 0000 0000 0000 2100 0000 6461 6767 6572 2f69 6e74 6572 6e61 6c2f 446f 7562 6c65 4368 6563 6b2e 636c 6173 739d 565b 5713 5714 fe0e 094c 0883 d020 17b9 68bc 5421 0163 bdb4 0a88 cac5 1a1b 2396 8845 7b71 488e 6170 3a49 2713 d43e f657 54df d557 2f15 dbb2 56b5 f5a1 6bf5 27f9 60fb 9d99 9020 061e ba96 9ecb defb ecfd ed6f ef3d e19f 77bf ff01 e028 96c2 e8c1 5433 3a30 ad96 19b5 9cd7 f079 188d bef8 420b ba90 d470 51c3 1761 8431 1542 4aed 97d4 920e e1b2 da67 c368 c695 30be c49c 864c 98cf ae6a 98d7 702d 8caf b0a0 e1ba 40eb d574 329d cc24 cfa5 92d7 67a6 0522 a965 63c5 4858 869d 4f5c 5e5c 9659 774c 2054 740a 2b66 4e3a 02dd 9efe 6ec2 b495 2e31 5b51 d0a8 79ce ccdb 865b 76a4 407f 7dab f14c 666c 42f9 33ed 926b d859 5a76 1c30 4a25 e9b8 66c1 2e4d 9b25 63d1 9239 0141 644d e3a6 6dba 1302 bd83 5bc4 1c9a 1708 4e15 7274 d396 326d 992e 7fbf 289d 8cf2 a112 2964 0d6b de70 4c75 af08 83ee 9259 1218 48e5 8c7c 5e3a f4e8 4ac7 36ac c474 a14c 83a9 2599 bd4d 7c5d efbf bd57 5c7f bf6f bb87 ebd9 b5ce b946 f6f6 25a3 e83d 22f1 245c 60cf 1659 f8af 542a 81bc 7405 760e 0ed5 2b41 5bb6 ec38 d276 9355 e69a 1c59 2a5b 2eab a8e1 8640 e3e0 103d 091c d992 ad2d 2b17 ca49 4be6 0d97 4e67 c733 a31f 869f d81e fbf6 c50e 5ac6 8ff7 040e 6e8d abc2 698a 768a be4d f7c8 c6fb bad3 f3ff 0b67 1d47 a1f1 ac55 e9b3 c0a0 aac2 7c7d cf1f 8ab6 0b55 2f52 78ae 5076 b2f2 bca9 1aa9 7d43 df1c 568e 74ec c319 1dbb d0ab 638f 5aa2 d82b d053 8b7a 6e7d 4c66 1ca7 e0e8 e843 bf8e 048e b0b3 6a46 494b 15d2 6203 ba72 e66e 5616 d503 0e6d cd62 ce75 4c3b 3f59 362d 6f9c 67e6 b285 a2cc 45d7 073c 7ac7 2845 4d7b a570 9b42 47b2 e94a e68a b4ee f1cc c9b6 f934 9a33 6fdd 92aa 15a3 7e03 9646 a33a bec6 376a f996 2c46 0ff2 fe1d 6eaa 8c0c 0d8b 3ab2 e048 f76d 3339 ca74 bf40 cb06 d604 3aeb f2ab 41ea b885 3c29 dc5c 117e 4c6a a2cc 9253 b8e3 0f6d 9351 2c4a 9b10 4606 539b 8918 1bfa 4054 e166 6c93 7da5 eadb d987 dc82 2fda 3cc5 9558 cca9 1e02 36dd c066 7266 c97d c1ce 99de 7751 40cf 2a9a d205 375d b6ac ea2c 6d09 acf6 d5a8 c9a6 2c7e 68f9 69cb c992 e9c8 5cb5 9d54 af94 4b5e f75f c727 fc89 e841 037f 5a3a 1144 af6a 47fe 1c4d aa66 0351 f2dc 80dd bcef 51f2 f61e d5a4 9435 52ca 0272 3dc0 dbcf dc1b b8ef 8fbd 8488 3d43 c30b 049e 21f8 006d f1bf d1b2 86c6 8597 687a 158b bf80 f694 6641 7ccc b58b 4e40 2741 ba6c a1ab 01ba da47 cd41 4fe7 b9c3 210c 02de c987 33f4 9e2e 56d5 eda6 2ece 731b c4bf 74d4 a061 58c3 0805 3efe c354 736e 7cb4 622f 43aa d0a5 d82f 08a4 e284 fb08 4bb1 854b 7f6d b8a7 78d6 7e43 4878 a740 7a84 d287 181e 893f c4a1 3534 2fac 21cc 9c5a 22fa 2a5a 4756 b123 d2c6 439c 8755 b4bf c447 5eae 8198 60c2 c36f 1e23 3c1a 1c7e b32b f82a fe84 10da 91c7 32c3 2fc3 f676 9f8d 4fd1 ca35 4660 71e8 18a6 d508 0b72 9859 27c8 c831 4a8f e333 9cc0 0d9c c44d 8c41 e234 7ec0 198f ad28 02d4 8fb2 94bd 3c31 b10a 6f8d 8c70 9432 9f37 9dbb af53 bc29 b67a 107c 871b 1a8e f9ff dea2 795a c3f1 b768 aad0 7682 7f4a f411 995f e425 fa56 1eba 63bf 2272 2df6 273a eea3 31f6 640d 1d0b 2cfb ce27 d554 22dc 8169 869f 61d0 0bd8 818b 1e4c 1f40 37d3 e8e7 3ef4 9e64 7705 1243 eca8 443f c9e8 a798 951f fd27 aa54 dd07 18b8 f33e c2b1 d7e8 4cc5 fde8 c4f3 1a5d 7530 5c86 862b 8c72 8d18 16aa 8da5 f3ff 2952 28bc fee8 aba2 a9e9 c6ab ba3a b84e 2384 0932 2f3c 5c93 1e2a a02f d2b1 8aee 07d0 828f 110c 3c47 700d 3dec 10f1 1c0d 4fbd 670a 55d8 33ee 6771 073c af9c 22fd aca0 d0f7 7c16 e7bc 7df2 3f50 4b07 08a1 b6d4 3fee 0400 0014 0a00 0050 4b03 0414 0008 0008 006d 572d 4900 0000 0000 0000 0000 0000 0023 0000 0064 6167 6765 722f 696e 7465 726e 616c 2f50 7265 636f 6e64 6974 696f 6e73 2e63 6c61 7373 7d92 df4f 1341 10c7 bfdb 9fb4 5c2d 20e0 4f2a 4862 da92 7848 6262 94f0 62f4 a954 9236 4d88 4fdb ed72 2c1c 7bcd f66a e4bf d2a7 269a e8a3 897f 9471 7639 424b 4fef 6167 6776 bef3 d999 bddf 7fbe fd00 b087 ed22 36ca 60a8 d9e5 4919 05d4 8ad8 2c62 8bc1 13a7 529c b7a3 b83d 0e43 8667 f5d6 19ff c4fd 90eb c0ff d03f 9322 7ed3 980f 31e4 de46 03c9 506d 292d dbe3 8bbe 345d de0f 29b2 d28a 040f 7bdc 28eb 27c1 9291 27d2 482d 5c42 4ab9 f559 d5e5 f05a 99ed 76e9 b8d2 89b9 383f e4c3 eb7a 1d15 681e 8f0d ed6b fbdd d7f3 250f ea24 6c38 f1ab 949e a622 9dd8 281d a477 e949 6322 7328 4723 1edc ba7a 2263 d8fd 373f 85e2 6e54 d857 5ac5 07d4 5dbd d1a3 59c6 a76a 440f d31a f020 90c6 573a 9646 f3d0 3f32 5244 7aa0 6215 e911 e9ca 9d68 6c84 7caf dca0 674e 9f5b 140d e386 681f f428 72b5 de7d 1672 68d3 3cdc c37d bb3c 65d8 f82f 8d61 e976 4f0c 6bf5 948e 7a78 813c fd52 f6cb a284 2216 9021 0b7c 24cb c8de 69fe c2e2 77b0 e309 323f 9b5f 2892 43d9 c629 1fd8 246f 0b1e b6b1 489e 77a5 205b 7176 3a52 25bb e428 ccc3 326d 3258 71c0 bb09 f084 8e32 64ab 04f4 2c70 6782 ec3c d127 6f97 eaef 39e2 fa95 2421 dadd 2ad6 8879 c3ae ceb2 2b09 db0a 699c 9452 7245 994b ce37 27c8 7d75 0996 5870 c197 53bd e5f1 000f c932 3c72 598f ff02 504b 0708 2348 6b25 d801 0000 a703 0000 504b 0304 1400 0800 0800 6d57 2d49 0000 0000 0000 0000 0000 0000 2a00 0000 6461 6767 6572 2f69 6e74 6572 6e61 6c2f 4d61 7050 726f 7669 6465 7246 6163 746f 7279 2431 2e63 6c61 7373 858c 410a c230 1045 ff68 b5b5 0a76 e756 a46b 835e 412c b810 054f 10db a1a6 8444 d25a f06a 2e3c 8087 1253 5cba 7086 f9c3 87f7 ffeb fd78 0258 631c 220c 3122 c427 7b73 3967 4a33 61b6 97d7 a3b3 ad2a d865 326f acbb 2f2b d94a c274 6b72 6d6b 65ca 3d37 175b 8488 0969 21cb 929d 50a6 6167 a416 bff1 7445 98ec 8c61 b7d1 b2ae b926 245d a3d0 d294 e270 ae38 6f08 8bff 45c9 1c84 1ebe d3f7 0bef 020c fc0f 30f4 1af9 8b3d 431d 9044 1f50 4b07 087b 4aae f7a7 0000 00ea 0000 0050 4b03 0414 0008 0008 006d 572d 4900 0000 0000 0000 0000 0000 0025 0000 0064 6167 6765 722f 696e 7465 726e 616c 2f49 6e73 7461 6e63 6546 6163 746f 7279 2e63 6c61 7373 8552 6b6b d350 187e 4e6f 59b3 ec62 6d3b af9b ad73 261d 5af4 9b5a 0a22 0e84 3a85 96c2 3e9e 66a1 66c6 a464 a7e2 fed5 0465 e040 3f0a fe28 f149 1adb 75ed 28e1 e4bc b7f3 5c0e e7cf df1f 3f01 3c85 a5a1 a243 a0aa e1be 8e34 b675 68a8 e619 3dd0 b0a3 e1a1 c092 eb1f 2be9 db8e 40a1 7524 3fcb ba27 fd7e fd5d efc8 b1d5 0b81 7cdb edfb 520d 430e a43b 1d56 7276 e848 c5f4 9139 7bc0 6a1d ca7e df09 ebae af9c d097 5e7d 4fda 2a08 4f78 30f3 2a38 e4b1 b596 eb3b fbc3 4f3d 27ec c89e 1713 07b6 f4ba 3274 a33c 2996 a78b 2783 ff8d 95b6 92f6 c7b7 7290 e4cf 1a9d e7b3 429a 26c5 5ea9 a6c1 6633 f2d2 707d 5735 054a f3bc 74a9 597d 708f 052a 3340 6f92 6b9b d8db 5934 3326 8da5 113c dd77 9440 d1b4 e65d 7cd6 b4e2 ebde 9b6f 6fb6 b4c8 abde 0e86 21c5 b8d1 a515 2f69 7b1c c109 6c4e 50f7 879e f73e 88c1 5e7f b19d 8172 03df 4009 a6c0 d602 a3d1 58d9 401e bac0 fa65 9d02 1b57 08e5 8598 5617 4ff8 3c35 3eda 25ae 4204 c27d 99cf 3905 839d 3c56 b0ca 788d 951e 73c1 bd54 fb8d e573 8883 33a4 7e9d 237d 503b 43e6 948d 0cd6 f95f e518 5061 5625 c436 ae31 3346 0763 7890 e662 c5e0 7e9d 8be0 46c2 5ce4 a2a7 316f 8a1f a093 275b dbfd 8edc d778 7c42 6691 ac46 a8dd 98ac 3c9a c606 6e00 7134 7255 98ea dd1c f78c b1e3 5b8c 6ee3 4ec2 fb92 5924 325b fb86 dce9 9832 1717 eb17 7c65 13aa c254 2522 18c1 dee5 1a45 9bd8 8af7 7bff 0050 4b07 08af cce0 d2fb 0100 0034 0400 0050 4b03 0414 0008 0008 006d 572d 4900 0000 0000 0000 0000 0000 003a 0000 0064 6167 6765 722f 696e 7465 726e 616c 2f4d 656d 6265 7273 496e 6a65 6374 6f72 7324 4e6f 4f70 4d65 6d62 6572 7349 6e6a 6563 746f 722e 636c 6173 739d 546b 4f13 4114 3dd3 2e6c bb2c 0fcb 4b5e 8a8a d882 52c0 f2b2 4d03 2198 d4d4 6252 c418 3f0d cb5a 0697 59b3 ddf2 bb04 1221 1a0d 9ffd 51c6 3bd3 aa50 1a4d ba4d 663a 73ce 3df7 dc3b b3fb e3e7 97ef 0016 918b c340 cac2 0c66 4d24 4c3c b1d0 8539 35a4 2dcc 6321 866e 8b18 6945 5b34 f1d4 4486 2156 2895 7736 4a9b 5b0c fd25 7ffb e34b f768 cf0d aa05 79e8 3aa1 1f30 d805 29dd 60d3 e3d5 aa5b 6558 2eee f34a c50d d242 866e 20b9 976e 8aa8 4eb5 90c9 3298 53bb 1bc5 d75b 6586 9577 ed6a 741e 73af a65c ac25 536d 8b18 9bfe becb d05b 14d2 2dd5 14ba c3f7 3cda 31b5 faf6 7b86 17c9 e221 3fe6 698f cb4a ba1c 0642 56b2 a976 f325 8abe c3bd 5d1e 0895 a691 cb90 fcc8 55d8 8d3c 5465 4e48 11e6 1986 5ad8 28a4 7629 3a3c 10d4 8578 5954 240f 6b01 2945 930a e816 3a6f c304 c3e0 5585 ed3d 8565 152f 2664 35e4 d269 b2d0 6010 9e73 bc86 89f0 0abe 256b 47b9 f6fa 90cf fe8e 6b42 7237 f3e7 c981 55f6 6b81 e33e 17aa 5b83 cd29 e654 8c8d 5bea 9a27 6c2c 61d9 c40a 43a6 1d6b 3686 b16a 631c 1326 d66c 3c43 d646 37fa 187a ae17 4ee7 d1ba 0286 0ec7 f325 f91c 48a6 5a75 73f2 7fb6 1896 ae1e 947e d9b2 adae e075 4724 3dd1 2cfd 2a70 1d5f ee8b 50f8 9274 6de7 c075 3e94 fcb0 54f3 3c86 e956 f7e1 e6d6 fa3c 7d22 ba40 e188 ac8f a86e 007d a3aa ddf4 a1e9 401c fd18 2074 9056 f769 568f 750a f619 914b 443f d18a 7a45 63a7 c632 c41f c6ed 063f 8388 deb5 12c6 cc05 3a2e 6128 7ee4 1a7f 8446 bbce c228 c634 4ec7 43a3 5258 4094 7e80 3933 3b7e 8ece 937f 849b b8a3 ace3 aee6 4cd2 de3d 6d58 c9e4 698e a8a8 d90b 986f feaa 587a 7795 ca5c d34a 4375 5643 49fd 7b80 298a 8de1 a156 545a 2bd4 2ef5 8c7d 85f1 3611 8b9e 237e 06cb f846 abe8 295d e533 b093 3f5d a927 58a2 ae66 a88e bab5 693c d273 12bd 9a41 af38 1ea3 677d f417 504b 0708 5822 97d3 9102 0000 dd05 0000 504b 0304 1400 0800 0800 6d57 2d49 0000 0000 0000 0000 0000 0000 1200 0000 6461 6767 6572 2f42 696e 6473 2e63 6c61 7373 8590 bf4e c330 10c6 bf2b b486 52a0 b031 a002 4347 22b1 3281 9a0a 244a 5108 2c4c 6e72 8a5c b90e 4a9c 4a7d 3506 1e80 87aa b874 a04b 242c 9def ecef f79d fffc acbf be01 dce0 54e1 58a1 af70 42e8 bee6 5591 f0d8 5896 c5bd 7169 793d d74b 4d38 8b2a e7cd 82df 4d69 6696 ef9c cbbd f626 7725 e1f2 a966 02ab 5d16 e83f 2118 e549 b560 e739 bd25 5c34 3311 7b21 a412 a4bd d4b6 9273 87ff a02f b935 c94a 0c2a 7a7b 8e1f 2721 e1bc d912 eb22 632f e455 b31e 5aae 2f18 af3e 59a0 ce24 8c1f a623 422f d559 c645 b079 3fa1 bff5 4e67 734e 3c61 d0d8 6efb 2943 02a1 25b1 837a b4b0 bb99 dbe8 481e c8ae 92bc 27fa 3ea3 8b03 f4ea f203 c438 c4d1 2f50 4b07 08bd ac58 36f5 0000 009a 0100 0050 4b03 0414 0008 0008 006d 572d 4900 0000 0000 0000 0000 0000 001a 0000 0064 6167 6765 722f 4d75 6c74 6962 696e 6469 6e67 732e 636c 6173 736d 8f4d 6bc2 4010 86df f12b 6a5b 95e2 c583 94f6 e0b1 815e 3d15 d493 c5a2 4128 3d6d 9261 5959 3725 d915 fad7 7ae8 0ff0 4749 371e 2a42 06e6 03de 8777 668e a79f 5f00 2fe8 07b8 0d70 17a0 47e8 6e32 9727 bc50 9a09 f76f 4e5b 152b 932a 238b e79d 3808 c268 ed8c 557b deaa 42c5 9a5f 8dc9 acb0 2a33 05e1 7159 32a1 1646 86e2 5f08 6759 e2f6 6c2c a753 c2b8 9a89 442e d97a bd79 10da f9e5 4fd5 dc5c 7369 157d 7fb1 871b d1c7 fb9c 304c 8594 9c87 57f7 1206 1787 55bc e3c4 121e 2a4d 2f4f 4c08 849a cf3a caa8 a171 ae4d b47c 1ffa 29f0 bded f5ce 2788 d1c5 cd1f 504b 0708 60bf 608d d700 0000 4701 0000 504b 0304 1400 0800 0800 6d57 2d49 0000 0000 0000 0000 0000 0000 2200 0000 6461 6767 6572 2f6d 756c 7469 6269 6e64 696e 6773 2f4c 6f6e 674b 6579 2e63 6c61 7373 6d90 4d4b c340 1086 df69 d346 6bb5 f5a6 a088 1e44 2f06 bcf6 24b4 229a 52d0 e0c5 d326 1996 2d9b 4d69 3685 fe35 0ffe 007f 9438 9562 2f39 cc07 f3bc ccd7 f7cf e717 807b 1c87 380a 3108 3124 7456 cad6 4c68 dfdc 3e13 7a6f 65bd ccf8 d158 29f5 e3d2 e917 5edf cdd5 4a11 4e5f 6be7 4dc1 efa6 32a9 e507 e74a afbc 295d 45b8 8c37 9ac8 2aa7 23f5 0fa2 7199 d505 3bcf f988 70de ac49 d452 b317 7ed5 cc27 9637 2d92 f582 45d4 9d4e 92a7 d998 3088 73a5 352f a3a9 5ac8 8e82 ceb6 85a2 b6de a4c6 e5c6 e92a dade 4018 eeba cfd2 3967 9e70 d138 7077 d835 81d0 126b cbdb 2820 04e8 48d6 42f7 cf87 d893 7822 745f 624f 74c1 0788 7180 3e0e 815f 504b 0708 37e5 6ca0 f400 0000 6f01 0000 504b 0304 1400 0800 0800 6d57 2d49 0000 0000 0000 0000 0000 0000 2300 0000 6461 6767 6572 2f6d 756c 7469 6269 6e64 696e 6773 2f43 6c61 7373 4b65 792e 636c 6173 736d 9041 4b02 5110 c7ff 63ea a665 5a42 d421 a20e 511d 5ce8 5a04 9146 9022 e4d2 a5d3 d31d 9627 6fdf caee 5bc1 afd6 a10f d087 8a46 a90c dac3 3033 efff e33f 6fe6 e3f3 ed1d c015 da1e 5a1e 763d ec11 2a73 6572 26b4 cf2f fa53 3557 be51 36f2 ef8d cab2 6b42 6da4 23ab 5c9e 0ab1 ff9f b8b9 bc15 a83e 4af2 74c2 0fda 08d5 5809 4fbc e82c 59c2 e173 6e9d 8ef9 4567 7a6c f8ce dac4 29a7 139b 114e fef8 a95f c1ef 2693 3c66 eb38 14f3 a362 2650 69c4 4ef4 d362 bd67 7869 112c 662c 5075 d00b 1e87 5d42 b31f aa28 e2d4 1fa8 99fc 71e9 fffd 10e7 c6e9 b1b6 a1b6 51e6 ff2c 4168 aded 87e3 294f 1ce1 b870 e27a b333 02a1 24b1 21d7 a632 a18c 8a74 55e9 4af0 2436 5755 0d75 c907 426d 49de 16a2 fc0a 6234 b083 26f0 0550 4b07 08ab aa9a 8010 0100 00ae 0100 0050 4b03 0414 0008 0008 006d 572d 4900 0000 0000 0000 0000 0000 0025 0000 0064 6167 6765 722f 6d75 6c74 6962 696e 6469 6e67 732f 4d75 6c74 6962 696e 6473 2e63 6c61 7373 6d4f 3d4b 0341 107d 134d 4ea3 3116 3616 225a 58ba 606b 2524 c1c2 10d0 234d aabd bb61 d9b0 b727 77bb 81fc 350b 7f80 3f4a 9c13 f49a 1b98 0f78 6fe6 bdf9 fafe f804 f080 6982 d304 9304 6784 f15b 15eb 9c17 d631 61ba 8c2e d8cc faa2 b9df ea9d 265c be46 1f6c c96b dbd8 ccf1 93f7 55d0 c156 be21 dcbc b41c e5b4 374a ff03 6a56 e5b1 641f b878 245c f573 525d 1b0e 820f 77da 4551 beed e7cd 1db7 a7d2 fd3b 0b79 b49c a7cf ab19 e1ba d0c6 70ad ca3f bbd6 9b46 75e6 09e7 ddb9 55b6 e53c c852 af42 f7d1 1d81 3090 3c40 1b03 1cfe d621 46d2 2f64 4aa4 1f09 7ebc 0131 c638 f901 504b 0708 09d7 9236 dc00 0000 5101 0000 504b 0304 1400 0800 0800 6d57 2d49 0000 0000 0000 0000 0000 0000 2a00 0000 6461 6767 6572 2f6d 756c 7469 6269 6e64 696e 6773 2f45 6c65 6d65 6e74 7349 6e74 6f53 6574 2e63 6c61 7373 8590 4d4b c340 1086 dfad b6d1 fa55 c58b 07a9 8af4 68c0 6b4f 4253 2c58 2b69 f4e2 6993 0c61 cb66 5792 4da1 7fcd 833f a03f 4a9c 8858 9080 03f3 b1f3 3ecc 2cb3 fe7c ff00 708b 130f 471e 7a1e 8e05 ba73 5b15 098d 9526 81d3 4053 4ec6 9513 e3ec 9cdc cd42 2ea5 c059 5819 a772 7a51 a58a 35dd 1963 9d74 ca9a 52e0 f2a1 667c 2d4d e6cb 5fc1 1fd9 a4aa 2751 3a14 386f 6622 5964 e458 6f2f a5ae 78fd 5533 f7f3 a968 f546 0c77 a641 743f 1b09 5c34 d321 3986 b962 76f0 0ff2 64b5 4a56 0c7a e1f3 6334 9906 02d7 a9cc 322a fcbc d24e c5ca a4ca 64a5 ffe7 2e02 bdcd e059 bca0 845b fdc6 5d9b 630d 0404 5aec 5ba8 ad85 edef d846 8773 9fbb 1ee7 1dd6 775f 2108 5dec 61bf 7e11 0e70 f805 504b 0708 3151 0df1 0401 0000 bc01 0000 504b 0304 1400 0800 0800 6d57 2d49 0000 0000 0000 0000 0000 0000 2200 0000 6461 6767 6572 2f6d 756c 7469 6269 6e64 696e 6773 2f49 6e74 6f53 6574 2e63 6c61 7373 8590 cf4a c340 10c6 bfad b6d1 5ab5 7a13 94aa 871e 0d78 f524 3462 c15a 49a3 174f 9b64 085b 36bb 92ec 16fa 6a1e 7c00 1f4a 9c88 d84b c081 f9fb fd98 81f9 fc7a ff00 708d e300 8701 8601 8e04 fa0b ebab 8cee 9426 81c1 d438 bb20 77b5 942b 2970 127b e354 492f aa56 a9a6 5b63 ac93 4e59 530b 5c3c 344c a8a5 2942 f927 8413 9bf9 928c a3fc 46e0 ac9d 4964 5590 63bd bb92 daf3 d9cb 762e d2d4 ac4a d66f c470 6f16 25f7 f389 c079 3b1d 9363 982b 66c7 ff20 4f56 ab6c cd60 103f 3f26 d359 2470 9acb a2a0 2a2c bd76 2a55 2657 a6a8 c3df 7f08 0c37 0be7 e992 321e 8d5a 6f6c 9e34 1610 e8b0 6fa1 b10e b67f 6217 3dce 239e 069c 7758 df7d 8520 f4b1 8741 d311 f671 f00d 504b 0708 9783 6961 fe00 0000 ac01 0000 504b 0304 1400 0800 0800 6d57 2d49 0000 0000 0000 0000 0000 0000 2100 0000 6461 6767 6572 2f6d 756c 7469 6269 6e64 696e 6773 2f49 6e74 4b65 792e 636c 6173 736d 904d 4bc3 4010 86df 69d3 465b b5f5 a688 881e 442f 06bc 7a12 5ab1 d852 d0e0 c5d3 2619 c296 cda6 24bb 85fe 350f fe00 7f94 3855 b197 1ce6 8379 5ee6 ebf3 ebfd 03c0 2d0e 431c 8418 8418 123a 2b65 3c13 da57 d713 42ef a5f4 55ca 0fda 48a9 3fb1 ee89 d737 0bb5 5284 e367 6f9d 2ef8 55d7 3a31 7c6f 6de9 94d3 a5ad 09e7 d38d 2632 cae6 91fa 07d1 a84c 7dc1 d671 7647 386d d6c4 aaca d909 bf68 e663 c39b 16f1 7ac9 22ea cec6 f1e3 7c44 184c 3395 e75c 4533 b594 1d05 9dfc 150a 6f9c 4eb4 cdb4 cdeb e8f7 04c2 70db 7c9e 2c38 7584 b3c6 79db bb2e 0984 9658 5b9e 4601 2140 47b2 16ba 3f3e c48e c423 a1bb 127b a20b de40 8c3e f6b0 0f7c 0350 4b07 0832 5a85 a4f4 0000 006d 0100 0050 4b03 0414 0008 0008 006d 572d 4900 0000 0000 0000 0000 0000 0022 0000 0064 6167 6765 722f 6d75 6c74 6962 696e 6469 6e67 732f 496e 746f 4d61 702e 636c 6173 7385 90cf 4ac3 4010 c6bf a9b6 d15a b57a 1394 aa87 1e0d 78f5 2434 62c1 5889 d18b a74d 3284 2d9b 4d49 3785 be9a 071f c087 1227 22f6 1270 60fe 7e3f 6660 3ebf de3f 005c e3d8 c3a1 87a1 8723 42ff b9ac ab94 efb4 61c2 606a 5d19 aac5 d55c ad14 e124 aaad d305 bfea a54e 0cdf 5a5b 3ae5 7469 9784 8b87 86f1 8db2 b9af fe04 7f52 a675 c1d6 7176 4338 6b67 6255 e5ec 44ef ae94 a9e5 ec65 3b17 186e 56c5 eb05 0bdc 0b83 f87e 3621 9cb7 d311 3b81 a512 76fc 0ff2 541a 9dae 05f4 a297 c778 1a06 84d3 4ce5 3957 7e51 1ba7 136d 336d f3a5 fffb 0fc2 70b3 7096 cc39 7584 51eb 8dcd 93c6 0442 477c 0b8d 75b0 fd13 bbe8 491e c9d4 93bc 23fa ee1b 88d1 c71e 064d c7d8 c7c1 3750 4b07 0871 fcd5 47fe 0000 00ac 0100 0050 4b03 0414 0008 0008 006d 572d 4900 0000 0000 0000 0000 0000 0024 0000 0064 6167 6765 722f 6d75 6c74 6962 696e 6469 6e67 732f 5374 7269 6e67 4b65 792e 636c 6173 736d 90cf 4ac3 4010 c6bf a969 a355 db0a 1ef4 a0a2 07d1 8b81 5e3d 096d 116c 29d8 e0c5 d326 19c2 96cd a624 9b42 5fcd 830f e043 49a7 2aad 871c 6667 99ef c737 7fbe be3f 3e01 f471 e2a3 e3a3 eba3 4768 2e95 a998 707a 773f 9eab a50a 8cb2 6930 7385 b6e9 23a1 3dcb ab22 e691 36c2 747e cb2f bc7a d8a0 84f3 d7ca 3a9d f19b 2e75 64f8 c9da dc29 a773 5b12 aeff d9a9 ad10 0cf2 b8ca d83a 4ec4 fda2 9e09 5591 b213 fda6 5e1f 1ade 5884 ab05 0bd4 9a0c c3e7 e980 d01d 272a 4db9 0826 6a21 338a 74f9 57c8 2ae3 74a4 6d22 d397 c176 0b42 6fe7 3f8d e61c 3bc2 556d cbdd 6ab7 0442 4362 4f6e 491e c143 537e 0db4 7e5e 1ffb 92cf 443d 90dc 16ce 7b07 310e 7184 6360 0d50 4b07 086d a4a0 7efc 0000 0084 0100 0050 4b03 0414 0008 0008 006d 572d 4900 0000 0000 0000 0000 0000 001c 0000 0064 6167 6765 722f 4269 6e64 734f 7074 696f 6e61 6c4f 662e 636c 6173 736d 8fcd 6ac2 5010 85cf 6835 6aeb cf42 0417 a5b4 8b2e 1be8 d695 a2d2 8525 a0a1 9bae c664 1aae 5c6f 24b9 117c b52e fa00 3e54 e94d 1715 4a06 e607 cec7 9999 f3f7 e717 8067 f43d dc78 e87a e811 3a9b b4c8 2259 2a2d 84e1 4c99 380f 0e56 a586 75f0 f1b4 e323 13c6 ebc2 58b5 9737 95ab ad96 a931 a9e5 92c9 09f7 ab92 f135 9bc4 e73f c19f a751 b117 6325 9e10 6eab 9990 b344 acd3 1b47 d685 5bff 50cd 2db4 9456 e1e9 200e 6ebe 2ec2 9760 4e18 c59c 2492 f9ff 6e26 0c2e 2ec1 7627 9125 dc55 1a5f 1e79 2410 6a2e eb28 a386 abdf da40 d3f5 a19b 3cd7 5b4e 6fbf 8304 1d5c ff00 504b 0708 2615 5f0f db00 0000 4d01 0000 504b 0304 0a00 0000 0000 6e57 2d49 0000 0000 0000 0000 0000 0000 0f00 0000 4d45 5441 2d49 4e46 2f6d 6176 656e 2f50 4b03 040a 0000 0000 006e 572d 4900 0000 0000 0000 0000 0000 0021 0000 004d 4554 412d 494e 462f 6d61 7665 6e2f 636f 6d2e 676f 6f67 6c65 2e64 6167 6765 722f 504b 0304 0a00 0000 0000 6e57 2d49 0000 0000 0000 0000 0000 0000 2800 0000 4d45 5441 2d49 4e46 2f6d 6176 656e 2f63 6f6d 2e67 6f6f 676c 652e 6461 6767 6572 2f64 6167 6765 722f 504b 0304 1400 0800 0800 5257 2d49 0000 0000 0000 0000 0000 0000 2f00 0000 4d45 5441 2d49 4e46 2f6d 6176 656e 2f63 6f6d 2e67 6f6f 676c 652e 6461 6767 6572 2f64 6167 6765 722f 706f 6d2e 786d 6cb5 565d 77db 360c 7df7 afc0 fcd4 6e11 65a7 3d69 9729 eaf1 92f4 cc6d eaf4 c4c9 ba3e f530 122c 3395 4895 a46c e7df 0fd4 8723 d94e d276 8b5f 6c80 2070 015c 800e deac b214 16a8 8d50 f2a8 3f64 833e a08c 542c 6472 d4bf ba7c ebbd eebf 097b c12f 9ed7 8363 95df 6a91 cc2d 3c3b 7e0e fb83 e13e 4cbf 155c e31e 8c65 c47a 3d80 3311 a134 1843 2163 d460 e708 a39c 47f4 559f ecc1 df55 30d8 6703 78e6 0cfa f551 fff9 1fe4 e156 1590 f15b 90ca 4261 905c 0803 3391 22e0 2ac2 dc82 9010 a92c 4f05 9711 c252 d879 19a6 76c2 c8c5 e7da 85ba b69c ac39 d9e7 24cd da76 c0ad c35b 7ee6 d6e6 87be bf5c 2e19 2fc1 32a5 133f ad0c 8d7f 363e 3e9d 4c4f 3d02 ecae 5cc9 148d 018d df0a a129 d3eb 5be0 39c1 89f8 3581 4cf9 1294 069e 68a4 33ab 1cdc a516 96ea b907 46cd ec92 ea45 5e62 61ac 16d7 85ed d4aa 0147 29b7 0da8 5a5c 427f 3485 f1b4 0f7f 8ea6 e3e9 1ef9 f834 befc ebfc ea12 3e8d 2e2e 4693 cbf1 e914 ce2f e0f8 7c72 32be 1c9f 4f48 7a0b a3c9 6778 3f9e 9cec 0152 a528 0cae 72ed f013 48e1 aa88 b12b d914 b103 60a6 2a40 26c7 48cc 4444 79c9 a4e0 0942 a288 2d92 d281 1c75 268c eba5 2178 3179 4945 262c b7a5 662b 29d6 f33c 6252 aed5 0d46 1688 77d2 1cf5 ebda 677c 81b2 5dfd 8fe7 1ffc 976c e0f8 585a 1eae 8c58 5bbb 4e2d 5f94 76fb 83c1 d0ff e7c3 d994 2e66 dc13 d258 c70b ba65 c4a1 2995 672a 2a31 7d47 30b8 cfa2 5478 8b97 5f06 5f06 6c65 e27e 48e9 0699 8a31 adf9 1c96 0e02 bfa3 737c 0972 eab8 b461 c9b6 20d1 aac8 c771 4814 6689 5249 8a2c e649 823a f09b a3ca 906b 2b66 3cb2 a4a8 0cbc ca4f e0b7 4e2a d37a 7cc3 7df6 2af0 1bc1 45f6 9bd0 bd5d 0e37 3d05 9267 189e d467 a550 e1d7 8a5a 6d05 9a3a 1e2d 03b8 28a4 1519 4256 184b b390 b941 7bc7 17fc c071 de14 79ae b475 acd0 4ac4 0c5c e7cb ab37 64c2 1a88 4376 10f8 1d4d 05ba 15cf 2962 cc91 c824 a33b 046b d56d 580f f1ba b0ce df8a 09e9 48b6 51d3 6e11 ba86 5b45 f5db 311e 8dda 6a27 8dc9 823f 18b9 b6d8 0c49 4686 3615 8616 0d21 aa7e ef00 f368 050a 291e 49bd b278 2a00 ad62 585d d8f9 8358 6a8b 9fc7 d292 d794 b92e 44da 3432 4f8b 84d6 c2da 6d25 3762 0b36 cd39 a397 0fe7 bc30 2c53 376a 0b77 1739 9722 e3a9 67a4 98cd 683c ab15 5179 df95 4f6b 5087 ecf5 dda0 96e3 3464 bfff d63c 2906 de9d bc7f e596 bedb 9e65 2af4 9c45 7321 713d 48a5 3b5c 6154 94db f64e d956 b7b5 a417 7158 62f5 782e 025f c41b c789 e2a9 09cb af90 d65e f495 d277 bfab af6e 087f 478c 96b2 651c 444a ce44 5268 be89 2830 2291 dc16 1a37 81dc d70f b6be b1a3 335b 1ca7 191b 1eec 6ec4 4633 069d ad79 97cf 0e80 81bf 331f 5a5a 1d56 6d93 ac05 a322 8ac3 17ab e861 c2dc 5f3c fa33 9416 317e e4d1 577a 9527 b4ac 4dbd d669 a559 7aa1 797a b821 b35f 5d8b b6af 3d41 7246 153a c287 73fb 71f6 726b 690c 6ae7 6607 85f3 3937 1826 2891 3240 8f46 a931 ad4e 7611 bea3 abb5 441e ed49 e5d1 bfa0 660a ba57 ffc3 48fc 1455 f4ff 5aca 0712 77db d6c5 7bda ac1b c954 fbbb ded6 e5cb ef5e e3b0 f72f 504b 0708 57e6 18dc 3904 0000 970c 0000 504b 0304 1400 0800 0800 6d57 2d49 0000 0000 0000 0000 0000 0000 3600 0000 4d45 5441 2d49 4e46 2f6d 6176 656e 2f63 6f6d 2e67 6f6f 676c 652e 6461 6767 6572 2f64 6167 6765 722f 706f 6d2e 7072 6f70 6572 7469 6573 5376 4fcd 4b2d 4a2c 494d 5148 aa54 f04d 2c4b cde3 520e 294d 5508 4e2d 5030 3456 3034 b032 b5b4 3232 5370 7509 5130 3230 34e3 2a4b 2d2a cecc cfb3 35d2 33e7 4a2f ca2f 2df0 4cb1 4dce cfd5 4bcf cf4f cf49 d54b 494c 4f4f 2de2 4a2c 2ac9 4c4b 4c2e 014a 4245 0050 4b07 0837 c687 4b65 0000 006a 0000 0050 4b01 0214 030a 0000 0000 006e 572d 4900 0000 0000 0000 0000 0000 0009 0000 0000 0000 0000 0010 00ed 4100 0000 004d 4554 412d 494e 462f 504b 0102 1403 1400 0800 0800 6d57 2d49 92ab 04aa 7700 0000 8e00 0000 1400 0000 0000 0000 0000 0000 a481 2700 0000 4d45 5441 2d49 4e46 2f4d 414e 4946 4553 542e 4d46 504b 0102 1403 0a00 0000 0000 6d57 2d49 0000 0000 0000 0000 0000 0000 0700 0000 0000 0000 0000 1000 e841 e000 0000 6461 6767 6572 2f50 4b01 0214 030a 0000 0000 006d 572d 4900 0000 0000 0000 0000 0000 0010 0000 0000 0000 0000 0010 00e8 4105 0100 0064 6167 6765 722f 696e 7465 726e 616c 2f50 4b01 0214 030a 0000 0000 006d 572d 4900 0000 0000 0000 0000 0000 0015 0000 0000 0000 0000 0010 00e8 4133 0100 0064 6167 6765 722f 6d75 6c74 6962 696e 6469 6e67 732f 504b 0102 1403 1400 0800 0800 6d57 2d49 a793 c40e e000 0000 5f01 0000 1500 0000 0000 0000 0000 0000 a081 6601 0000 6461 6767 6572 2f52 6575 7361 626c 652e 636c 6173 7350 4b01 0214 0314 0008 0008 006d 572d 4920 bb6a c865 0100 0083 0200 0016 0000 0000 0000 0000 0000 00a0 8189 0200 0064 6167 6765 722f 436f 6d70 6f6e 656e 742e 636c 6173 7350 4b01 0214 0314 0008 0008 006d 572d 49af 188f 3446 0100 004b 0200 0015 0000 0000 0000 0000 0000 00a0 8132 0400 0064 6167 6765 722f 5072 6f76 6964 6573 2e63 6c61 7373 504b 0102 1403 1400 0800 0800 6d57 2d49 e17c d960 a000 0000 f600 0000 1c00 0000 0000 0000 0000 0000 a081 bb05 0000 6461 6767 6572 2f4d 656d 6265 7273 496e 6a65 6374 6f72 2e63 6c61 7373 504b 0102 1403 1400 0800 0800 6d57 2d49 aaea 0589 f800 0000 8601 0000 1e00 0000 0000 0000 0000 0000 a081 a506 0000 6461 6767 6572 2f43 6f6d 706f 6e65 6e74 2442 7569 6c64 6572 2e63 6c61 7373 504b 0102 1403 1400 0800 0800 6d57 2d49 d9cb 77cd fc00 0000 8f01 0000 2100 0000 0000 0000 0000 0000 a081 e907 0000 6461 6767 6572 2f53 7562 636f 6d70 6f6e 656e 7424 4275 696c 6465 722e 636c 6173 7350 4b01 0214 0314 0008 0008 006d 572d 49e5 eb58 8392 0000 00d4 0000 0011 0000 0000 0000 0000 0000 00a0 8134 0900 0064 6167 6765 722f 4c61 7a79 2e63 6c61 7373 504b 0102 1403 1400 0800 0800 6d57 2d49 4c14 e3b0 2501 0000 e301 0000 1300 0000 0000 0000 0000 0000 a081 050a 0000 6461 6767 6572 2f4d 6170 4b65 792e 636c 6173 7350 4b01 0214 0314 0008 0008 006d 572d 49f2 ed6e 4d5b 0100 0064 0200 0019 0000 0000 0000 0000 0000 00a0 816b 0b00 0064 6167 6765 722f 5375 6263 6f6d 706f 6e65 6e74 2e63 6c61 7373 504b 0102 1403 1400 0800 0800 6d57 2d49 12ab 3334 6002 0000 4d04 0000 1a00 0000 0000 0000 0000 0000 a081 0d0d 0000 6461 6767 6572 2f50 726f 7669 6465 7324 5479 7065 2e63 6c61 7373 504b 0102 1403 1400 0800 0800 6d57 2d49 09f5 1b5c 3601 0000 1002 0000 1300 0000 0000 0000 0000 0000 a081 b50f 0000 6461 6767 6572 2f4d 6f64 756c 652e 636c 6173 7350 4b01 0214 0314 0008 0008 006d 572d 49da e884 49d1 0000 0044 0100 001a 0000 0000 0000 0000 0000 00a0 812c 1100 0064 6167 6765 722f 696e 7465 726e 616c 2f42 6574 612e 636c 6173 7350 4b01 0214 0314 0008 0008 006d 572d 49c0 5b0e eb95 0100 0018 0300 0022 0000 0000 0000 0000 0000 00a0 8145 1200 0064 6167 6765 722f 696e 7465 726e 616c 2f53 6574 4661 6374 6f72 7924 312e 636c 6173 7350 4b01 0214 0314 0008 0008 006d 572d 4931 3fd9 d100 0300 00a8 0600 0024 0000 0000 0000 0000 0000 00a0 812a 1400 0064 6167 6765 722f 696e 7465 726e 616c 2f50 726f 7669 6465 724f 664c 617a 792e 636c 6173 7350 4b01 0214 0314 0008 0008 006d 572d 4935 13b6 5ba0 0000 00e7 0000 001d 0000 0000 0000 0000 0000 00a0 817c 1700 0064 6167 6765 722f 696e 7465 726e 616c 2f46 6163 746f 7279 2e63 6c61 7373 504b 0102 1403 1400 0800 0800 6d57 2d49 f2ad fb42 4906 0000 6f0e 0000 2000 0000 0000 0000 0000 0000 a081 6718 0000 6461 6767 6572 2f69 6e74 6572 6e61 6c2f 5365 7446 6163 746f 7279 2e63 6c61 7373 504b 0102 1403 1400 0800 0800 6d57 2d49 c610 677f aa03 0000 3107 0000 2700 0000 0000 0000 0000 0000 a081 fe1e 0000 6461 6767 6572 2f69 6e74 6572 6e61 6c2f 4461 6767 6572 436f 6c6c 6563 7469 6f6e 732e 636c 6173 7350 4b01 0214 0314 0008 0008 006d 572d 4911 b043 bc60 0200 00d9 0500 0026 0000 0000 0000 0000 0000 00a0 81fd 2200 0064 6167 6765 722f 696e 7465 726e 616c 2f4d 656d 6265 7273 496e 6a65 6374 6f72 732e 636c 6173 7350 4b01 0214 0314 0008 0008 006d 572d 4976 1346 0883 0000 00a6 0000 0025 0000 0000 0000 0000 0000 00a0 81b1 2500 0064 6167 6765 722f 696e 7465 726e 616c 2f47 7774 496e 636f 6d70 6174 6962 6c65 2e63 6c61 7373 504b 0102 1403 1400 0800 0800 6d57 2d49 f24b 808a 1504 0000 8609 0000 2000 0000 0000 0000 0000 0000 a081 8726 0000 6461 6767 6572 2f69 6e74 6572 6e61 6c2f 4d61 7046 6163 746f 7279 2e63 6c61 7373 504b 0102 1403 1400 0800 0800 6d57 2d49 3aae 138a 3902 0000 8404 0000 2500 0000 0000 0000 0000 0000 a081 ea2a 0000 6461 6767 6572 2f69 6e74 6572 6e61 6c2f 4465 6c65 6761 7465 4661 6374 6f72 792e 636c 6173 7350 4b01 0214 0314 0008 0008 006d 572d 49a0 a44e f73c 0300 00c2 0800 0028 0000 0000 0000 0000 0000 00a0 8176 2d00 0064 6167 6765 722f 696e 7465 726e 616c 2f4d 6170 5072 6f76 6964 6572 4661 6374 6f72 792e 636c 6173 7350 4b01 0214 0314 0008 0008 006d 572d 499e 2bca 1358 0400 00aa 0a00 0028 0000 0000 0000 0000 0000 00a0 8108 3100 0064 6167 6765 722f 696e 7465 726e 616c 2f53 6574 4661 6374 6f72 7924 4275 696c 6465 722e 636c 6173 7350 4b01 0214 0314 0008 0008 006d 572d 49cb cfd5 135a 0300 00e0 0600 0021 0000 0000 0000 0000 0000 00a0 81b6 3500 0064 6167 6765 722f 696e 7465 726e 616c 2f53 696e 676c 6543 6865 636b 2e63 6c61 7373 504b 0102 1403 1400 0800 0800 6d57 2d49 afd7 a3c4 7903 0000 4a08 0000 3000 0000 0000 0000 0000 0000 a081 5f39 0000 6461 6767 6572 2f69 6e74 6572 6e61 6c2f 4d61 7050 726f 7669 6465 7246 6163 746f 7279 2442 7569 6c64 6572 2e63 6c61 7373 504b 0102 1403 1400 0800 0800 6d57 2d49 a1b6 d43f ee04 0000 140a 0000 2100 0000 0000 0000 0000 0000 a081 363d 0000 6461 6767 6572 2f69 6e74 6572 6e61 6c2f 446f 7562 6c65 4368 6563 6b2e 636c 6173 7350 4b01 0214 0314 0008 0008 006d 572d 4923 486b 25d8 0100 00a7 0300 0023 0000 0000 0000 0000 0000 00a0 8173 4200 0064 6167 6765 722f 696e 7465 726e 616c 2f50 7265 636f 6e64 6974 696f 6e73 2e63 6c61 7373 504b 0102 1403 1400 0800 0800 6d57 2d49 7b4a aef7 a700 0000 ea00 0000 2a00 0000 0000 0000 0000 0000 a081 9c44 0000 6461 6767 6572 2f69 6e74 6572 6e61 6c2f 4d61 7050 726f 7669 6465 7246 6163 746f 7279 2431 2e63 6c61 7373 504b 0102 1403 1400 0800 0800 6d57 2d49 afcc e0d2 fb01 0000 3404 0000 2500 0000 0000 0000 0000 0000 a081 9b45 0000 6461 6767 6572 2f69 6e74 6572 6e61 6c2f 496e 7374 616e 6365 4661 6374 6f72 792e 636c 6173 7350 4b01 0214 0314 0008 0008 006d 572d 4958 2297 d391 0200 00dd 0500 003a 0000 0000 0000 0000 0000 00a0 81e9 4700 0064 6167 6765 722f 696e 7465 726e 616c 2f4d 656d 6265 7273 496e 6a65 6374 6f72 7324 4e6f 4f70 4d65 6d62 6572 7349 6e6a 6563 746f 722e 636c 6173 7350 4b01 0214 0314 0008 0008 006d 572d 49bd ac58 36f5 0000 009a 0100 0012 0000 0000 0000 0000 0000 00a0 81e2 4a00 0064 6167 6765 722f 4269 6e64 732e 636c 6173 7350 4b01 0214 0314 0008 0008 006d 572d 4960 bf60 8dd7 0000 0047 0100 001a 0000 0000 0000 0000 0000 00a0 8117 4c00 0064 6167 6765 722f 4d75 6c74 6962 696e 6469 6e67 732e 636c 6173 7350 4b01 0214 0314 0008 0008 006d 572d 4937 e56c a0f4 0000 006f 0100 0022 0000 0000 0000 0000 0000 00a0 8136 4d00 0064 6167 6765 722f 6d75 6c74 6962 696e 6469 6e67 732f 4c6f 6e67 4b65 792e 636c 6173 7350 4b01 0214 0314 0008 0008 006d 572d 49ab aa9a 8010 0100 00ae 0100 0023 0000 0000 0000 0000 0000 00a0 817a 4e00 0064 6167 6765 722f 6d75 6c74 6962 696e 6469 6e67 732f 436c 6173 734b 6579 2e63 6c61 7373 504b 0102 1403 1400 0800 0800 6d57 2d49 09d7 9236 dc00 0000 5101 0000 2500 0000 0000 0000 0000 0000 a081 db4f 0000 6461 6767 6572 2f6d 756c 7469 6269 6e64 696e 6773 2f4d 756c 7469 6269 6e64 732e 636c 6173 7350 4b01 0214 0314 0008 0008 006d 572d 4931 510d f104 0100 00bc 0100 002a 0000 0000 0000 0000 0000 00a0 810a 5100 0064 6167 6765 722f 6d75 6c74 6962 696e 6469 6e67 732f 456c 656d 656e 7473 496e 746f 5365 742e 636c 6173 7350 4b01 0214 0314 0008 0008 006d 572d 4997 8369 61fe 0000 00ac 0100 0022 0000 0000 0000 0000 0000 00a0 8166 5200 0064 6167 6765 722f 6d75 6c74 6962 696e 6469 6e67 732f 496e 746f 5365 742e 636c 6173 7350 4b01 0214 0314 0008 0008 006d 572d 4932 5a85 a4f4 0000 006d 0100 0021 0000 0000 0000 0000 0000 00a0 81b4 5300 0064 6167 6765 722f 6d75 6c74 6962 696e 6469 6e67 732f 496e 744b 6579 2e63 6c61 7373 504b 0102 1403 1400 0800 0800 6d57 2d49 71fc d547 fe00 0000 ac01 0000 2200 0000 0000 0000 0000 0000 a081 f754 0000 6461 6767 6572 2f6d 756c 7469 6269 6e64 696e 6773 2f49 6e74 6f4d 6170 2e63 6c61 7373 504b 0102 1403 1400 0800 0800 6d57 2d49 6da4 a07e fc00 0000 8401 0000 2400 0000 0000 0000 0000 0000 a081 4556 0000 6461 6767 6572 2f6d 756c 7469 6269 6e64 696e 6773 2f53 7472 696e 674b 6579 2e63 6c61 7373 504b 0102 1403 1400 0800 0800 6d57 2d49 2615 5f0f db00 0000 4d01 0000 1c00 0000 0000 0000 0000 0000 a081 9357 0000 6461 6767 6572 2f42 696e 6473 4f70 7469 6f6e 616c 4f66 2e63 6c61 7373 504b 0102 1403 0a00 0000 0000 6e57 2d49 0000 0000 0000 0000 0000 0000 0f00 0000 0000 0000 0000 1000 ed41 b858 0000 4d45 5441 2d49 4e46 2f6d 6176 656e 2f50 4b01 0214 030a 0000 0000 006e 572d 4900 0000 0000 0000 0000 0000 0021 0000 0000 0000 0000 0010 00ed 41e5 5800 004d 4554 412d 494e 462f 6d61 7665 6e2f 636f 6d2e 676f 6f67 6c65 2e64 6167 6765 722f 504b 0102 1403 0a00 0000 0000 6e57 2d49 0000 0000 0000 0000 0000 0000 2800 0000 0000 0000 0000 1000 ed41 2459 0000 4d45 5441 2d49 4e46 2f6d 6176 656e 2f63 6f6d 2e67 6f6f 676c 652e 6461 6767 6572 2f64 6167 6765 722f 504b 0102 1403 1400 0800 0800 5257 2d49 57e6 18dc 3904 0000 970c 0000 2f00 0000 0000 0000 0000 0000 a081 6a59 0000 4d45 5441 2d49 4e46 2f6d 6176 656e 2f63 6f6d 2e67 6f6f 676c 652e 6461 6767 6572 2f64 6167 6765 722f 706f 6d2e 786d 6c50 4b01 0214 0314 0008 0008 006d 572d 4937 c687 4b65 0000 006a 0000 0036 0000 0000 0000 0000 0000 00a0 8100 5e00 004d 4554 412d 494e 462f 6d61 7665 6e2f 636f 6d2e 676f 6f67 6c65 2e64 6167 6765 722f 6461 6767 6572 2f70 6f6d 2e70 726f 7065 7274 6965 7350 4b05 0600 0000 0033 0033 005c 0f00 00c9 5e00 0000 00 javax.inject-1.jar 504b 0304 0a00 0000 0000 e280 4d3b 0000 0000 0000 0000 0000 0000 0600 0400 6a61 7661 782f feca 0000 504b 0304 0a00 0000 0000 e280 4d3b 0000 0000 0000 0000 0000 0000 0d00 0000 6a61 7661 782f 696e 6a65 6374 2f50 4b03 0414 0008 0008 00e2 804d 3b00 0000 0000 0000 0000 0000 0019 0000 006a 6176 6178 2f69 6e6a 6563 742f 496e 6a65 6374 2e63 6c61 7373 8590 cd4e 0231 1485 4f41 1805 7f50 dcb8 30fe 2c48 dc38 71ed cac0 1027 01c6 0c83 1b57 65bc 2125 a543 a043 e4d5 5cf8 003e 94f1 1612 d94c 6293 9e36 e77e f7b4 b9df 3f9f 5f00 1e70 eee1 d4c3 9987 a640 6d98 e58b 94ba 4a93 403d 3453 4aed fd54 aea4 c045 9c1b ab66 f4aa 966a ace9 c998 cc4a ab32 b314 b8ec 39c6 d7d2 4c7c f957 f013 b998 907d 14a8 aca4 ce39 f1b6 980b 34cd c8d8 643d 2786 abfd 2079 8e3a fc7e 3b1a 0c93 78d4 4ea2 9833 ba61 d063 f7ba 3823 26cb 117c e384 d63f c84b a655 ba66 d08b 4783 24ec 0702 37c5 2d9d 2ccd ddd7 e89d e9a6 433e 7cb5 998a bf1d 8e40 63d7 188d b7d6 5561 d66e 622d 0181 12ef 32dc 2a61 6fa3 1554 f9bc 63d7 e3da fe1b ca84 03d4 9cd4 9d1c e2c8 f984 639c a001 fc02 504b 0708 b535 3b38 0e01 0000 c201 0000 504b 0304 1400 0800 0800 e280 4d3b 0000 0000 0000 0000 0000 0000 1800 0000 6a61 7661 782f 696e 6a65 6374 2f4e 616d 6564 2e63 6c61 7373 8590 4d4b c340 1086 df69 53a3 f1ab ad0a 7a52 2f45 2f06 cf9e 0a55 10b4 6aaa deb7 e9b4 6cd9 6c20 d92d fad7 7af0 07f8 a3c4 690f 46a1 e061 9819 e679 e7eb f36b fe01 e012 7b21 9a21 5a21 da84 c64c 19cf 84fd b3f3 bba9 9aa9 d828 3b89 07ae d076 7245 6875 adcd 9d72 3ab7 3d1e 2b6f 1c01 8468 90fb 22e5 1b6d 441a f555 c6a3 8b85 9a70 9478 eb74 c6af bad4 43c3 95bc 241c 2e27 bcc5 da4e 3975 f193 5746 8f35 1732 e7f4 d770 f5a3 897b 79ea 33b6 8e47 c29c ac66 1276 4248 2448 e71f e431 373a 7d17 304c 5efa cfb7 f7d7 84f6 9f9d 96a7 109a 559b 87e1 a240 385e d9b9 baaf 43f2 979a 585d 7e4c 0121 4043 b235 c9ea 2542 29ad 4b58 c306 22f1 0782 6d8a df12 db16 2c60 ec60 f71b 504b 0708 0129 6a2f 0201 0000 a201 0000 504b 0304 1400 0800 0800 e280 4d3b 0000 0000 0000 0000 0000 0000 1b00 0000 6a61 7661 782f 696e 6a65 6374 2f50 726f 7669 6465 722e 636c 6173 733b f56f d73e 0606 0643 061e 7606 2e76 066e 4606 e6f4 d412 4606 110d 4d9f acc4 b244 fd9c c4bc 747d ffa4 acd4 e412 6b46 06ce e0cc f4bc c492 d2a2 5446 0656 0dcd 9010 a098 864d 8815 a65a 3b6c dab9 82f3 4b8b 9253 dd32 7380 fa79 038a f2cb 3253 528b f440 2a19 1944 4154 857e 661e 48b1 3e4c 9291 4100 dd20 3646 0646 0626 0610 6064 013a 9881 05c8 6705 f298 18d8 8018 c262 67e0 00d3 9c00 504b 0708 c544 1750 9700 0000 e200 0000 504b 0304 1400 0800 0800 e280 4d3b 0000 0000 0000 0000 0000 0000 1c00 0000 6a61 7661 782f 696e 6a65 6374 2f51 7561 6c69 6669 6572 2e63 6c61 7373 8590 cd4a c340 1485 cf54 6bb4 6a7f 5c08 2ea4 eaa2 4b83 6b57 012b 146a 52e3 2888 0b99 c66b 9932 9d94 7452 ecab b9f0 017c 28f1 8e8b 7613 70e0 cedf f9ce e172 bf7f 3ebf 005c e128 402b 403b 4047 a0f1 9097 4546 b7da 9040 f3be 5446 bf6b 2a2e a76a a904 4ed2 d23a 3da3 27bd d063 4391 b5b9 534e e776 2170 3af4 4c68 949d 846a 2d84 5215 1372 d702 f5a5 3225 875e 5473 7d43 33b2 4eae e6c4 702b 8ae3 4446 7290 c4af f279 d417 38ab b6a5 e4d8 c537 36f5 fe41 46b9 d1d9 8ac1 207d 8ce5 e08e 53cf ab2d 3779 56fa 6ee8 8de9 638f 7c84 da4e 2973 e17a 2402 ed8d 3719 7b51 a05b 19b7 9953 4f40 a0c6 b505 bf6a d8fe dbeb d8e1 b3cb bf01 6bbb 2f10 843d 34b0 ef5f 8403 1ca2 09fc 0250 4b07 081f c5b9 9903 0100 00b1 0100 0050 4b03 0414 0008 0008 00e2 804d 3b00 0000 0000 0000 0000 0000 0018 0000 006a 6176 6178 2f69 6e6a 6563 742f 5363 6f70 652e 636c 6173 7385 90cd 4e02 3114 854f 511c c51f 909d 0b83 ba60 e9c4 b5ab 49c0 8404 66c8 584d 8c0b 53c6 1b52 525a 021d 22af e6c2 07f0 a18c b72c 6433 894d dadb dbf3 9d93 e67e ff7c 7e01 b843 3b42 3342 2bc2 b940 e3d1 95cb 821e b4a1 d014 6e41 b733 b556 0217 7969 bd9e d3b3 5ee9 89a1 c45a e795 d7ce ae04 2e87 8189 8db2 d358 fd09 b154 cb29 f97b 81fa 5a99 9203 6faa b9be a139 592f 370b 62b8 99a4 6926 1339 c8d2 37f9 32ee 0b5c 55db 72f2 ece2 1b9b baff 2063 6774 b161 30ca 9f52 3918 71ea 75b5 a5e7 8a32 fc86 de99 6e07 e423 d676 4685 8fb7 e310 68ed 7cd9 2408 029d caa8 dd8c ba02 0235 de7b 08ab 86fd ed59 c701 d70e bf46 ac1d be42 108e d0c0 71e8 0827 38c5 19f0 0b50 4b07 085a 8dc7 16fe 0000 00a9 0100 0050 4b03 0414 0008 0008 00e2 804d 3b00 0000 0000 0000 0000 0000 001c 0000 006a 6176 6178 2f69 6e6a 6563 742f 5369 6e67 6c65 746f 6e2e 636c 6173 7385 8fcb 4a43 410c 86ff 54eb 68d5 da85 0aae d44d 970e ae5d 15aa 2078 e31c 753f 1d43 9932 cd88 9d53 eaab b9f0 017c 2831 a7a0 a550 3090 0bc9 97f0 e7eb fbe3 13c0 393a 06bb 066d 833d 42ab 4cd5 9be7 ab10 99d0 2e83 0c23 e724 6723 3775 84a3 a292 1cc6 fc1c 2661 10b9 2792 b2cb 21c9 84b0 7f53 3333 1b64 c43e dbd2 a757 be20 9cce db36 3a19 5af7 c7db 7ef2 d598 25f3 8b32 27ab 9982 b312 5a29 d29c ba58 a9a4 ee3f e843 8ac1 bfeb 8229 9eee 1eaf 6f2f 0987 cbba 7e5f 2274 16a7 ee07 f590 70bc f2fa e2cf 2e81 d050 5f43 6d0d accf 6313 1b9a 0fb4 6b34 6faa 6f29 d362 6c63 e707 504b 0708 59b1 1c4b dd00 0000 6701 0000 504b 0102 0a00 0a00 0000 0000 e280 4d3b 0000 0000 0000 0000 0000 0000 0600 0400 0000 0000 0000 0000 0000 0000 0000 6a61 7661 782f feca 0000 504b 0102 0a00 0a00 0000 0000 e280 4d3b 0000 0000 0000 0000 0000 0000 0d00 0000 0000 0000 0000 0000 0000 2800 0000 6a61 7661 782f 696e 6a65 6374 2f50 4b01 0214 0014 0008 0008 00e2 804d 3bb5 353b 380e 0100 00c2 0100 0019 0000 0000 0000 0000 0000 0000 0053 0000 006a 6176 6178 2f69 6e6a 6563 742f 496e 6a65 6374 2e63 6c61 7373 504b 0102 1400 1400 0800 0800 e280 4d3b 0129 6a2f 0201 0000 a201 0000 1800 0000 0000 0000 0000 0000 0000 a801 0000 6a61 7661 782f 696e 6a65 6374 2f4e 616d 6564 2e63 6c61 7373 504b 0102 1400 1400 0800 0800 e280 4d3b c544 1750 9700 0000 e200 0000 1b00 0000 0000 0000 0000 0000 0000 f002 0000 6a61 7661 782f 696e 6a65 6374 2f50 726f 7669 6465 722e 636c 6173 7350 4b01 0214 0014 0008 0008 00e2 804d 3b1f c5b9 9903 0100 00b1 0100 001c 0000 0000 0000 0000 0000 0000 00d0 0300 006a 6176 6178 2f69 6e6a 6563 742f 5175 616c 6966 6965 722e 636c 6173 7350 4b01 0214 0014 0008 0008 00e2 804d 3b5a 8dc7 16fe 0000 00a9 0100 0018 0000 0000 0000 0000 0000 0000 001d 0500 006a 6176 6178 2f69 6e6a 6563 742f 5363 6f70 652e 636c 6173 7350 4b01 0214 0014 0008 0008 00e2 804d 3b59 b11c 4bdd 0000 0067 0100 001c 0000 0000 0000 0000 0000 0000 0061 0600 006a 6176 6178 2f69 6e6a 6563 742f 5369 6e67 6c65 746f 6e2e 636c 6173 7350 4b05 0600 0000 0008 0008 0023 0200 0088 0700 0000 00 nineoldandroids-2.4.0.jar 504b 0304 0a00 0000 0000 e280 4d3b 0000 0000 0000 0000 0000 0000 0600 0400 6a61 7661 782f feca 0000 504b 0304 0a00 0000 0000 e280 4d3b 0000 0000 0000 0000 0000 0000 0d00 0000 6a61 7661 782f 696e 6a65 6374 2f50 4b03 0414 0008 0008 00e2 804d 3b00 0000 0000 0000 0000 0000 0019 0000 006a 6176 6178 2f69 6e6a 6563 742f 496e 6a65 6374 2e63 6c61 7373 8590 cd4e 0231 1485 4f41 1805 7f50 dcb8 30fe 2c48 dc38 71ed cac0 1027 01c6 0c83 1b57 65bc 2125 a543 a043 e4d5 5cf8 003e 94f1 1612 d94c 6293 9e36 e77e f7b4 b9df 3f9f 5f00 1e70 eee1 d4c3 9987 a640 6d98 e58b 94ba 4a93 403d 3453 4aed fd54 aea4 c045 9c1b ab66 f4aa 966a ace9 c998 cc4a ab32 b314 b8ec 39c6 d7d2 4c7c f957 f013 b998 907d 14a8 aca4 ce39 f1b6 980b 34cd c8d8 643d 2786 abfd 2079 8e3a fc7e 3b1a 0c93 78d4 4ea2 9833 ba61 d063 f7ba 3823 26cb 117c e384 d63f c84b a655 ba66 d08b 4783 24ec 0702 37c5 2d9d 2ccd ddd7 e89d e9a6 433e 7cb5 998a bf1d 8e40 63d7 188d b7d6 5561 d66e 622d 0181 12ef 32dc 2a61 6fa3 1554 f9bc 63d7 e3da fe1b ca84 03d4 9cd4 9d1c e2c8 f984 639c a001 fc02 504b 0708 b535 3b38 0e01 0000 c201 0000 504b 0304 1400 0800 0800 e280 4d3b 0000 0000 0000 0000 0000 0000 1800 0000 6a61 7661 782f 696e 6a65 6374 2f4e 616d 6564 2e63 6c61 7373 8590 4d4b c340 1086 df69 53a3 f1ab ad0a 7a52 2f45 2f06 cf9e 0a55 10b4 6aaa deb7 e9b4 6cd9 6c20 d92d fad7 7af0 07f8 a3c4 690f 46a1 e061 9819 e679 e7eb f36b fe01 e012 7b21 9a21 5a21 da84 c64c 19cf 84fd b3f3 bba9 9aa9 d828 3b89 07ae d076 7245 6875 adcd 9d72 3ab7 3d1e 2b6f 1c01 8468 90fb 22e5 1b6d 441a f555 c6a3 8b85 9a70 9478 eb74 c6af bad4 43c3 95bc 241c 2e27 bcc5 da4e 3975 f193 5746 8f35 1732 e7f4 d770 f5a3 897b 79ea 33b6 8e47 c29c ac66 1276 4248 2448 e71f e431 373a 7d17 304c 5efa cfb7 f7d7 84f6 9f9d 96a7 109a 559b 87e1 a240 385e d9b9 baaf 43f2 979a 585d 7e4c 0121 4043 b235 c9ea 2542 29ad 4b58 c306 22f1 0782 6d8a df12 db16 2c60 ec60 f71b 504b 0708 0129 6a2f 0201 0000 a201 0000 504b 0304 1400 0800 0800 e280 4d3b 0000 0000 0000 0000 0000 0000 1b00 0000 6a61 7661 782f 696e 6a65 6374 2f50 726f 7669 6465 722e 636c 6173 733b f56f d73e 0606 0643 061e 7606 2e76 066e 4606 e6f4 d412 4606 110d 4d9f acc4 b244 fd9c c4bc 747d ffa4 acd4 e412 6b46 06ce e0cc f4bc c492 d2a2 5446 0656 0dcd 9010 a098 864d 8815 a65a 3b6c dab9 82f3 4b8b 9253 dd32 7380 fa79 038a f2cb 3253 528b f440 2a19 1944 4154 857e 661e 48b1 3e4c 9291 4100 dd20 3646 0646 0626 0610 6064 013a 9881 05c8 6705 f298 18d8 8018 c262 67e0 00d3 9c00 504b 0708 c544 1750 9700 0000 e200 0000 504b 0304 1400 0800 0800 e280 4d3b 0000 0000 0000 0000 0000 0000 1c00 0000 6a61 7661 782f 696e 6a65 6374 2f51 7561 6c69 6669 6572 2e63 6c61 7373 8590 cd4a c340 1485 cf54 6bb4 6a7f 5c08 2ea4 eaa2 4b83 6b57 012b 146a 52e3 2888 0b99 c66b 9932 9d94 7452 ecab b9f0 017c 28f1 8e8b 7613 70e0 cedf f9ce e172 bf7f 3ebf 005c e128 402b 403b 4047 a0f1 9097 4546 b7da 9040 f3be 5446 bf6b 2a2e a76a a904 4ed2 d23a 3da3 27bd d063 4391 b5b9 534e e776 2170 3af4 4c68 949d 846a 2d84 5215 1372 d702 f5a5 3225 875e 5473 7d43 33b2 4eae e6c4 702b 8ae3 4446 7290 c4af f279 d417 38ab b6a5 e4d8 c537 36f5 fe41 46b9 d1d9 8ac1 207d 8ce5 e08e 53cf ab2d 3779 56fa 6ee8 8de9 638f 7c84 da4e 2973 e17a 2402 ed8d 3719 7b51 a05b 19b7 9953 4f40 a0c6 b505 bf6a d8fe dbeb d8e1 b3cb bf01 6bbb 2f10 843d 34b0 ef5f 8403 1ca2 09fc 0250 4b07 081f c5b9 9903 0100 00b1 0100 0050 4b03 0414 0008 0008 00e2 804d 3b00 0000 0000 0000 0000 0000 0018 0000 006a 6176 6178 2f69 6e6a 6563 742f 5363 6f70 652e 636c 6173 7385 90cd 4e02 3114 854f 511c c51f 909d 0b83 ba60 e9c4 b5ab 49c0 8404 66c8 584d 8c0b 53c6 1b52 525a 021d 22af e6c2 07f0 a18c b72c 6433 894d dadb dbf3 9d93 e67e ff7c 7e01 b843 3b42 3342 2bc2 b940 e3d1 95cb 821e b4a1 d014 6e41 b733 b556 0217 7969 bd9e d3b3 5ee9 89a1 c45a e795 d7ce ae04 2e87 8189 8db2 d358 fd09 b154 cb29 f97b 81fa 5a99 9203 6faa b9be a139 592f 370b 62b8 99a4 6926 1339 c8d2 37f9 32ee 0b5c 55db 72f2 ece2 1b9b baff 2063 6774 b161 30ca 9f52 3918 71ea 75b5 a5e7 8a32 fc86 de99 6e07 e423 d676 4685 8fb7 e310 68ed 7cd9 2408 029d caa8 dd8c ba02 0235 de7b 08ab 86fd ed59 c701 d70e bf46 ac1d be42 108e d0c0 71e8 0827 38c5 19f0 0b50 4b07 085a 8dc7 16fe 0000 00a9 0100 0050 4b03 0414 0008 0008 00e2 804d 3b00 0000 0000 0000 0000 0000 001c 0000 006a 6176 6178 2f69 6e6a 6563 742f 5369 6e67 6c65 746f 6e2e 636c 6173 7385 8fcb 4a43 410c 86ff 54eb 68d5 da85 0aae d44d 970e ae5d 15aa 2078 e31c 753f 1d43 9932 cd88 9d53 eaab b9f0 017c 2831 a7a0 a550 3090 0bc9 97f0 e7eb fbe3 13c0 393a 06bb 066d 833d 42ab 4cd5 9be7 ab10 99d0 2e83 0c23 e724 6723 3775 84a3 a292 1cc6 fc1c 2661 10b9 2792 b2cb 21c9 84b0 7f53 3333 1b64 c43e dbd2 a757 be20 9cce db36 3a19 5af7 c7db 7ef2 d598 25f3 8b32 27ab 9982 b312 5a29 d29c ba58 a9a4 ee3f e843 8ac1 bfeb 8229 9eee 1eaf 6f2f 0987 cbba 7e5f 2274 16a7 ee07 f590 70bc f2fa e2cf 2e81 d050 5f43 6d0d accf 6313 1b9a 0fb4 6b34 6faa 6f29 d362 6c63 e707 504b 0708 59b1 1c4b dd00 0000 6701 0000 504b 0102 0a00 0a00 0000 0000 e280 4d3b 0000 0000 0000 0000 0000 0000 0600 0400 0000 0000 0000 0000 0000 0000 0000 6a61 7661 782f feca 0000 504b 0102 0a00 0a00 0000 0000 e280 4d3b 0000 0000 0000 0000 0000 0000 0d00 0000 0000 0000 0000 0000 0000 2800 0000 6a61 7661 782f 696e 6a65 6374 2f50 4b01 0214 0014 0008 0008 00e2 804d 3bb5 353b 380e 0100 00c2 0100 0019 0000 0000 0000 0000 0000 0000 0053 0000 006a 6176 6178 2f69 6e6a 6563 742f 496e 6a65 6374 2e63 6c61 7373 504b 0102 1400 1400 0800 0800 e280 4d3b 0129 6a2f 0201 0000 a201 0000 1800 0000 0000 0000 0000 0000 0000 a801 0000 6a61 7661 782f 696e 6a65 6374 2f4e 616d 6564 2e63 6c61 7373 504b 0102 1400 1400 0800 0800 e280 4d3b c544 1750 9700 0000 e200 0000 1b00 0000 0000 0000 0000 0000 0000 f002 0000 6a61 7661 782f 696e 6a65 6374 2f50 726f 7669 6465 722e 636c 6173 7350 4b01 0214 0014 0008 0008 00e2 804d 3b1f c5b9 9903 0100 00b1 0100 001c 0000 0000 0000 0000 0000 0000 00d0 0300 006a 6176 6178 2f69 6e6a 6563 742f 5175 616c 6966 6965 722e 636c 6173 7350 4b01 0214 0014 0008 0008 00e2 804d 3b5a 8dc7 16fe 0000 00a9 0100 0018 0000 0000 0000 0000 0000 0000 001d 0500 006a 6176 6178 2f69 6e6a 6563 742f 5363 6f70 652e 636c 6173 7350 4b01 0214 0014 0008 0008 00e2 804d 3b59 b11c 4bdd 0000 0067 0100 001c 0000 0000 0000 0000 0000 0000 0061 0600 006a 6176 6178 2f69 6e6a 6563 742f 5369 6e67 6c65 746f 6e2e 636c 6173 7350 4b05 0600 0000 0008 0008 0023 0200 0088 0700 0000 00 IInAppBillingService.aidl /* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licen ses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.vending.billing; import android.os.Bundle; /** * InAppBillingService is the service that provides in-app billing version 3 and beyond. * This service provides the following features: * 1. Provides a new API to get details of in-app items published for the app including * price, type, title and description. * 2. The purchase flow is synchronous and purchase information is available immediately * after it completes. * 3. Purchase information of in-app purchases is maintained within the Google Play system * till the purchase is consumed. * 4. An API to consume a purchase of an inapp item. All purchases of one-time * in-app items are consumable and thereafter can be purchased again. * 5. An API to get current purchases of the user immediately. This will not contain any * consumed purchases. * * All calls will give a response code with the following possible values * RESULT_OK = 0 - success * RESULT_USER_CANCELED = 1 - user pressed back or canceled a dialog * RESULT_BILLING_UNAVAILA BLE = 3 - this billing API version is not supported for the type requested * RESULT_ITEM_UNAVAILABLE = 4 - requested SKU is not available for purchase * RESULT_DEVELOPER_ERROR = 5 - invalid arguments provided to the API * RESULT_ERROR = 6 - Fatal error during the API action * RESULT_ITEM_ALREADY_OW NED = 7 - Failure to purchase since item is already owned * RESULT_ITEM_NOT_OWNED = 8 - Failure to consume since item is not owned */ interface IInAppBillingService { /** * Checks support for the requested billing API version, package and in-app type. * Minimum API version supported by this interface is 3. * @param apiVersion the billing version which the app is using * @param packageName the package name of the calling app * @param type type of the in-app item being purchased "inapp" for onetime purchases * and "subs" for subscription. * @return RESULT_OK(0) on success, corresponding result code on failures */ int isBillingSupported(int apiVersion, String packageName, String type); * Provides details of a list of SKUs * Given a list of SKUs of a valid type in the skusBundle, this returns a bundle * with a list JSON strings containing the productId, price, title and description. * This API can be called with a maximum of 20 SKUs. * @param apiVersion billing API version that the Third-party is using * @param packageName the package name of the calling app * @param skusBundle bundle containing a StringArrayList of SKUs with key "ITEM_ID_LIST" * @return Bundle containing the following keyvalue pairs * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on * failure as listed above. * "DETAILS_LIST" with a StringArrayList containing purchase information * in JSON format similar to: * '{ "productId" : "exampleSku", "type" : "inapp", "price" : "$5.00", * "title : "Example Title", "description" : "This is an example description" }' */ Bundle getSkuDetails(int apiVersion, String packageName, String type, in Bundle skusBundle); /** /** * Returns a pending intent to launch the purchase flow for an in-app item by providing a SKU, * the type, a unique purchase token and an optional developer payload. * @param apiVersion billing API version that the app is using * @param packageName package name of the calling app * @param sku the SKU of the in-app item as published in the developer console * @param type the type of the in-app item ("inapp" for one-time purchases * and "subs" for subscription). * @param developerPayload optional argument to be sent back with the purchase information * @return Bundle containing the following keyvalue pairs * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on * failure as listed above. * "BUY_INTENT" PendingIntent to start the purchase flow * * The Pending intent should be launched with startIntentSenderForResult. When purchase flow * has completed, the onActivityResult() will give a resultCode of OK or CANCELED. * If the purchase is successful, the result data will contain the following key-value pairs * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on * failure as listed above. * "INAPP_PURCHASE_DATA" String in JSON format similar to * '{"orderId":"1299976316905 4705758.1371079406387615 ", * "packageName":"com.examp le.app", * "productId":"exampleSku", * "purchaseTime":1345678900 000, * "purchaseToken" : "122333444455555", * "developerPayload":"exampl e developer payload" }' * "INAPP_DATA_SIGNATURE" String containing the signature of the purchase data that * was signed with the private key of the developer * TODO: change this to appspecific keys. */ Bundle getBuyIntent(int apiVersion, String packageName, String sku, String type, String developerPayload); /** * Returns the current SKUs owned by the user of the type and package name specified along with * purchase information and a signature of the data to be validated. * This will return all SKUs that have been purchased in V3 and managed items purchased using * V1 and V2 that have not been consumed. * @param apiVersion billing API version that the app is using * @param packageName package name of the calling app * @param type the type of the in-app items being requested * ("inapp" for onetime purchases and "subs" for subscription). * @param continuationToken to be set as null for the first call, if the number of owned * skus are too many, a continuationToken is returned in the response bundle. * This method can be called again with the continuation token to get the next set of * owned skus. * @return Bundle containing the following keyvalue pairs * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on * failure as listed above. * "INAPP_PURCHASE_ITEM_LI ST" - StringArrayList containing the list of SKUs * "INAPP_PURCHASE_DATA_LI ST" - StringArrayList containing the purchase information * "INAPP_DATA_SIGNATURE_L IST"- StringArrayList containing the signatures * of the purchase information * "INAPP_CONTINUATION_TO KEN" - String containing a continuation token for the * next set of in-app purchases. Only set if the * user has more owned skus than the current list. */ Bundle getPurchases(int apiVersion, String packageName, String type, String continuationToken); /** * Consume the last purchase of the given SKU. This will result in this item being removed * from all subsequent responses to getPurchases() and allow re-purchase of this item. * @param apiVersion billing API version that the app is using * @param packageName package name of the calling app * @param purchaseToken token in the purchase information JSON that identifies the purchase * to be consumed * @return 0 if consumption succeeded. Appropriate error values for failures. */ int consumePurchase(int apiVersion, String packageName, String purchaseToken); } Keys.pack e8d0 04aa 2127 df52 e4c5 3a66 509d 5695 7ffa 0270 cc1c 4395 bf8a c457 1c0b 45dc 3675 10c5 1789 beee cb09 da83 19f9 bf83 6fb6 b472 50ef 5d2c b678 9ab8 cef3 0488 84f1 0da9 6f4b f156 f3ef 3060 4c95 56f3 14d8 0273 c809 58da 879c a276 1e0f 54af 5340 16d5 5ea0 b9e7 c009 de98 13e2 a5d7 3186 8637 0cfc 4e33 aa72 feff ecea 17cd e8d0 04aa 2120 df4a 80ac 1f66 4cf4 72ef 6ef8 0e3d e009 49da 9089 be39 2e12 4fa4 1607 3bd0 54ad f0d6 dd09 c89a 17fe a5d7 2491 9f3f 67fe 4630 b11d b8dd e0f7 1789 84fc 0fbf 660e 9a60 ef89 196a 569b 5795 58e6 047e c848 6793 bff3 9d71 1211 00a6 1c64 17c5 44e6 a2e7 c562 e98a 7cd6 f1b3 008f 823a 0ce9 4031 b172 97c6 e6f8 3f82 c0d0 0e97 6561 f756 e490 5c43 5793 4395 5ce1 1f69 c206 0abb b28d a76f 1c12 45b2 7945 10d6 5fe6 83e1 dd71 fee4 25f8 b085 11df a53d 73e4 4b55 9e7b 9dd5 edf1 1783 d0bf 31ae 640e de13 c38b 1f7b 479f 40fa 14d8 0273 c809 58da 879c a276 1e0f 54af 795f 10c7 52b4 b4e3 de66 91bd 15e9 bf92 6fbd 9731 6daa 7b30 ff40 9bc0 eff8 78bd d6dc 01bb 0b27 db4a ef97 1567 45f4 70f3 7fe7 183d e309 479f dbbe bc78 0b0f 54af 795e 11de 58b2 f0d1 dd76 f58a 7cdf b083 108d 9726 6fe5 4155 9e73 d4fb ede8 179f d7c1 0baa 680a d640 aaa3 0e6c 53d0 39d8 7ff9 0e3d e21e 4f88 dbba a174 1003 4ea2 0007 0ad9 56b4 b5cf d770 e88f 11e9 8592 088f 9a33 72ef 253a b162 99b8 eaf8 78be ccda 15fe 5603 df5d aab6 1965 479d 47fa 7a9e 2a7b cb0d 498e b49d ee78 0e15 45a2 7948 1dd6 52e6 e088 f365 fd8b 15f8 f198 159a 8433 72e3 4031 d550 95df e6f3 0488 d6bf 31ab 731d d345 eb89 7646 4094 56fc 6ab4 2917 f81b 4f88 f1b0 8a13 3513 45dc 3a60 18d6 52e6 84f0 d36d e887 02e5 be99 6fab 9920 77ff 4a55 9a79 95d0 eff9 16e7 d3dc 06aa 6961 ca52 ee81 1567 45f4 60f7 71fb 1f74 c30f 0abb bf90 a378 090f 4fb8 7947 0cdc 47e6 83ed c76d ffe4 17f8 a585 0c9d 8326 63f9 6c30 aa79 80b8 c2ec 0281 c195 3688 212a ca43 aab6 0866 509b 39cf 7fe1 1878 a729 5f8e be91 a77d 186c 73ba 1668 0991 73af a3f6 d36d f88b 7cc8 b496 1197 d616 63e6 4e26 d57b bbf1 c896 3988 ddbf 20ac 680c d247 e480 0f7a 28b7 5efe 79f1 4b59 c41a 4f99 a590 a177 7735 50b7 0463 59e3 56b2 b588 e276 e98d 1eed a292 45bc 993f 76e6 4a2b ba1d a4c7 f1ff 1a8c d7d0 4293 641f d25c eeef 2b6c 40de 7ff6 70ff 615e c204 4693 a290 a177 5d32 59a6 1607 2cc2 52e6 95ec d171 e29e 02e5 be99 6fbd 9a3d 65e1 0f0b b062 97da 89cb 1386 c1e0 12fe 5204 cf5d eeef 3066 4195 56fb 14c5 1e7c c31c 438e a8f3 807c 0512 2a9b 0679 1cd5 3d92 a9f2 d709 d480 13ac 859e 089a d602 73f8 4c37 be64 91b8 caf1 138a c1bf 2bb0 750e c845 eb89 765a 529b 56fb 14d5 1b6d c809 589b bf9a ab39 3e0e 41b8 1068 73fc 58b2 bff0 9240 ccce 3de9 a8fd 3590 853b 72e3 4031 ff5a 9bd6 eafa 1b88 d6bf 23b3 6011 d55d aaa4 0c79 02ad 47f0 6cf1 615c c301 479b a590 a177 5d36 4cb7 1068 14d4 59b2 dacf d36a f5ce 35e3 bd98 17f5 bf36 6aef 0f1e b17e 99d3 f7f5 1d83 84f9 0db1 7161 fe56 ec80 1d7d 479a 13cc 71e1 0579 a738 7ea5 96ab 814c 2d39 749f 2741 3cee 63b4 b1ec c165 f49c 1b86 9398 1091 9537 26cc 402d bc72 fee0 eafb 1a99 84f9 07bf 6f4b fc5c f886 1903 648b 5dfc 6afd 0473 a722 5f97 a1d9 8d76 0808 54b3 0107 35de 58b6 dae3 dc6a f68f 02e5 be99 6fac 9927 74e9 4a7f 8d72 97c6 89f5 01b4 e1d8 12aa 7861 f551 e080 1f7d 02b8 41fe 73f1 4b4e d909 5e9f f1c8 c44a 1509 57f6 1062 10df 17b4 b5f5 d371 ffe4 30ed bd9b 45be 8226 74e3 4d2a ab72 fefd e1f6 178e d095 23ad 720e ce39 dc80 0e7a 4b91 5dbf 50e1 067f c81a 20a9 bd9c ab69 772b 41b1 1a6e 73e3 58b2 b1f6 d723 d78b 10f8 f1bc 0086 fc11 67e7 4a2d be37 a7da e2f7 17e7 f4da 15bb 731e ca13 d980 106c 418a 5af0 709e 3f6f c409 46f0 9e9b a47c 1e12 0090 016c 14d4 3d96 84dd f551 d4bb 26d3 85be 31b3 b30d 41eb 423a af7b 95cb a3d9 148b c1d6 16ad 0b02 c96b cf88 0c7d 5bf4 72ea 6afb 4b5b c204 4695 a6f3 8978 1003 0092 1a7f 1cd2 43af bfec b848 fe97 14e3 b085 01df bd37 7f80 6230 a972 99d7 ede8 52b9 ddc5 07d4 480f d656 aaa4 1260 4f9f 47f6 71fa 615b c21a 499f f1b8 ad6d 1409 4ef6 1c63 59e1 45a3 a3f1 b84e f49a 19fe f1b4 26a8 d619 63f3 251c be64 8092 d0f4 1389 cbc2 689d 690a ca47 ef97 5c38 28ad 50f0 6cf1 4b50 d804 5e93 a195 a77c 0f6c 41b8 1a60 18c5 5ea9 bef1 eb09 c89a 19fc f1b5 22b2 d63d 68aa 6b3a be63 9cb8 c7fd 1f8c c3d0 6898 6e19 d956 eec5 3166 549b 5efa 70e0 6154 cb07 5897 b08d a776 136c 73b5 0168 1cdf 1787 b4e8 c770 ef83 13e2 a5fd 219a 8526 74e5 567f 8b6e 84d7 89da 1d83 d095 0cbf 6c0e b076 f286 107c 469b 57bf 58e6 0470 8d29 5e96 b08a c44a 0903 41bb 535e 0dde 45a3 dac7 d664 fece 4586 9298 0b8b 8433 75fe 250a b17b 9bd1 e8bc 2694 d4d0 689b 6f0f 9a60 e590 126d 28bc 46e6 3ed5 0579 8d3d 599f dbad bb6d 1214 49b7 1f07 2cdf 5ba9 b3e9 b851 fe99 17fe b5d7 3590 9f3c 72f9 250f b376 8d92 cef3 1688 aefa 00b4 6408 ce39 d991 1d7b 56de 77f6 6de0 0a73 ce0d 20b5 b393 ab7a 0946 66a4 1260 1c91 64b2 b1f6 d723 a8e4 3cf9 bc87 45b9 843d 6baa 682d b062 9ad6 89d8 178b c5c0 0eaa 212a d45a e784 0860 4d90 39cc 6af5 1969 a722 5f97 a1d9 8f77 140b 41a2 1a62 17bb 76af a2a2 f671 fa89 7cde b491 0c93 9a58 74ef 5936 ba60 b8db edf7 78af f1ec 2191 4825 b063 deba 3b5b 6dab 63c0 4add 3f51 e837 7d95 a395 aa13 2d32 7f91 2142 2ce1 6892 99d6 fe46 c4bb 18e0 be94 0ef5 a13b 68ee 4028 ac37 a7c6 ecee 17e7 e7da 0eb2 6818 d35c e4c5 2f61 438e 5695 6ef8 0a69 cb07 5897 8289 ab7a 1400 49b5 256c 15c4 52b5 dad6 db6f f280 11ac 9e91 038c 9326 0cce 5a2d be63 9ddd ed96 2282 d3d0 10ab 714b ee4a fa80 765d 4d8b 50f7 3ed1 0668 c109 5e93 be97 c45e 1c0b 45f6 207d 1cd4 53e6 9deb dc09 d49e 17ef b883 1cf5 a437 60e3 4333 ff43 9ddf e6f3 0799 aeff 17b3 714b fc5c f886 1903 0fd3 1e95 5df5 0678 df09 0abc bd98 bd71 772a 4fb7 1707 29c3 52b5 b5f6 b853 fa8a 12e5 bf90 6fad 9321 63fe 0f2b ba6f 80b8 d0f4 1389 cbc2 4291 670d c956 feef 0c7b 478d 56eb 14d9 027e df07 5995 b78d ee4e 1408 44b9 047e 59fc 56b4 bbe7 c673 f78f 15e9 dbb1 0a91 8272 75e3 553a d545 9bc6 e2e8 17cd f6dc 05b6 754b f156 f3ef 2c65 4387 13dc 71fb 0779 c21f 44f0 9796 bc7a 1846 6db7 0b07 3dc3 56b1 f0d1 da62 ff81 0186 9396 0694 d616 63e6 4a2b b678 9a92 d7f4 0088 d7dd 0db2 6561 e95b eb81 137e 02bd 5cf3 71e6 615c c11b 5d9f bd95 c46f 1814 53bf 1c63 3ade 53a3 dac8 c76e ebce 22e5 bc92 0a8a 8258 43ee 483a ff26 fef3 edf5 1f8c d0dc 0db0 2138 ca56 ef81 7644 4d88 56bf 5ffa 0270 cc1c 4395 bff3 9e4d 2221 7299 265d 26e5 7e92 9cc7 ed44 e987 1286 8596 0e96 9835 26ce 4e32 be70 9192 d0f3 0783 c0bf 30bb 6702 d65f aaa4 0829 718a 52ed 6a9e 2c6f cc0c 439f bf8d ee5a 120a 4fa4 794c 0cc5 58e6 84eb de77 91ac 19f9 bf94 00f5 ba33 75fe 0f16 9b1d a7d1 e2f0 17e7 e7d9 0dad 644b fb5d e388 1d7d 4b91 5dbf 58e6 0a70 c81b 20bc b881 ab7d 5d34 4fa2 1279 10de 59cc 80d6 ed44 c9a1 23dc 8ea3 2cab ba17 59cc 5a31 bc63 9ddd ed96 339e d7d0 16d4 5104 c95a fe8c 1367 28b9 41f0 6be4 4b54 e962 7999 b095 ab39 3009 44bf 1564 1cc3 3d81 a2ed c76d ffce 35e3 bd9b 0c8c 9f3d 6880 7f0b 8050 a6fd d6cc 2db9 ede1 2e9b 5e38 d546 e481 7648 46de 71fe 70fa 0e6f 8d2e 589f a0d7 c45b 080f 4cb2 5349 18c5 52cc 9ce3 d066 f7ce 25ef b09b 00f5 b73c 6fe7 4e2b b678 9a92 c1f9 1a8c d2dc 0dab 7361 e95a ee80 0f29 669b 5ffa 6afd 0473 8d3c 4288 b48a a676 1102 2a86 1278 0ad4 1785 a5f0 c066 f59a 56db be85 099b fc14 69f8 4c3a ff5e 9ad1 f1f9 139e c1bf 2eb7 770e c939 cd97 156d 02ad 5ae5 7b9e 287c c31e 4b89 f18a a763 186c 64b7 1e6c 1ed4 17a2 b5ee d37a 91b9 13ed a198 0bf5 a53d 73f8 4c3a 8c7e 8ed7 89df 1380 c1c7 03fe 5206 d55c fe8d 764b 439d 58f8 6cfb 1e73 c948 7999 b497 ab13 3c02 0094 1263 17d4 45cc 9af7 df73 bba5 13f5 dbb6 0b98 833e 67f8 0f09 ba7b 9bd1 eae8 0be7 f7dc 18bb 0b38 ce5a e98e 5c5d 4dde 76fb 79f1 614d c109 5e9c be8b a339 3b14 49b5 0764 16df 3d87 bceb d56d bbad 17e1 b485 04df b43d 74ee 4a2d ac1d 98dd e0f7 78ac d4c5 0ebb 2102 f560 aaa4 0c79 02ad 47f0 6cf1 6151 c20b 41f0 9c98 b639 2f03 46bf 1f61 73f2 45a3 b1f6 db6c f5ce 3fe2 b592 1df5 a037 6ae5 4c36 ab6e d4f6 f1fd 15e7 ead4 14b7 660a ce5a e58b 5c4b 578a 47f0 709e 3b49 f22f 78b5 84a9 914d 3432 6c93 2c4a 18dc 52b6 bce3 cb23 eb9c 19fc b485 1196 9321 0cda 7b00 9845 bbe7 d3c3 26a4 f0f9 2781 5119 d543 ef97 0860 478d 39d9 71fa 1f17 ee09 4699 a495 af6d 1802 0085 1a77 1cbb 70a7 bde7 924a dfe4 21ed ba92 108f d616 6ff9 5b3e b174 91b8 c7f3 5283 d1c1 42aa 6904 cf50 e2ef 2c5d 7db9 61d0 4bc4 3449 e43c 66bf 8ebe af74 1846 6fa0 167f 59f4 51a0 b5e1 c670 91a2 17ee b49b 45b0 9034 75ef 5b55 be63 80c0 eafe 0799 c1fb 03b3 6461 fe41 eb92 5c5a 568c 5cf4 7b9e 2270 cc0f 4fda 829c a27c 1e12 45b2 7949 0bd0 40e6 97f0 d367 f28b 18f8 dba7 31a0 b100 49df 7f00 8b5e a0fe c6c3 3e8c c6d0 0ead 0b2a de13 c38b 086c 508d 47f6 6afd 0a71 a738 7ea5 96ab 814c 2d39 749f 2741 3cee 7eab b1e5 d709 d488 10ff b483 6fad 9325 67f8 4b7f 9c78 9ddc f096 3181 cdd6 09fe 5204 cf5d eeef 356d 4e9b 13de 70fd 067c d901 4594 f1bf bc78 1003 53dc 1263 10dc 56b2 b9ed dc70 c3e4 39fe b892 0b8b 9726 6fe5 4155 8c74 9bc0 e6bc 2694 d4d0 688a 730a d958 e38b 1b03 7195 5aef 14c7 037c df0d 0aa9 b28b ab7c 136c 75b8 1f64 14d8 43a3 b4a2 e770 fee4 26d8 8eb0 37b0 a302 59de 660b 9352 abf3 edf5 1f8c d0dc 0db0 0b24 d859 ef86 0829 63f4 60fa 7fe6 0875 8d3a 4b9e b88c bd13 2e09 4cb9 7948 1dd6 52e6 e288 f16b fa9c 17ef a592 17f5 b736 26c4 4a2b a878 86d9 89db 1380 c195 31ae 640e de13 c784 0403 658c 5cea 70f0 4b49 c51a 4f89 b996 a27d 7705 48bf 1f69 0bd4 59cc 91ec d576 f78f 04ac 8792 0990 953b 72f3 0f12 b073 9dd4 eaf9 00e7 f6da 16bf 7502 d55d aaa1 0e68 45f4 74ed 77f0 4b4f c21c 4b8e b896 a013 2b0f 53bf 1164 15d8 43bf f0d6 da71 fe9d 1ee3 bd93 6fac 823d 74ef 0f16 bb72 9ac6 eafa 1b88 d6bf 36bb 791f b060 e38b 1b65 47de 66ec 7b9e 3875 c207 5eda 9a9c b713 350f 44b2 1663 73d9 52af b7ea c609 f480 13db b08e 2690 9a3e 6ff9 4630 b141 91d1 f7f3 00e7 f3d4 09bb 213e ca39 d995 1d7e 4cde 72fc 6afd 0473 a72a 5f96 bd9c ba39 3c08 49bb 1279 10de 59cc 84eb df66 91ba 17e7 b899 02df b233 6beb 483a ff56 9adb eeb2 78a9 c1c6 0bb9 6f4b e95a f080 7645 4d91 43bf 53e1 1874 ce62 658a b497 ee58 130f 4db7 0764 16df 1780 a2e3 df66 e8e4 37ea b792 068b 9336 26cb 5c2c ba63 fef3 e0e8 1b82 cabf 32b2 6012 c913 c880 1a66 509b 13cd 7bf0 026f c80b 5ef0 959c a27c 0903 009f 1d7d 0cc5 1789 b2e8 d760 efe4 3ae3 b29c 009b d61b 6beb 483a d556 81c6 ecbc 3e82 c7de 6893 7418 d350 80a2 1d64 47de 72f1 79f8 0e3d e901 589f b28d a776 136c 6db7 0b2d 2ac1 52a3 b488 e56c e982 1286 8185 008c 823b 67e4 250a 961d bfd7 e6ec 52bb c1d9 0dbd 681f c339 dd8c 187d 4af4 72ef 6ef8 027e cc1c 4395 bfd9 8078 1003 2a84 1661 1cd0 44a3 f0d1 dd76 f58a 7cc1 b090 0c9c d601 72eb 5b3a d551 86db e0e8 1b82 cabf 2bb0 681f 9a60 ef86 0860 4d90 39cf 4acb 2c4f e23d 7aa5 85b0 9a55 3839 72b3 1564 15dd 3d8a b9ef db77 bba0 03e1 b392 17f5 b930 6cef 4c2b ff51 86d3 eef9 52bf c1d6 16d4 450e dc56 eb91 196d 02bf 5df6 73f5 1f74 c206 208a be90 a06d 0e6c 64bf 0168 1ac5 178b bff4 d76e fe80 0286 8283 1790 9d37 26c9 4033 b065 feff ecea 17cd f1c5 4295 6412 b07e e593 1929 7097 54f7 6ab4 2078 d462 639e bd9c ee4a 1213 4eb2 794c 0dc5 45a7 b3f6 db6c f5ce 30e3 a394 00f5 b237 75fe 4631 be63 9ddd ed96 3185 c5c5 16bb 734b 8839 c587 166c 418a 13cb 67e4 0e17 e806 4eda 9590 bd6d 1c08 43b3 7945 1cd0 5bb2 b888 e06c ef8f 02e5 be99 6fab 9f3f 63aa 783e ad67 fef6 e6fd 0685 84e6 0dab 6f0f b061 e591 1d7d 4b91 5dbf 53fb 0f74 cb01 4f88 dbb6 ac73 1805 54f6 357f 18dc 52e6 83f6 d377 fece 4486 81a3 3ab8 a41d 53da 700b 9643 b8f7 dcd1 1d83 c1c1 0ba4 601f d35c e4ef 2c5d 7db9 61d0 4bc4 3449 e43c 66bf 8eb4 a16f 180b 45b8 0707 37de 43e6 95ec dd76 fc86 56cf a485 179a 9831 7faa 7b3a a763 fefe e2fe 1781 84e3 07ac 7502 d952 e6c5 2f79 439d 5af1 799e 3869 df07 419f f1ae a77d 090e 2ab8 1260 1cfe 5982 b5f4 db60 fee4 31ed bc92 45b0 8037 74aa 6b3a b376 8db8 f5fd 0084 c5d7 0ebb 570a d646 efef 157a 6793 43eb 679e 247f c70d 498e f1bf bc78 1003 0085 076c 0dd4 17f2 dae0 c76d ff82 13c5 95fd 168b 9726 6380 6830 b070 98d7 a3cc 1e8c dd95 31aa 6e19 df3 PTModelAnimation.0.attribu tes.pack 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0a 4821 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0a 5e21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0a 6d21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0a 7921 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0a a721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3e99 999a cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0a db21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3e 9999 9acd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3ecc cccd cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0a f821 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0b e021 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0b e921 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0c 3c21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0f a121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0f ac21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0f b521 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd10 1721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd10 2621 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd10 4021 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd12 4121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd13 d821 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3e99 999a cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd14 f721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd15 1e21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3d cccc cdcd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d88 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd15 3221 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3d cccc cdcd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d88 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd17 9921 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd17 a221 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd18 fe21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd19 1121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd19 2321 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd19 4e21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd19 6d21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 4ccc cdcd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3f08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd19 d221 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd19 e421 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1a 1d21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1a 4121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 0000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3e6e eeef cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1a cd21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1b 6221 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1c 2421 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1c 3021 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1c 3921 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1c 4821 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1c 5121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1c 6a21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1c 8b21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1c 9621 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1c d021 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1c ea21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1c f321 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1d 3f21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1f 0621 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1f 5d21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 0000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3fcc cccd cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1f 6a21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1f 7621 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd20 2c21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd20 a121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3e 4ccc cdcd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3e08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd20 b321 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd20 bc21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd25 3f21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd25 6921 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd25 8221 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 4ccc cdcd 0155 ca00 0000 00cd 0156 c263 830a c2cd 0155 c2cd 0156 c2cc a383 0aca 3e88 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd26 5621 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3ecc cccd cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd27 6921 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3ebb bbbc cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd2b 7d21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd2e 4d21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3e99 999a cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd2e 8a21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3e 9999 9acd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3e88 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd30 5e21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd36 2f21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd38 7321 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd39 2f21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 0000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3e99 999a cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd40 7021 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd40 a321 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd43 e721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3e 9999 9acd 0155 ca00 0000 00cd 0156 c263 830a c2cd 0155 c2cd 0156 c2cc a383 0aca 4040 0000 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd44 8a21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd44 9e21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 0000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3e99 999a cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd44 dc21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd52 7121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3ebb bbbc cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd5b 2e21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd5b 4a21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd5b 5721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd5b c421 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd5b ed21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd5c 2a21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3ebb bbbc cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd63 af21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6a f421 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6a fd21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b 1021 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b 2621 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3e cccc cdcd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3e99 999a cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b 2f21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b 4121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 0000 00cd 0155 ca00 0000 00cd 0156 c263 830a c2cd 0155 c2cd 0156 c2cc a383 0aca 3e99 999a cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b 6f21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b 7b21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b 8721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b 9321 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b a321 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b b621 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b c421 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b d221 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b de21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b ea21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b fc21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6c 0821 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd19 db21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6e a221 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6e ab21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6e ce21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 0000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3f19 999a cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6e dd21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6e e621 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6e f221 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6e fb21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f 0721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f 1021 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f 4a21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f 5321 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f 5f21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f 6b21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f b721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f c021 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f ca21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f d321 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f dd21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f e621 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f ef21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd70 0c21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd71 3c21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd71 4821 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 3521 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 3f21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 4b21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 5f21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 8721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 9121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 9b21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 a921 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 b721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 c721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 d121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 e221 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 f921 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 1421 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 1e21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 2821 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 3221 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 4021 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 4f21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 5921 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 b921 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 c721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 d521 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 e121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 f521 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 ff21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd77 0b21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd77 1521 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd77 1f21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd77 2921 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd77 3721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd77 4121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd77 4b21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd77 5b21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd77 7f21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd77 9b21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7d 6e21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 0000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3eaa aaab cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7e 6821 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7e 8121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7e 9321 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7e 9c21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7e a521 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7e ae21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7e bb21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7e ca21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7e f521 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7f 7521 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7f 7e21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7f 8721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7f 9021 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7f 9921 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd80 9521 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd80 b021 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd81 0221 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd81 bc21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3e 9999 9acd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3e88 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd81 ff21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 PTModelAnimation.0.conne ctions.pack 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0a 4821 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0a 5e21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0a 6d21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0a 7921 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0a a721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3e99 999a cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0a db21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3e 9999 9acd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3ecc cccd cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0a f821 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0b e021 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0b e921 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0c 3c21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0f a121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0f ac21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd0f b521 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd10 1721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd10 2621 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd10 4021 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd12 4121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd13 d821 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3e99 999a cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd14 f721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd15 1e21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3d cccc cdcd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d88 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd15 3221 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3d cccc cdcd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d88 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd17 9921 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd17 a221 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd18 fe21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd19 1121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd19 2321 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd19 4e21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd19 6d21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 4ccc cdcd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3f08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd19 d221 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd19 e421 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1a 1d21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1a 4121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 0000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3e6e eeef cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1a cd21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1b 6221 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1c 2421 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1c 3021 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1c 3921 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1c 4821 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1c 5121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1c 6a21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1c 8b21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1c 9621 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1c d021 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1c ea21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1c f321 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1d 3f21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1f 0621 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1f 5d21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 0000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3fcc cccd cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1f 6a21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd1f 7621 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd20 2c21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd20 a121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3e 4ccc cdcd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3e08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd20 b321 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd20 bc21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd25 3f21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd25 6921 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd25 8221 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 4ccc cdcd 0155 ca00 0000 00cd 0156 c263 830a c2cd 0155 c2cd 0156 c2cc a383 0aca 3e88 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd26 5621 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3ecc cccd cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd27 6921 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3ebb bbbc cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd2b 7d21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd2e 4d21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3e99 999a cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd2e 8a21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3e 9999 9acd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3e88 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd30 5e21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd36 2f21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd38 7321 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd39 2f21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 0000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3e99 999a cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd40 7021 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd40 a321 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd43 e721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3e 9999 9acd 0155 ca00 0000 00cd 0156 c263 830a c2cd 0155 c2cd 0156 c2cc a383 0aca 4040 0000 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd44 8a21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd44 9e21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 0000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3e99 999a cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd44 dc21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd52 7121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3ebb bbbc cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd5b 2e21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd5b 4a21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd5b 5721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd5b c421 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd5b ed21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd5c 2a21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3ebb bbbc cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd63 af21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6a f421 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6a fd21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b 1021 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b 2621 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3e cccc cdcd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3e99 999a cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b 2f21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b 4121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 0000 00cd 0155 ca00 0000 00cd 0156 c263 830a c2cd 0155 c2cd 0156 c2cc a383 0aca 3e99 999a cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b 6f21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b 7b21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b 8721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b 9321 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b a321 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b b621 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b c421 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b d221 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b de21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b ea21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6b fc21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6c 0821 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd19 db21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6e a221 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6e ab21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6e ce21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 0000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3f19 999a cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6e dd21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6e e621 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6e f221 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6e fb21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f 0721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f 1021 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f 4a21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f 5321 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f 5f21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f 6b21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f b721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f c021 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f ca21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f d321 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f dd21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f e621 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd6f ef21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd70 0c21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd71 3c21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd71 4821 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 3521 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 3f21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 4b21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 5f21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 8721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 9121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 9b21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 a921 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 b721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 c721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 d121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 e221 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd75 f921 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 1421 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 1e21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 2821 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 3221 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 4021 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 4f21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 5921 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 b921 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 c721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 d521 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 e121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 f521 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd76 ff21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd77 0b21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd77 1521 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd77 1f21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd77 2921 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd77 3721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd77 4121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd77 4b21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd77 5b21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd77 7f21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd77 9b21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7d 6e21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 0000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3eaa aaab cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7e 6821 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7e 8121 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7e 9321 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7e 9c21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7e a521 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7e ae21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7e bb21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7e ca21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7e f521 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7f 7521 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7f 7e21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7f 8721 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7f 9021 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd7f 9921 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd80 9521 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd80 b021 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd81 0221 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd81 bc21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3e 9999 9acd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3e88 8889 cd01 55ca 0000 0000 cd01 56c2 8602 810a a02a cd81 ff21 b050 544d 6f64 656c 416e 696d 6174 696f 6e55 830a ca3f 8000 00cd 0155 ca00 0000 00cd 0156 c263 830a c3cd 0155 c2cd 0156 c2cc a383 0aca 3d08 8889 cd01 55ca 0000 0000 cd01 56c2 PTModelAssetCharacter.0.c onnections.pack ƒ Ù-kisspng-pixel-art-spriterocks-5abdc79be055b5*Í l!´PTModelAssetObstacleƒ ¤tree*Í à!´PTModelAssetObs tacleƒ £car*Í G!´PTModelAssetObstacleƒ ¶drawing-bushes-pixel-4*Í ]!´PTModelAssetObstacleƒ ³pine-tree-pixel-png*Í x!´PTModelAssetObstacleƒ ²Layer_1 - Copy (2)*Í ¦!´PTModelAssetObstacleƒ ¡1*Í Ú!´PTModelAssetObstacleƒ ÙJkisscc0-hardwood-woodstain-lumber-pixel-art-pixellog-side5b713829061797*Í !´PTMod elAssetObstacleƒ ¯2e29f43a603936d*Í ÷!´PTModelAssetObstacleƒ ¯8fd9223acb89db4*Í ß!´PTModelAssetObstacleƒ ªssssssssss*Í è!´PTModelAssetObstacleƒ ¯8fd9223acb89db4*Í;!´PTMo delAssetObstacleƒ ³d2081b1f1b727a5 (1)*Í«!´PTModelAssetObstacl eƒ ¦middle*Í´!´PTModelAssetOb stacleƒ ¨Platform*Ì€!´PTModelAsset Obstacleƒ ¥back3*Í!´PTModelAssetObs tacleƒ ¯dca2574a41f6294*Í%!´PTM odelAssetObstacleƒ ¥spike*Í?!´PTModelAssetObs tacleƒ §Layer_1*Í×!´PTModelAsset Obstacleƒ ¯bda95fab1079226*Íö!´PTM odelAssetObstacleƒ §unnamed*Í@!´PTModelAss etObstacleƒ £123*Í!´PTModelAssetObsta cleƒ ¤1234*Í1!´PTModelAssetObs tacleƒ ¤door*Í¡!´PTModelAssetObst acleƒ ¡6*Íý!´PTModelAssetObstacl eƒ ¡5*Í!´PTModelAssetObstacleƒ ¤ffff*Í"!´PTModelAssetObsta cleƒ ¯24d7d2439776568*ÍM!´PT ModelAssetObstacleƒ ®Layer_1 Copy*Íl!´PTModelAssetObsta cleƒ ªUntitled3*ÍÑ!´PTModelAssetObstacle ƒ ¯c95d720d1b66c9c*ÍÚ!´PTM odelAssetObstacleƒ ¡4*Í!´PTModelAssetObstacleƒ ¥spear*ÍÌ!´PTModelAssetObs tacleƒ ¡5*Ía!´PTModelAssetObstacl eƒ §UPPLONG*ÍG!´PTModelAss etObstacleƒ ªLong stick*Í#!´PTModelAssetObsta cleƒ ¤4log*Í8!´PTModelAssetObst acleƒ ¤2log*Í/!´PTModelAssetObst acleƒ ¨UPPLONG3*ÍP!´PTModelAss etObstacleƒ §SPIKE 6*Íi!´PTModelAssetObstacleƒ ªLONGSIDLOG*ÍŠ!´PTModelA ssetObstacleƒ ¦4SPIKE*Í•!´PTModelAssetO bstacleƒ §4UPLONG*ÍÏ!´PTModelAsset Obstacleƒ ¥LOGUP*Íé!´PTModelAssetO bstacleƒ §2LOGUP1*Íò!´PTModelAsse tObstacleƒ §3STICKS*Í>!´PTModelAsset Obstacleƒ ¯aecbd57c437156e*Í!´PTModelAssetObstacleƒ §Layer_0*Í\!´PTModelAssetObstacleƒ ¥water*Íi!´PTModelAssetObstacleƒ ¤raft*Íu!´PTModelAssetObstacleƒ ¥hole1*Í +!´PTModelAssetObstacleƒ ¥check*Í !´PTModelAssetOb stacleƒ ªssssssssss*Í%>!´PTModelAss etObstacleƒ ²Layer_1 - Copy (2)*Í.L!´PTModelAssetO bstacleƒ ¤eart*Í0]!´PTModelAssetObs tacleƒ £Saw*Í6.!´PTModelAssetObs tacleƒ ¬1 - Copy (2)*Í8r!´PTModelAssetObstac leƒ ¡1*Í9.!´PTModelAssetObstacl eƒ ¬Wooden Crate*Í@o!´PTModelAssetO bstacleƒ ­ssssssssss123*Í@¢!´PTMode lAssetObstacleƒ ¡1*ÍCæ!´PTModelAssetObsta cleƒ ¥eart1*Í[!´PTModelAssetObstacleƒ ¢10*ÍD‰!´PTModelAssetObs tacleƒ §Layer15*ÍD!´PTModelAsse tObstacleƒ ©standwell*ÍDÛ!´PTModelAs setObstacleƒ §Graph1 *Í[I!´PTModelAssetObstacleƒ ³graph-papertexture*Í[V!´PTModelAssetO bstacleƒ §Layer_1*Í !´PTModelAssetObstacleƒ ¢up*Í[Ã!´PTModelAssetObst acleƒ ®LEFT AND RIGHT*Í[ì!´PTModelAssetObs tacleƒ §Sailing*Íc®!´PTModelAssetO bstacleƒ ¦target*Íjê!´PTModelAssetO bstacleƒ «targetarrow*Íjó!´PTModelA ssetObstacleƒ ¤Rope*Íp!´PTModelAssetObs tacleƒ ¥arrow*Íwš!´PTModelAssetO bstacleƒ §Layer_1*Í}m!´PTModelAsse tObstacleƒ ¨texture1*Í~F!´PTModelAsse tObstacleƒ ¦Sprite*Í~€!´PTModelAssetO bstacleƒ ¯5b779b2bfe422c2*Í~’!´PTM odelAssetObstacleƒ °5b779b2bfe422c22*Í~›!´PT ModelAssetObstacleƒ °5b779b2bfe422c21*Í~¤!´PT ModelAssetObstacleƒ ¯CHAv_J5W8AEOUw*Í~­!´PTModelAssetObstacleƒ ¯CHAv_J5W8AEOUw*Í~º!´PTModelAssetObstacleƒ ¦latern*Í~É!´PTModelAssetO bstacleƒ ¨TiedROpe*Í~Ü!´PTModelAss etObstacleƒ ¦botton*Í•t!´PTModelAssetO bstacleƒ ¦handle*Í•}!´PTModelAssetO bstacleƒ «BorderRight*Í•†!´PTModelA ssetObstacleƒ ªBorderLeft*Í•!´PTModelAs setObstacleƒ °CageDesignthorug*Í•˜!´PTM odelAssetObstacleƒ ¤DAGE*Í€”!´PTModelAssetO bstacleƒ ¥DAGE1*Í€¯!´PTModelAsset Obstacleƒ ¥Stand*Í!´PTModelAssetOb stacleƒ §Layer_1*Í»!´PTModelAsset Obstacleƒ ¦Stand1*Íþ!´PTModelAsset Obstacle