diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..275c487 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,35 @@ +root = true + +[*] +indent_style = space +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.cs] +indent_size = 4 +dotnet_sort_system_directives_first = true + +[*.{xml,config,*proj,nuspec,props,resx,targets,yml,tasks}] +indent_size = 2 + +# Xml config files +[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}] +indent_size = 2 + +[*.json] +indent_size = 2 + +[*.{ps1,psm1}] +indent_size = 4 + +[*.sh] +indent_size = 4 +end_of_line = lf + +# Docstrings and comments use max_line_length = 79 +[*.py] +max_line_length = 119 + +[*.php] +indent_size = 4 diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md new file mode 100644 index 0000000..cc04bd3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -0,0 +1,16 @@ +--- +name: Bug Report +about: Report a problem with a sample. +title: '' +--- + +> STOP: Have you discovered a problem with a sample found here, or are you looking for help getting the sample to work for you? +> +> If you're looking for help getting a sample working for you, please ask on [Stack Overflow](https://stackoverflow.com/questions/tagged/azure-notificationhub?tab=newest) with the tag `azure-notificationhub`. You'll be asking a broader community for help, potentially getting you an answer more quickly. + + +## What are you trying to do? + +## What did you expect to see? + +## What actually happened? diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 0000000..2dbc05e --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,26 @@ +version: 2 +updates: + - package-ecosystem: "npm" + directory: "/apache-cordova" + schedule: + interval: "weekly" + - package-ecosystem: "npm" + directory: "/Ionic-3" + schedule: + interval: "weekly" + - package-ecosystem: "npm" + directory: "/Ionic-4" + schedule: + interval: "weekly" + - package-ecosystem: "yarn" + directory: "/NotificationHubSample" + schedule: + interval: "weekly" + - package-ecosystem: "pip" + directory: "/notificationhubs-rest-python" + schedule: + interval: "weekly" + - package-ecosystem: "nuget" + directory: "/PushToSafari" + schedule: + interval: "weekly" diff --git a/Android/GetStarted/.gitignore b/Android/GetStarted/.gitignore deleted file mode 100644 index c6cbe56..0000000 --- a/Android/GetStarted/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -*.iml -.gradle -/local.properties -/.idea/workspace.xml -/.idea/libraries -.DS_Store -/build -/captures diff --git a/Android/GetStarted/.idea/.name b/Android/GetStarted/.idea/.name deleted file mode 100644 index 0b49cea..0000000 --- a/Android/GetStarted/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -GetStarted \ No newline at end of file diff --git a/Android/GetStarted/.idea/compiler.xml b/Android/GetStarted/.idea/compiler.xml deleted file mode 100644 index 1f2af51..0000000 --- a/Android/GetStarted/.idea/compiler.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Android/GetStarted/.idea/copyright/profiles_settings.xml b/Android/GetStarted/.idea/copyright/profiles_settings.xml deleted file mode 100644 index e7bedf3..0000000 --- a/Android/GetStarted/.idea/copyright/profiles_settings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/Android/GetStarted/.idea/encodings.xml b/Android/GetStarted/.idea/encodings.xml deleted file mode 100644 index 97626ba..0000000 --- a/Android/GetStarted/.idea/encodings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Android/GetStarted/.idea/gradle.xml b/Android/GetStarted/.idea/gradle.xml deleted file mode 100644 index ee6ddd0..0000000 --- a/Android/GetStarted/.idea/gradle.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Android/GetStarted/.idea/misc.xml b/Android/GetStarted/.idea/misc.xml deleted file mode 100644 index 95f0f03..0000000 --- a/Android/GetStarted/.idea/misc.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Android/GetStarted/.idea/modules.xml b/Android/GetStarted/.idea/modules.xml deleted file mode 100644 index 3eb187a..0000000 --- a/Android/GetStarted/.idea/modules.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/Android/GetStarted/GetStarted.iml b/Android/GetStarted/GetStarted.iml deleted file mode 100644 index e436f49..0000000 --- a/Android/GetStarted/GetStarted.iml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Android/GetStarted/README.md b/Android/GetStarted/README.md deleted file mode 100644 index 783a444..0000000 --- a/Android/GetStarted/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# Get Started with Notification Hubs on Android - -This Android Studio 2.0 project is a copy of the completed code for the [Sending push notifications to Android with Azure Notification Hubs](https://azure.microsoft.com/documentation/articles/notification-hubs-android-get-started/) tutorial. - -* You must update your **Google (GCM)** access policy on the setting blade of your notification hub with the GCM API key you created for your Android app. - -* You must also update the following placeholders in [NotificationSettings.java](./app/src/main/java/com/example/microsoft/getstarted/NotificationSettings.java): - - - **SenderId**: Set to the project number that you obtained earlier from the project that you created in the Google Cloud Console. - - **HubName**: Use the name of your notification hub that appears at the top of the page in Azure for your hub (not the full URL). For example, use "myhub". - - **HubListenConnectionString**: Set to the DefaultListenAccessSignature connection string for your hub. You can copy that connection string by clicking keys button on the main page for your hub on the Azure portal. - - **HubFullAccess**: This is only needed if you want to send notifications from the app instead of a backend. Update `HubFullAccess` with the **DefaultFullSharedAccessSignature** connection string for your hub. This connection string can be copied by clicking keys button on the main page for your hub on the Azure portal. diff --git a/Android/GetStarted/app/.gitignore b/Android/GetStarted/app/.gitignore deleted file mode 100644 index 796b96d..0000000 --- a/Android/GetStarted/app/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/Android/GetStarted/app/app.iml b/Android/GetStarted/app/app.iml deleted file mode 100644 index c4a4087..0000000 --- a/Android/GetStarted/app/app.iml +++ /dev/null @@ -1,125 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Android/GetStarted/app/build.gradle b/Android/GetStarted/app/build.gradle deleted file mode 100644 index d155d97..0000000 --- a/Android/GetStarted/app/build.gradle +++ /dev/null @@ -1,38 +0,0 @@ -apply plugin: 'com.android.application' -//apply plugin: 'com.google.gms.google-services' - - -android { - compileSdkVersion 23 - buildToolsVersion "21.1.2" - - defaultConfig { - applicationId "com.example.microsoft.getstarted" - minSdkVersion 9 - targetSdkVersion 23 - versionCode 1 - versionName "1.0" - } - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } -} - - -dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - testCompile 'junit:junit:4.12' - compile 'com.google.android.gms:play-services-gcm:8.4.0' - compile 'com.android.support:appcompat-v7:23.2.0' - compile 'com.microsoft.azure:azure-notifications-handler:1.0.1@aar' - compile 'com.microsoft.azure:notification-hubs-android-sdk:0.4@aar' -} - -repositories { - maven { - url "http://dl.bintray.com/microsoftazuremobile/SDK" - } -} diff --git a/Android/GetStarted/app/libs/notification-hubs-0.4.jar b/Android/GetStarted/app/libs/notification-hubs-0.4.jar deleted file mode 100644 index 132f3e0..0000000 Binary files a/Android/GetStarted/app/libs/notification-hubs-0.4.jar and /dev/null differ diff --git a/Android/GetStarted/app/proguard-rules.pro b/Android/GetStarted/app/proguard-rules.pro deleted file mode 100644 index cf9697c..0000000 --- a/Android/GetStarted/app/proguard-rules.pro +++ /dev/null @@ -1,17 +0,0 @@ -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in C:\Users\Wesley\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the proguardFiles -# directive in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} diff --git a/Android/GetStarted/app/src/androidTest/java/com/example/microsoft/getstarted/ApplicationTest.java b/Android/GetStarted/app/src/androidTest/java/com/example/microsoft/getstarted/ApplicationTest.java deleted file mode 100644 index d833202..0000000 --- a/Android/GetStarted/app/src/androidTest/java/com/example/microsoft/getstarted/ApplicationTest.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.example.microsoft.getstarted; - -import android.app.Application; -import android.test.ApplicationTestCase; - -/** - * Testing Fundamentals - */ -public class ApplicationTest extends ApplicationTestCase { - public ApplicationTest() { - super(Application.class); - } -} \ No newline at end of file diff --git a/Android/GetStarted/app/src/main/AndroidManifest.xml b/Android/GetStarted/app/src/main/AndroidManifest.xml deleted file mode 100644 index 8859e5d..0000000 --- a/Android/GetStarted/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Android/GetStarted/app/src/main/java/com/example/microsoft/getstarted/MainActivity.java b/Android/GetStarted/app/src/main/java/com/example/microsoft/getstarted/MainActivity.java deleted file mode 100644 index b392673..0000000 --- a/Android/GetStarted/app/src/main/java/com/example/microsoft/getstarted/MainActivity.java +++ /dev/null @@ -1,276 +0,0 @@ -package com.example.microsoft.getstarted; - -import android.content.Intent; -import android.support.v7.app.AppCompatActivity; -import android.os.Bundle; - -import com.google.android.gms.common.ConnectionResult; -import com.google.android.gms.common.GoogleApiAvailability; -import com.google.android.gms.gcm.*; -import com.microsoft.windowsazure.notifications.NotificationsManager; -import android.util.Log; -import android.widget.TextView; -import android.widget.Toast; - -import java.io.BufferedOutputStream; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLEncoder; -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; -import android.util.Base64; -import android.view.View; -import android.widget.EditText; - - -public class MainActivity extends AppCompatActivity { - - public static MainActivity mainActivity; - - private GoogleCloudMessaging gcm; - private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000; - public static Boolean isVisible = false; - private static final String TAG = "MainActivity"; - - private String HubEndpoint = null; - private String HubSasKeyName = null; - private String HubSasKeyValue = null; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - mainActivity = this; - NotificationsManager.handleNotifications(this, NotificationSettings.SenderId, MyHandler.class); - registerWithNotificationHubs(); - } - - public void registerWithNotificationHubs() - { - Log.i(TAG, " Registering with Notification Hubs"); - - if (checkPlayServices()) { - // Start IntentService to register this application with GCM. - Intent intent = new Intent(this, RegistrationIntentService.class); - startService(intent); - } - } - - /** - * Check the device to make sure it has the Google Play Services APK. If - * it doesn't, display a dialog that allows users to download the APK from - * the Google Play Store or enable it in the device's system settings. - */ - private boolean checkPlayServices() { - GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance(); - int resultCode = apiAvailability.isGooglePlayServicesAvailable(this); - if (resultCode != ConnectionResult.SUCCESS) { - if (apiAvailability.isUserResolvableError(resultCode)) { - apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST) - .show(); - } else { - Log.i(TAG, "This device is not supported by Google Play Services."); - ToastNotify("This device is not supported by Google Play Services."); - finish(); - } - return false; - } - return true; - } - - /** - * Example code from http://msdn.microsoft.com/library/azure/dn495627.aspx - * to parse the connection string so a SaS authentication token can be - * constructed. - * - * @param connectionString This must be the DefaultFullSharedAccess connection - * string for this example. - */ - private void ParseConnectionString(String connectionString) - { - String[] parts = connectionString.split(";"); - if (parts.length != 3) - throw new RuntimeException("Error parsing connection string: " - + connectionString); - - for (int i = 0; i < parts.length; i++) { - if (parts[i].startsWith("Endpoint")) { - this.HubEndpoint = "https" + parts[i].substring(11); - } else if (parts[i].startsWith("SharedAccessKeyName")) { - this.HubSasKeyName = parts[i].substring(20); - } else if (parts[i].startsWith("SharedAccessKey")) { - this.HubSasKeyValue = parts[i].substring(16); - } - } - } - - /** - * Example code from http://msdn.microsoft.com/library/azure/dn495627.aspx to - * construct a SaS token from the access key to authenticate a request. - * - * @param uri The unencoded resource URI string for this operation. The resource - * URI is the full URI of the Service Bus resource to which access is - * claimed. For example, - * "http://.servicebus.windows.net/" - */ - private String generateSasToken(String uri) { - - String targetUri; - String token = null; - try { - targetUri = URLEncoder - .encode(uri.toString().toLowerCase(), "UTF-8") - .toLowerCase(); - - long expiresOnDate = System.currentTimeMillis(); - int expiresInMins = 60; // 1 hour - expiresOnDate += expiresInMins * 60 * 1000; - long expires = expiresOnDate / 1000; - String toSign = targetUri + "\n" + expires; - - // Get an hmac_sha1 key from the raw key bytes - byte[] keyBytes = HubSasKeyValue.getBytes("UTF-8"); - SecretKeySpec signingKey = new SecretKeySpec(keyBytes, "HmacSHA256"); - - // Get an hmac_sha1 Mac instance and initialize with the signing key - Mac mac = Mac.getInstance("HmacSHA256"); - mac.init(signingKey); - - // Compute the hmac on input data bytes - byte[] rawHmac = mac.doFinal(toSign.getBytes("UTF-8")); - - // Using android.util.Base64 for Android Studio instead of - // Apache commons codec - String signature = URLEncoder.encode( - Base64.encodeToString(rawHmac, Base64.NO_WRAP).toString(), "UTF-8"); - - // Construct authorization string - token = "SharedAccessSignature sr=" + targetUri + "&sig=" - + signature + "&se=" + expires + "&skn=" + HubSasKeyName; - } catch (Exception e) { - if (isVisible) { - ToastNotify("Exception Generating SaS : " + e.getMessage().toString()); - } - } - - return token; - } - - /** - * Send Notification button click handler. This method parses the - * DefaultFullSharedAccess connection string and generates a SaS token. The - * token is added to the Authorization header on the POST request to the - * notification hub. The text in the editTextNotificationMessage control - * is added as the JSON body for the request to add a GCM message to the hub. - * - * @param v - */ - public void sendNotificationButtonOnClick(View v) { - EditText notificationText = (EditText) findViewById(R.id.editTextNotificationMessage); - final String json = "{\"data\":{\"message\":\"" + notificationText.getText().toString() + "\"}}"; - - new Thread() - { - public void run() - { - try - { - // Based on reference documentation... - // http://msdn.microsoft.com/library/azure/dn223273.aspx - ParseConnectionString(NotificationSettings.HubFullAccess); - URL url = new URL(HubEndpoint + NotificationSettings.HubName + - "/messages/?api-version=2015-01"); - - HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection(); - - try { - // POST request - urlConnection.setDoOutput(true); - - // Authenticate the POST request with the SaS token - urlConnection.setRequestProperty("Authorization", generateSasToken(url.toString())); - - // Notification format should be GCM - urlConnection.setRequestProperty("ServiceBusNotification-Format", "gcm"); - - // Include any tags - // Example below targets 3 specific tags - // Refer to : https://azure.microsoft.com/en-us/documentation/articles/notification-hubs-routing-tag-expressions/ - // urlConnection.setRequestProperty("ServiceBusNotification-Tags", "tag1 || tag2 || tag3"); - - // Send notification message - urlConnection.setFixedLengthStreamingMode(json.getBytes().length); - OutputStream bodyStream = new BufferedOutputStream(urlConnection.getOutputStream()); - bodyStream.write(json.getBytes()); - bodyStream.close(); - - // Get reponse - urlConnection.connect(); - int responseCode = urlConnection.getResponseCode(); - if ((responseCode != 200) && (responseCode != 201)) { - if (isVisible) { - BufferedReader br = new BufferedReader(new InputStreamReader((urlConnection.getErrorStream()))); - String line; - StringBuilder builder = new StringBuilder("Send Notification returned " + - responseCode + " : ") ; - while ((line = br.readLine()) != null) { - builder.append(line); - } - - ToastNotify(builder.toString()); - } - } - } finally { - urlConnection.disconnect(); - } - } - catch(Exception e) - { - if (isVisible) { - ToastNotify("Exception Sending Notification : " + e.getMessage().toString()); - } - } - } - }.start(); - } - - @Override - protected void onStart() { - super.onStart(); - isVisible = true; - } - - @Override - protected void onPause() { - super.onPause(); - isVisible = false; - } - - @Override - protected void onResume() { - super.onResume(); - isVisible = true; - } - - @Override - protected void onStop() { - super.onStop(); - isVisible = false; - } - - public void ToastNotify(final String notificationMessage) - { - runOnUiThread(new Runnable() { - @Override - public void run() { - Toast.makeText(MainActivity.this, notificationMessage, Toast.LENGTH_LONG).show(); - TextView helloText = (TextView) findViewById(R.id.text_hello); - helloText.setText(notificationMessage); - } - }); - } -} diff --git a/Android/GetStarted/app/src/main/java/com/example/microsoft/getstarted/MyHandler.java b/Android/GetStarted/app/src/main/java/com/example/microsoft/getstarted/MyHandler.java deleted file mode 100644 index d513011..0000000 --- a/Android/GetStarted/app/src/main/java/com/example/microsoft/getstarted/MyHandler.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.example.microsoft.getstarted; - -/** - * Created by Wesley on 4/8/2016. - */ - -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.media.RingtoneManager; -import android.net.Uri; -import android.os.Bundle; -import android.os.PowerManager; -import android.support.v4.app.NotificationCompat; -import com.microsoft.windowsazure.notifications.NotificationsHandler; - -public class MyHandler extends NotificationsHandler { - public static final int NOTIFICATION_ID = 1; - private NotificationManager mNotificationManager; - NotificationCompat.Builder builder; - Context ctx; - - @Override - public void onReceive(Context context, Bundle bundle) { - ctx = context; - String nhMessage = bundle.getString("message"); - sendNotification(nhMessage); - if (MainActivity.isVisible) { - MainActivity.mainActivity.ToastNotify(nhMessage); - } - } - - private void sendNotification(String msg) { - - Intent intent = new Intent(ctx, MainActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - - mNotificationManager = (NotificationManager) - ctx.getSystemService(Context.NOTIFICATION_SERVICE); - - PendingIntent contentIntent = PendingIntent.getActivity(ctx, 0, - intent, PendingIntent.FLAG_ONE_SHOT); - - Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); - NotificationCompat.Builder mBuilder = - new NotificationCompat.Builder(ctx) - .setSmallIcon(R.mipmap.ic_launcher) - .setContentTitle("Notification Hub Demo") - .setStyle(new NotificationCompat.BigTextStyle() - .bigText(msg)) - .setSound(defaultSoundUri) - .setContentText(msg); - - mBuilder.setContentIntent(contentIntent); - mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build()); - } - -} diff --git a/Android/GetStarted/app/src/main/java/com/example/microsoft/getstarted/MyInstanceIDService.java b/Android/GetStarted/app/src/main/java/com/example/microsoft/getstarted/MyInstanceIDService.java deleted file mode 100644 index 750ca76..0000000 --- a/Android/GetStarted/app/src/main/java/com/example/microsoft/getstarted/MyInstanceIDService.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.example.microsoft.getstarted; - -/** - * Created by Wesley on 4/7/2016. - */ - -import android.content.Intent; -import android.util.Log; -import com.google.android.gms.iid.InstanceIDListenerService; - - -public class MyInstanceIDService extends InstanceIDListenerService { - - private static final String TAG = "MyInstanceIDService"; - - @Override - public void onTokenRefresh() { - - Log.i(TAG, "Refreshing GCM Registration Token"); - - Intent intent = new Intent(this, RegistrationIntentService.class); - startService(intent); - } -}; \ No newline at end of file diff --git a/Android/GetStarted/app/src/main/java/com/example/microsoft/getstarted/NotificationSettings.java b/Android/GetStarted/app/src/main/java/com/example/microsoft/getstarted/NotificationSettings.java deleted file mode 100644 index 995fc07..0000000 --- a/Android/GetStarted/app/src/main/java/com/example/microsoft/getstarted/NotificationSettings.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.example.microsoft.getstarted; - -/** - * Created by Wesley on 4/11/2016. - */ -public class NotificationSettings { - public static String SenderId = ""; - public static String HubName = ""; - public static String HubListenConnectionString = "< your DefaultListenSharedAccessSignature>"; - public static String HubFullAccess = ""; -} diff --git a/Android/GetStarted/app/src/main/java/com/example/microsoft/getstarted/RegistrationIntentService.java b/Android/GetStarted/app/src/main/java/com/example/microsoft/getstarted/RegistrationIntentService.java deleted file mode 100644 index c046d22..0000000 --- a/Android/GetStarted/app/src/main/java/com/example/microsoft/getstarted/RegistrationIntentService.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.example.microsoft.getstarted; - -import android.app.IntentService; -import android.content.Intent; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; -import android.util.Log; - -import com.google.android.gms.gcm.GoogleCloudMessaging; -import com.google.android.gms.iid.InstanceID; -import com.microsoft.windowsazure.messaging.NotificationHub; - -/** - * Created by Wesley on 4/9/2016. - */ -public class RegistrationIntentService extends IntentService { - - private static final String TAG = "RegIntentService"; - - private NotificationHub hub; - - public RegistrationIntentService() { - super(TAG); - } - - @Override - protected void onHandleIntent(Intent intent) { - - SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); - String resultString = null; - String regID = null; - - try { - InstanceID instanceID = InstanceID.getInstance(this); - String token = instanceID.getToken(NotificationSettings.SenderId, - GoogleCloudMessaging.INSTANCE_ID_SCOPE); - - Log.i(TAG, "Got GCM Registration Token: " + token); - - // Storing the registration id that indicates whether the generated token has been - // sent to your server. If it is not stored, send the token to your server, - // otherwise your server should have already received the token. - if ((regID=sharedPreferences.getString("registrationID", null)) == null) { - - NotificationHub hub = new NotificationHub(NotificationSettings.HubName, - NotificationSettings.HubListenConnectionString, this); - Log.i(TAG, "Attempting to register with NH using token : " + token); - - regID = hub.register(token).getRegistrationId(); - - // If you want to use tags... - // Refer to : https://azure.microsoft.com/en-us/documentation/articles/notification-hubs-routing-tag-expressions/ - // regID = hub.register(token, "tag1,tag2").getRegistrationId(); - - resultString = "Registered Successfully - RegId : " + regID; - Log.i(TAG, resultString); - - sharedPreferences.edit().putString("registrationID", regID ).apply(); - } else { - resultString = "Previously Registered Successfully - RegId : " + regID; - } - } catch (Exception e) { - Log.e(TAG, resultString="Failed to complete token refresh", e); - // If an exception happens while fetching the new token or updating our registration data - // on a third-party server, this ensures that we'll attempt the update at a later time. - } - - // Notify UI that registration has completed. - if (MainActivity.isVisible) { - MainActivity.mainActivity.ToastNotify(resultString); - } - } -} - diff --git a/Android/GetStarted/app/src/main/res/layout/activity_main.xml b/Android/GetStarted/app/src/main/res/layout/activity_main.xml deleted file mode 100644 index ec77d9f..0000000 --- a/Android/GetStarted/app/src/main/res/layout/activity_main.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - -
-
-
- -Notification Hub Name:


-Connection String:
- -
- - - -
-
- - - - - - diff --git a/PushToChromeApps/register.js b/PushToChromeApps/register.js deleted file mode 100644 index 3c61726..0000000 --- a/PushToChromeApps/register.js +++ /dev/null @@ -1,146 +0,0 @@ -var registrationId = ""; -var hubName = "", connectionString = ""; -var originalUri = "", targetUri = "", endpoint = "", sasKeyName = "", sasKeyValue = "", sasToken = ""; - -window.onload = function() { - document.getElementById("registerWithGCM").onclick = registerWithGCM; - document.getElementById("registerWithNH").onclick = registerWithNH; - updateLog("You have not registered yet. Please provider sender ID and register with GCM and then Notifications Hub."); -} - -function updateLog(status) { - currentStatus = document.getElementById("console").innerHTML; - if (currentStatus != "") { - currentStatus = currentStatus + "\n\n"; - } - - document.getElementById("console").innerHTML = currentStatus + status; -} - -function registerWithGCM() { - var senderId = document.getElementById("senderId").value.trim(); - chrome.gcm.register([senderId], registerCallback); - - // Prevent register button from being clicked again before the registration finishes - document.getElementById("registerWithGCM").disabled = true; -} - - -function registerCallback(regId) { - registrationId = regId; - document.getElementById("registerWithGCM").disabled = false; - - if (chrome.runtime.lastError) { - // When the registration fails, handle the error and retry the - // registration later. - updateLog("Registration failed: " + chrome.runtime.lastError.message); - return; - } - - updateLog("Registration with GCM succeeded."); - document.getElementById("registerWithNH").disabled = false; - - // Mark that the first-time registration is done. - chrome.storage.local.set({registered: true}); -} - -function registerWithNH() { - hubName = document.getElementById("hubName").value.trim(); - connectionString = document.getElementById("connectionString").value.trim(); - splitConnectionString(); - generateSaSToken(); - sendNHRegistrationRequest(); -} - -// From http://msdn.microsoft.com/en-us/library/dn495627.aspx -function splitConnectionString() -{ - var parts = connectionString.split(';'); - if (parts.length != 3) - throw "Error parsing connection string"; - - parts.forEach(function(part) { - if (part.indexOf('Endpoint') == 0) { - endpoint = 'https' + part.substring(11); - } else if (part.indexOf('SharedAccessKeyName') == 0) { - sasKeyName = part.substring(20); - } else if (part.indexOf('SharedAccessKey') == 0) { - sasKeyValue = part.substring(16); - } - }); - - originalUri = endpoint + hubName; -} - -function generateSaSToken() -{ - targetUri = encodeURIComponent(originalUri.toLowerCase()).toLowerCase(); - var expiresInMins = 10; // 10 minute expiration - - // Set expiration in seconds - var expireOnDate = new Date(); - expireOnDate.setMinutes(expireOnDate.getMinutes() + expiresInMins); - var expires = Date.UTC(expireOnDate.getUTCFullYear(), expireOnDate - .getUTCMonth(), expireOnDate.getUTCDate(), expireOnDate - .getUTCHours(), expireOnDate.getUTCMinutes(), expireOnDate - .getUTCSeconds()) / 1000; - var tosign = targetUri + '\n' + expires; - - // using CryptoJS - var signature = CryptoJS.HmacSHA256(tosign, sasKeyValue); - var base64signature = signature.toString(CryptoJS.enc.Base64); - var base64UriEncoded = encodeURIComponent(base64signature); - - // construct authorization string - sasToken = "SharedAccessSignature sr=" + targetUri + "&sig=" - + base64UriEncoded + "&se=" + expires + "&skn=" + sasKeyName; -} - -function sendNHRegistrationRequest() -{ - var registrationPayload = - "" + - "" + - "" + - "" + - "{GCMRegistrationId}" + - "" + - "" + - ""; - - registrationPayload = registrationPayload.replace("{GCMRegistrationId}", registrationId); - - var url = originalUri + "/registrations/?api-version=2014-09"; - var client = new XMLHttpRequest(); - - client.onload = function () { - if (client.readyState == 4) { - if (client.status == 200) { - updateLog("Notification Hub Registration succesful!"); - updateLog(client.responseText); - } else { - updateLog("Notification Hub Registration did not succeed!"); - updateLog("HTTP Status: " + client.status + " : " + client.statusText); - updateLog("HTTP Response: " + "\n" + client.responseText); - } - } - }; - - client.onerror = function () { - updateLog("ERROR - Notification Hub Registration did not succeed!"); - } - - client.open("POST", url, true); - client.setRequestHeader("Content-Type", "application/atom+xml;type=entry;charset=utf-8"); - client.setRequestHeader("Authorization", sasToken); - client.setRequestHeader("x-ms-version", "2014-09"); - - try { - client.send(registrationPayload); - } - catch(err) { - updateLog(err.message); - } -} - - diff --git a/PushToSLPhoneApp/README.md b/PushToSLPhoneApp/README.md deleted file mode 100644 index 59184f3..0000000 --- a/PushToSLPhoneApp/README.md +++ /dev/null @@ -1,203 +0,0 @@ -# Azure Notification Hubs - Push to Windows Phone Silverlight application - -Azure Notification Hubs Windows Phone SDK currently does not support using WNS with Windows Phone 8.1 Silverlight apps. This sample takes you through the steps to create a Windows Phone 8.1 Silverlight app which registers with Azure Notification Hubs (ANH) so that it can receive notifications via ANH. - -If you have a Windows Universal application then see this for how to use ANH to do notifications with WNS - [Notification Hubs - Windows Universal tutorial]. - -If you have a Windows Phone application (non- Silverlight) then see this for how to use ANH to do notifications with MPNS - [Notification Hubs - Windows Phone tutorial]. - -Here are couple of links to provide guidance (from Windows Dev Center) - - -- [Windows Phone 8 app developer guidance] -- [MPNS/WNS guidance] - -###Steps:### - -1. Open up Visual Studio and create a Windows Phone Silverlight application. - - ![][4] - -2. Register your app for the Windows Store if not already. You can follow the instructions at [Notification Hubs - Windows Universal tutorial] (see section - *Register your app for the Windows Store*) - -3. Make a note of the *Package SID*, *Client Secret* and *Application Identity*. - -4. Create an Azure Notification Hub and configure the Package SID and Client Secret you obtained from the previous step in here. You can follow the instructions at [Notification Hubs - Windows Universal tutorial] on how to do this (see section - *Configure your Notification Hub*) - -5. For your Windows Phone Silverlight app - open up the *Package.appxmanifest* and configure *Identity Name="[UPDATE THIS]" Publisher="[UPDATE THIS]"* based on what you obtained from *Application Identity* e.g. - - - -6. Open up the package.appxmanifest in Visual Studio and enable Toast notifications. - - ![][2] - -7. Also enable **Internet (Client & Server)** capability. - - ![][3] - -8. Remove any unneeded declarations from the *Declaration* tab in package.appxmanifest file. - -9. Make sure you are calling the following method at the app startup. Configure your *Notification Hub name* and the *DefaultListenSharedAccessSignature*. - - public async void RegisterToReceiveNotifications() - { - string notificationHubName = "[hubName]"; - string connectionString = "[ConnectionString-DefaultListenSharedAccessSignature]"; - - // Register with WNS - var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync(); - - // Register with Azure Notification Hubs - NotificationHub hub = new NotificationHub(notificationHubName, connectionString); - hub.Register(channel.Uri); - Debug.WriteLine("ChannelURI : {0}", channel.Uri); - } - -10. Add a Notification Hub class which abstracts the functionality of registering with the Azure Notification Hubs. This is based on [Notification Hubs REST APIs]. See explanation in the following steps: - - class NotificationHub - { - private const string ApiVersion = "?api-version=2014-09"; - private const string AuthHeader = "Authorization"; - private const string ContentType = "application/atom+xml;type=entry;charset=utf-8"; - - static string HubName { get; set; } - static string ConnectionString { get; set; } - static string Endpoint { get; set; } - static string SasKeyName { get; set; } - static string SasKeyValue { get; set; } - static string Payload { get; set; } - - public NotificationHub(string hubName, string connectionString) - { - HubName = hubName; - ConnectionString = connectionString; - } - - public void Register(string pushChannel) - { - ParseConnectionInfo(); - SendNHRegistrationRequest(pushChannel); - } - - // From http://msdn.microsoft.com/en-us/library/dn495627.aspx - private static void ParseConnectionInfo() - { - if (string.IsNullOrWhiteSpace(HubName)) - { - throw new InvalidOperationException("Hub name is empty"); - } - - var parts = ConnectionString.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries); - - if (parts.Length != 3) - { - throw new InvalidOperationException("Error parsing connection string: " + ConnectionString); - } - - foreach (var part in parts) - { - if (part.StartsWith("Endpoint")) - { - Endpoint = "https" + part.Substring(11); - } - else if (part.StartsWith("SharedAccessKeyName")) - { - SasKeyName = part.Substring(20); - } - else if (part.StartsWith("SharedAccessKey")) - { - SasKeyValue = part.Substring(16); - } - } - } - private static string GenerateSaSToken(Uri uri) - { - var targetUri = WebUtility.UrlEncode(uri.ToString().ToLower()).ToLower(); - - var expiresOnDate = Convert.ToInt64(DateTime.UtcNow.Subtract - (new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds) + 60 * 60; - var toSign = targetUri + "\n" + expiresOnDate; - - var keyBytes = Encoding.UTF8.GetBytes(SasKeyValue); - var mac = new HMACSHA256(keyBytes); - mac.Initialize(); - var rawHmac = mac.ComputeHash(Encoding.UTF8.GetBytes(toSign)); - var signature = WebUtility.UrlEncode(Convert.ToBase64String(rawHmac)); - - var token = "SharedAccessSignature sr=" + targetUri + "&sig=" - + signature + "&se=" + expiresOnDate + "&skn=" + SasKeyName; - return token; - } - - private static void SendNHRegistrationRequest(string pushChannel) - { - Payload = - @" - - - - {WindowsPushChannel} - - - "; - - Payload = Payload.Replace("{WindowsPushChannel}", pushChannel); - - var uri = new Uri(Endpoint + HubName + "/registrations/" + ApiVersion); - var sendRequest = WebRequest.CreateHttp(uri); - sendRequest.Method = "POST"; - sendRequest.ContentType = ContentType; - sendRequest.Headers[AuthHeader] = GenerateSaSToken(uri); - sendRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), sendRequest); - } - - static void GetRequestStreamCallback(IAsyncResult asynchronousResult) - { - HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; - // End the stream request operation - Stream postStream = request.EndGetRequestStream(asynchronousResult); - - byte[] byteArray = Encoding.UTF8.GetBytes(Payload); - - postStream.Write(byteArray, 0, byteArray.Length); - postStream.Close(); - - //Start the web request - request.BeginGetResponse(new AsyncCallback(GetResponceStreamCallback), request); - } - - static void GetResponceStreamCallback(IAsyncResult callbackResult) - { - HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState; - HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult); - using (StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream())) - { - string result = httpWebStreamReader.ReadToEnd(); - //For debug: show results - Debug.WriteLine(result); - } - } - } - -11. `ParseConnectionInfo` & `GenerateSaSToken` are used to create the standard Authorization header you need to communicate with Azure Notification Hubs. - -12. `SendNHRegistrationRequest` crafts the HTTP request to register with the Azure Notification Hubs by using HttpWebRequest. - -13. Now you can send a test notification to test this. I used Visual Studio to test this but you can use Portal or a simple console application to do the same. - - ![][1] - - -[Windows Dev Center]: http://go.microsoft.com/fwlink/p/?linkid=266582&clcid=0x409 -[Notification Hubs - Windows Universal tutorial]: http://azure.microsoft.com/en-us/documentation/articles/notification-hubs-windows-store-dotnet-get-started/ -[Notification Hubs - Windows Phone tutorial]: http://azure.microsoft.com/en-us/documentation/articles/notification-hubs-windows-phone-get-started/ -[MPNS/WNS guidance]: http://msdn.microsoft.com/en-us/library/windows/apps/dn642085(v=vs.105).aspx -[Windows Phone 8 app developer guidance]: http://msdn.microsoft.com/en-us/library/windows/apps/dn655121(v=vs.105).aspx -[Notification Hubs REST APIs]: http://msdn.microsoft.com/en-us/library/azure/dn223264.aspx - - -[1]: ./media/SuccessfulPush.png -[2]: ./media/EnableToast.png -[3]: ./media/EnableInternetCapability.png -[4]: ./media/CreateSLPhoneApp.png diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification.sln b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification.sln deleted file mode 100644 index 986f749..0000000 --- a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification.sln +++ /dev/null @@ -1,40 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.30723.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SilverlightPhoneAppPushNotification", "SilverlightPhoneAppPushNotification\SilverlightPhoneAppPushNotification.csproj", "{19C3776F-38F1-4512-B99E-423ADDD50A9E}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|ARM = Debug|ARM - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|ARM = Release|ARM - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {19C3776F-38F1-4512-B99E-423ADDD50A9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {19C3776F-38F1-4512-B99E-423ADDD50A9E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {19C3776F-38F1-4512-B99E-423ADDD50A9E}.Debug|Any CPU.Deploy.0 = Debug|Any CPU - {19C3776F-38F1-4512-B99E-423ADDD50A9E}.Debug|ARM.ActiveCfg = Debug|ARM - {19C3776F-38F1-4512-B99E-423ADDD50A9E}.Debug|ARM.Build.0 = Debug|ARM - {19C3776F-38F1-4512-B99E-423ADDD50A9E}.Debug|ARM.Deploy.0 = Debug|ARM - {19C3776F-38F1-4512-B99E-423ADDD50A9E}.Debug|x86.ActiveCfg = Debug|x86 - {19C3776F-38F1-4512-B99E-423ADDD50A9E}.Debug|x86.Build.0 = Debug|x86 - {19C3776F-38F1-4512-B99E-423ADDD50A9E}.Debug|x86.Deploy.0 = Debug|x86 - {19C3776F-38F1-4512-B99E-423ADDD50A9E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {19C3776F-38F1-4512-B99E-423ADDD50A9E}.Release|Any CPU.Build.0 = Release|Any CPU - {19C3776F-38F1-4512-B99E-423ADDD50A9E}.Release|Any CPU.Deploy.0 = Release|Any CPU - {19C3776F-38F1-4512-B99E-423ADDD50A9E}.Release|ARM.ActiveCfg = Release|ARM - {19C3776F-38F1-4512-B99E-423ADDD50A9E}.Release|ARM.Build.0 = Release|ARM - {19C3776F-38F1-4512-B99E-423ADDD50A9E}.Release|ARM.Deploy.0 = Release|ARM - {19C3776F-38F1-4512-B99E-423ADDD50A9E}.Release|x86.ActiveCfg = Release|x86 - {19C3776F-38F1-4512-B99E-423ADDD50A9E}.Release|x86.Build.0 = Release|x86 - {19C3776F-38F1-4512-B99E-423ADDD50A9E}.Release|x86.Deploy.0 = Release|x86 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification.v12.suo b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification.v12.suo deleted file mode 100644 index 16a0587..0000000 Binary files a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification.v12.suo and /dev/null differ diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/App.xaml b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/App.xaml deleted file mode 100644 index 1aca9d5..0000000 --- a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/App.xaml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/App.xaml.cs b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/App.xaml.cs deleted file mode 100644 index 1c98a94..0000000 --- a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/App.xaml.cs +++ /dev/null @@ -1,232 +0,0 @@ -using System; -using System.Diagnostics; -using System.Resources; -using System.Windows; -using System.Windows.Markup; -using System.Windows.Navigation; -using Microsoft.Phone.Controls; -using Microsoft.Phone.Shell; -using SilverlightPhoneAppPushNotification.Resources; - -namespace SilverlightPhoneAppPushNotification -{ - public partial class App : Application - { - /// - /// Provides easy access to the root frame of the Phone Application. - /// - /// The root frame of the Phone Application. - public static PhoneApplicationFrame RootFrame { get; private set; } - - /// - /// Constructor for the Application object. - /// - public App() - { - // Global handler for uncaught exceptions. - UnhandledException += Application_UnhandledException; - - // Standard XAML initialization - InitializeComponent(); - - // Phone-specific initialization - InitializePhoneApplication(); - - // Language display initialization - InitializeLanguage(); - - // Show graphics profiling information while debugging. - if (Debugger.IsAttached) - { - // Display the current frame rate counters. - Application.Current.Host.Settings.EnableFrameRateCounter = true; - - // Show the areas of the app that are being redrawn in each frame. - //Application.Current.Host.Settings.EnableRedrawRegions = true; - - // Enable non-production analysis visualization mode, - // which shows areas of a page that are handed off to GPU with a colored overlay. - //Application.Current.Host.Settings.EnableCacheVisualization = true; - - // Prevent the screen from turning off while under the debugger by disabling - // the application's idle detection. - // Caution:- Use this under debug mode only. Application that disables user idle detection will continue to run - // and consume battery power when the user is not using the phone. - PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled; - } - - } - - // Code to execute when a contract activation such as a file open or save picker returns - // with the picked file or other return values - private void Application_ContractActivated(object sender, Windows.ApplicationModel.Activation.IActivatedEventArgs e) - { - } - - // Code to execute when the application is launching (eg, from Start) - // This code will not execute when the application is reactivated - private void Application_Launching(object sender, LaunchingEventArgs e) - { - } - - // Code to execute when the application is activated (brought to foreground) - // This code will not execute when the application is first launched - private void Application_Activated(object sender, ActivatedEventArgs e) - { - } - - // Code to execute when the application is deactivated (sent to background) - // This code will not execute when the application is closing - private void Application_Deactivated(object sender, DeactivatedEventArgs e) - { - } - - // Code to execute when the application is closing (eg, user hit Back) - // This code will not execute when the application is deactivated - private void Application_Closing(object sender, ClosingEventArgs e) - { - } - - // Code to execute if a navigation fails - private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e) - { - if (Debugger.IsAttached) - { - // A navigation has failed; break into the debugger - Debugger.Break(); - } - } - - // Code to execute on Unhandled Exceptions - private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e) - { - if (Debugger.IsAttached) - { - // An unhandled exception has occurred; break into the debugger - Debugger.Break(); - } - } - - #region Phone application initialization - - // Avoid double-initialization - private bool phoneApplicationInitialized = false; - - // Do not add any additional code to this method - private void InitializePhoneApplication() - { - if (phoneApplicationInitialized) - return; - - // Create the frame but don't set it as RootVisual yet; this allows the splash - // screen to remain active until the application is ready to render. - RootFrame = new PhoneApplicationFrame(); - RootFrame.Navigated += CompleteInitializePhoneApplication; - - // Handle navigation failures - RootFrame.NavigationFailed += RootFrame_NavigationFailed; - - // Handle reset requests for clearing the backstack - RootFrame.Navigated += CheckForResetNavigation; - - // Handle contract activation such as a file open or save picker - PhoneApplicationService.Current.ContractActivated += Application_ContractActivated; - - // Ensure we don't initialize again - phoneApplicationInitialized = true; - } - - // Do not add any additional code to this method - private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e) - { - // Set the root visual to allow the application to render - if (RootVisual != RootFrame) - RootVisual = RootFrame; - - // Remove this handler since it is no longer needed - RootFrame.Navigated -= CompleteInitializePhoneApplication; - } - - private void CheckForResetNavigation(object sender, NavigationEventArgs e) - { - // If the app has received a 'reset' navigation, then we need to check - // on the next navigation to see if the page stack should be reset - if (e.NavigationMode == NavigationMode.Reset) - RootFrame.Navigated += ClearBackStackAfterReset; - } - - private void ClearBackStackAfterReset(object sender, NavigationEventArgs e) - { - // Unregister the event so it doesn't get called again - RootFrame.Navigated -= ClearBackStackAfterReset; - - // Only clear the stack for 'new' (forward) and 'refresh' navigations - if (e.NavigationMode != NavigationMode.New && e.NavigationMode != NavigationMode.Refresh) - return; - - // For UI consistency, clear the entire page stack - while (RootFrame.RemoveBackEntry() != null) - { - ; // do nothing - } - } - - #endregion - - // Initialize the app's font and flow direction as defined in its localized resource strings. - // - // To ensure that the font of your application is aligned with its supported languages and that the - // FlowDirection for each of those languages follows its traditional direction, ResourceLanguage - // and ResourceFlowDirection should be initialized in each resx file to match these values with that - // file's culture. For example: - // - // AppResources.es-ES.resx - // ResourceLanguage's value should be "es-ES" - // ResourceFlowDirection's value should be "LeftToRight" - // - // AppResources.ar-SA.resx - // ResourceLanguage's value should be "ar-SA" - // ResourceFlowDirection's value should be "RightToLeft" - // - // For more info on localizing Windows Phone apps see http://go.microsoft.com/fwlink/?LinkId=262072. - // - private void InitializeLanguage() - { - try - { - // Set the font to match the display language defined by the - // ResourceLanguage resource string for each supported language. - // - // Fall back to the font of the neutral language if the Display - // language of the phone is not supported. - // - // If a compiler error is hit then ResourceLanguage is missing from - // the resource file. - RootFrame.Language = XmlLanguage.GetLanguage(AppResources.ResourceLanguage); - - // Set the FlowDirection of all elements under the root frame based - // on the ResourceFlowDirection resource string for each - // supported language. - // - // If a compiler error is hit then ResourceFlowDirection is missing from - // the resource file. - FlowDirection flow = (FlowDirection)Enum.Parse(typeof(FlowDirection), AppResources.ResourceFlowDirection); - RootFrame.FlowDirection = flow; - } - catch - { - // If an exception is caught here it is most likely due to either - // ResourceLangauge not being correctly set to a supported language - // code or ResourceFlowDirection is set to a value other than LeftToRight - // or RightToLeft. - - if (Debugger.IsAttached) - { - Debugger.Break(); - } - - throw; - } - } - } -} \ No newline at end of file diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/ApplicationInsights.config b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/ApplicationInsights.config deleted file mode 100644 index d64080c..0000000 --- a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/ApplicationInsights.config +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - 6e75f05b-fdbd-4f69-b07d-fdeff545226c - \ No newline at end of file diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/AlignmentGrid.png b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/AlignmentGrid.png deleted file mode 100644 index f7d2e97..0000000 Binary files a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/AlignmentGrid.png and /dev/null differ diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/ApplicationIcon.png b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/ApplicationIcon.png deleted file mode 100644 index 7d95d4e..0000000 Binary files a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/ApplicationIcon.png and /dev/null differ diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/BadgeLogo.png b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/BadgeLogo.png deleted file mode 100644 index eb5bb83..0000000 Binary files a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/BadgeLogo.png and /dev/null differ diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/Logo.png b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/Logo.png deleted file mode 100644 index f2e1f40..0000000 Binary files a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/Logo.png and /dev/null differ diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/SplashScreen.png b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/SplashScreen.png deleted file mode 100644 index 4b90728..0000000 Binary files a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/SplashScreen.png and /dev/null differ diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/SquareTile150x150.png b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/SquareTile150x150.png deleted file mode 100644 index ec1d121..0000000 Binary files a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/SquareTile150x150.png and /dev/null differ diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/SquareTile71x71.png b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/SquareTile71x71.png deleted file mode 100644 index 4754af3..0000000 Binary files a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/SquareTile71x71.png and /dev/null differ diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/StoreLogo.png b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/StoreLogo.png deleted file mode 100644 index 12c5f4f..0000000 Binary files a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/StoreLogo.png and /dev/null differ diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/Tiles/FlipCycleTileLarge.png b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/Tiles/FlipCycleTileLarge.png deleted file mode 100644 index e0c59ac..0000000 Binary files a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/Tiles/FlipCycleTileLarge.png and /dev/null differ diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/Tiles/FlipCycleTileMedium.png b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/Tiles/FlipCycleTileMedium.png deleted file mode 100644 index e93b89d..0000000 Binary files a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/Tiles/FlipCycleTileMedium.png and /dev/null differ diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/Tiles/FlipCycleTileSmall.png b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/Tiles/FlipCycleTileSmall.png deleted file mode 100644 index 550b1b5..0000000 Binary files a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/Tiles/FlipCycleTileSmall.png and /dev/null differ diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/Tiles/IconicTileMediumLarge.png b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/Tiles/IconicTileMediumLarge.png deleted file mode 100644 index 686e6b5..0000000 Binary files a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/Tiles/IconicTileMediumLarge.png and /dev/null differ diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/Tiles/IconicTileSmall.png b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/Tiles/IconicTileSmall.png deleted file mode 100644 index d4b5ede..0000000 Binary files a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/Tiles/IconicTileSmall.png and /dev/null differ diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/WideLogo.png b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/WideLogo.png deleted file mode 100644 index 082197b..0000000 Binary files a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Assets/WideLogo.png and /dev/null differ diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/LocalizedStrings.cs b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/LocalizedStrings.cs deleted file mode 100644 index f024464..0000000 --- a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/LocalizedStrings.cs +++ /dev/null @@ -1,14 +0,0 @@ -using SilverlightPhoneAppPushNotification.Resources; - -namespace SilverlightPhoneAppPushNotification -{ - /// - /// Provides access to string resources. - /// - public class LocalizedStrings - { - private static AppResources _localizedResources = new AppResources(); - - public AppResources LocalizedResources { get { return _localizedResources; } } - } -} \ No newline at end of file diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/MainPage.xaml b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/MainPage.xaml deleted file mode 100644 index dd4d179..0000000 --- a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/MainPage.xaml +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/MainPage.xaml.cs b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/MainPage.xaml.cs deleted file mode 100644 index dd6e38d..0000000 --- a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/MainPage.xaml.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Microsoft.Phone.Controls; -using System; -using System.Diagnostics; -using Windows.Networking.PushNotifications; - -namespace SilverlightPhoneAppPushNotification -{ - public partial class MainPage : PhoneApplicationPage - { - // Constructor - public MainPage() - { - InitializeComponent(); - - // Register with Azure Notification Hubs - RegisterToReceiveNotifications(); - } - - public async void RegisterToReceiveNotifications() - { - string notificationHubName = "[hubName]"; - string connectionString = "[ConnectionString-DefaultListenSharedAccessSignature]"; - - // Register with WNS - var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync(); - - // Register with Azure Notification Hubs - NotificationHub hub = new NotificationHub(notificationHubName, connectionString); - hub.Register(channel.Uri); - Debug.WriteLine("ChannelURI : {0}", channel.Uri); - } - } -} \ No newline at end of file diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/NotificationHub.cs b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/NotificationHub.cs deleted file mode 100644 index 02c257a..0000000 --- a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/NotificationHub.cs +++ /dev/null @@ -1,134 +0,0 @@ -using System; -using System.Diagnostics; -using System.IO; -using System.Net; -using System.Security.Cryptography; -using System.Text; - -namespace SilverlightPhoneAppPushNotification -{ - class NotificationHub - { - private const string ApiVersion = "?api-version=2014-09"; - private const string AuthHeader = "Authorization"; - private const string ContentType = "application/atom+xml;type=entry;charset=utf-8"; - - static string HubName { get; set; } - static string ConnectionString { get; set; } - static string Endpoint { get; set; } - static string SasKeyName { get; set; } - static string SasKeyValue { get; set; } - static string Payload { get; set; } - - public NotificationHub(string hubName, string connectionString) - { - HubName = hubName; - ConnectionString = connectionString; - } - - public void Register(string pushChannel) - { - ParseConnectionInfo(); - SendNHRegistrationRequest(pushChannel); - } - - // From http://msdn.microsoft.com/en-us/library/dn495627.aspx - private static void ParseConnectionInfo() - { - if (string.IsNullOrWhiteSpace(HubName)) - { - throw new InvalidOperationException("Hub name is empty"); - } - - var parts = ConnectionString.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries); - - if (parts.Length != 3) - { - throw new InvalidOperationException("Error parsing connection string: " + ConnectionString); - } - - foreach (var part in parts) - { - if (part.StartsWith("Endpoint")) - { - Endpoint = "https" + part.Substring(11); - } - else if (part.StartsWith("SharedAccessKeyName")) - { - SasKeyName = part.Substring(20); - } - else if (part.StartsWith("SharedAccessKey")) - { - SasKeyValue = part.Substring(16); - } - } - } - private static string GenerateSaSToken(Uri uri) - { - var targetUri = WebUtility.UrlEncode(uri.ToString().ToLower()).ToLower(); - - var expiresOnDate = Convert.ToInt64(DateTime.UtcNow.Subtract - (new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds) + 60 * 60; - var toSign = targetUri + "\n" + expiresOnDate; - - var keyBytes = Encoding.UTF8.GetBytes(SasKeyValue); - var mac = new HMACSHA256(keyBytes); - mac.Initialize(); - var rawHmac = mac.ComputeHash(Encoding.UTF8.GetBytes(toSign)); - var signature = WebUtility.UrlEncode(Convert.ToBase64String(rawHmac)); - - var token = "SharedAccessSignature sr=" + targetUri + "&sig=" - + signature + "&se=" + expiresOnDate + "&skn=" + SasKeyName; - return token; - } - - private static void SendNHRegistrationRequest(string pushChannel) - { - Payload = - @" - - - - {WindowsPushChannel} - - - "; - - Payload = Payload.Replace("{WindowsPushChannel}", pushChannel); - - var uri = new Uri(Endpoint + HubName + "/registrations/" + ApiVersion); - var sendRequest = WebRequest.CreateHttp(uri); - sendRequest.Method = "POST"; - sendRequest.ContentType = ContentType; - sendRequest.Headers[AuthHeader] = GenerateSaSToken(uri); - sendRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), sendRequest); - } - - static void GetRequestStreamCallback(IAsyncResult asynchronousResult) - { - HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; - // End the stream request operation - Stream postStream = request.EndGetRequestStream(asynchronousResult); - - byte[] byteArray = Encoding.UTF8.GetBytes(Payload); - - postStream.Write(byteArray, 0, byteArray.Length); - postStream.Close(); - - //Start the web request - request.BeginGetResponse(new AsyncCallback(GetResponceStreamCallback), request); - } - - static void GetResponceStreamCallback(IAsyncResult callbackResult) - { - HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState; - HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult); - using (StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream())) - { - string result = httpWebStreamReader.ReadToEnd(); - //For debug: show results - Debug.WriteLine(result); - } - } - } -} diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Package.appxmanifest b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Package.appxmanifest deleted file mode 100644 index 24e0d13..0000000 --- a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Package.appxmanifest +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - SilverlightPhoneAppPushNotification - piyushjo - Assets\StoreLogo.png - - - 6.3.1 - 6.3.1 - - - - - - - - - - - - - - - - - AgHostSvcs.dll - - - - - - - - \ No newline at end of file diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Properties/AppManifest.xml b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Properties/AppManifest.xml deleted file mode 100644 index 6712a11..0000000 --- a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Properties/AppManifest.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Properties/AssemblyInfo.cs b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Properties/AssemblyInfo.cs deleted file mode 100644 index 7afb1fb..0000000 --- a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Resources; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("SilverlightPhoneAppPushNotification")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("SilverlightPhoneAppPushNotification")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("2fb337b8-aafa-45ec-9222-1f72ddbd5f73")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] -[assembly: NeutralResourcesLanguageAttribute("en-US")] diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Properties/WMAppManifest.xml b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Properties/WMAppManifest.xml deleted file mode 100644 index 95f1f69..0000000 --- a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Properties/WMAppManifest.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - Assets\ApplicationIcon.png - - - - - - - - - - - - - - Assets\Tiles\FlipCycleTileSmall.png - 0 - Assets\Tiles\FlipCycleTileMedium.png - SilverlightPhoneAppPushNotification - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Resources/AppResources.Designer.cs b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Resources/AppResources.Designer.cs deleted file mode 100644 index c64e564..0000000 --- a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Resources/AppResources.Designer.cs +++ /dev/null @@ -1,127 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.17626 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace SilverlightPhoneAppPushNotification.Resources -{ - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - public class AppResources - { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal AppResources() - { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - public static global::System.Resources.ResourceManager ResourceManager - { - get - { - if (object.ReferenceEquals(resourceMan, null)) - { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SilverlightPhoneAppPushNotification.Resources.AppResources", typeof(AppResources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - public static global::System.Globalization.CultureInfo Culture - { - get - { - return resourceCulture; - } - set - { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to LeftToRight. - /// - public static string ResourceFlowDirection - { - get - { - return ResourceManager.GetString("ResourceFlowDirection", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to us-EN. - /// - public static string ResourceLanguage - { - get - { - return ResourceManager.GetString("ResourceLanguage", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to MY APPLICATION. - /// - public static string ApplicationTitle - { - get - { - return ResourceManager.GetString("ApplicationTitle", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to button. - /// - public static string AppBarButtonText - { - get - { - return ResourceManager.GetString("AppBarButtonText", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to menu item. - /// - public static string AppBarMenuItemText - { - get - { - return ResourceManager.GetString("AppBarMenuItemText", resourceCulture); - } - } - } -} diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Resources/AppResources.resx b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Resources/AppResources.resx deleted file mode 100644 index 529a194..0000000 --- a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/Resources/AppResources.resx +++ /dev/null @@ -1,137 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - LeftToRight - Controls the FlowDirection for all elements in the RootFrame. Set to the traditional direction of this resource file's language - - - en-US - Controls the Language and ensures that the font for all elements in the RootFrame aligns with the app's language. Set to the language code of this resource file's language. - - - MY APPLICATION - - - add - - - Menu Item - - \ No newline at end of file diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/SilverlightPhoneAppPushNotification.csproj b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/SilverlightPhoneAppPushNotification.csproj deleted file mode 100644 index 0e55bf1..0000000 --- a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/SilverlightPhoneAppPushNotification.csproj +++ /dev/null @@ -1,207 +0,0 @@ - - - - Debug - AnyCPU - 10.0.20506 - 2.0 - {19C3776F-38F1-4512-B99E-423ADDD50A9E} - {C089C8C0-30E0-4E22-80C0-CE093F111A43};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} - Library - Properties - SilverlightPhoneAppPushNotification - SilverlightPhoneAppPushNotification - WindowsPhone - v8.1 - $(TargetFrameworkVersion) - true - - - true - true - SilverlightPhoneAppPushNotification_$(Configuration)_$(Platform).xap - Properties\AppManifest.xml - SilverlightPhoneAppPushNotification.App - true - 12.0 - true - en-US - 326b01c6 - /subscriptions/44e92301-f755-4d77-9870-403adda5d1c3/resourcegroups/Default-ApplicationInsights-CentralUS/providers/microsoft.insights/components/SilverlightPhoneAppPushNotification - - - true - full - false - Bin\Debug - DEBUG;TRACE;SILVERLIGHT;WINDOWS_PHONE - true - true - prompt - 4 - - - pdbonly - true - Bin\Release - TRACE;SILVERLIGHT;WINDOWS_PHONE - true - true - prompt - 4 - - - true - full - false - Bin\x86\Debug - DEBUG;TRACE;SILVERLIGHT;WINDOWS_PHONE - true - true - prompt - 4 - - - pdbonly - true - Bin\x86\Release - TRACE;SILVERLIGHT;WINDOWS_PHONE - true - true - prompt - 4 - - - true - full - false - Bin\ARM\Debug - DEBUG;TRACE;SILVERLIGHT;WINDOWS_PHONE - true - true - prompt - 4 - - - pdbonly - true - Bin\ARM\Release - TRACE;SILVERLIGHT;WINDOWS_PHONE - true - true - prompt - 4 - - - - App.xaml - - - - MainPage.xaml - - - - - True - True - AppResources.resx - - - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - - - Designer - - - - - - - - Designer - - - - - - PreserveNewest - - - - - - - - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - - - PublicResXFileCodeGenerator - AppResources.Designer.cs - - - - - ..\packages\Microsoft.ApplicationInsights.0.12.0-build17386\lib\wp8\Microsoft.ApplicationInsights.dll - - - ..\packages\Microsoft.ApplicationInsights.WindowsPhone.0.12.0-build17386\lib\wp8\Microsoft.ApplicationInsights.Extensibility.Windows.dll - - - ..\packages\Microsoft.Bcl.Async.1.0.168\lib\wp8\Microsoft.Threading.Tasks.dll - - - ..\packages\Microsoft.Bcl.Async.1.0.168\lib\wp8\Microsoft.Threading.Tasks.Extensions.dll - - - ..\packages\Microsoft.Bcl.Async.1.0.168\lib\wp8\Microsoft.Threading.Tasks.Extensions.Phone.dll - - - - - - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - \ No newline at end of file diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/SilverlightPhoneAppPushNotification.csproj.user b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/SilverlightPhoneAppPushNotification.csproj.user deleted file mode 100644 index d3122c8..0000000 --- a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/SilverlightPhoneAppPushNotification.csproj.user +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - True - Managed - Managed - False - - - - - \ No newline at end of file diff --git a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/packages.config b/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/packages.config deleted file mode 100644 index 23a2646..0000000 --- a/PushToSLPhoneApp/SilverlightPhoneAppPushNotification/packages.config +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/PushToSLPhoneApp/media/CreateSLPhoneApp.png b/PushToSLPhoneApp/media/CreateSLPhoneApp.png deleted file mode 100644 index 728923a..0000000 Binary files a/PushToSLPhoneApp/media/CreateSLPhoneApp.png and /dev/null differ diff --git a/PushToSLPhoneApp/media/EnableInternetCapability.png b/PushToSLPhoneApp/media/EnableInternetCapability.png deleted file mode 100644 index 5d7b226..0000000 Binary files a/PushToSLPhoneApp/media/EnableInternetCapability.png and /dev/null differ diff --git a/PushToSLPhoneApp/media/EnableToast.png b/PushToSLPhoneApp/media/EnableToast.png deleted file mode 100644 index 55646ed..0000000 Binary files a/PushToSLPhoneApp/media/EnableToast.png and /dev/null differ diff --git a/PushToSLPhoneApp/media/SuccessfulPush.png b/PushToSLPhoneApp/media/SuccessfulPush.png deleted file mode 100644 index 4621978..0000000 Binary files a/PushToSLPhoneApp/media/SuccessfulPush.png and /dev/null differ diff --git a/PushToSLPhoneApp/packages/repositories.config b/PushToSLPhoneApp/packages/repositories.config deleted file mode 100644 index 7739e4d..0000000 --- a/PushToSLPhoneApp/packages/repositories.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/PushToSafari/README.md b/PushToSafari/README.md index f321936..537f101 100644 --- a/PushToSafari/README.md +++ b/PushToSafari/README.md @@ -1,21 +1,21 @@ # Safari Push Notifications using Azure Notification Hubs and Azure WebSites This sample does a walkthrough of how you can implement Safari Push Notifications using [Azure Notification Hubs]. -Apple supports Safari Push Notifications which are widely popular and have been implemented on many notable sites like NYTimes.com. Once a user has consented to receive notifications, push notifications can be delivered to the user even if the user does not have the web site or even Safari open. As always, you need to be cautious about the delivery cadence so that the user doesn't feel spammed. The user can always go to the Safari Preferences and disable the notifications for a site. +Apple supports Safari Push Notifications which are widely popular and have been implemented on many notable sites like NYTimes.com. Once a user has consented to receive notifications, push notifications can be delivered to the user even if the user does not have the web site or even Safari open. As always, you need to be cautious about the delivery cadence so that the user doesn't feel spammed. The user can always go to the Safari Preferences and disable the notifications for a site. ![1] [Apple - Safari Push guidance] provides a detailed guidance on the implementation. Here is the general flow: -1. The WebServer serves the web site content to the user. -2. The client running in the Safari Web browser prompts the user to receive notifications. -3. When the user consents then the Safari client makes a request to a web service which delivers the requisite 'package' to the client. This package contains details about the site in an Apple specified secured package format. -4. Safari client then fetches a secure device token (APNS identifier) which identifies the client instance to receive notifications. -5. Safari client sends this token to the web service URL which must persistently store it. -6. A push agent uses this token to send a notification to the client instance using APNS. -7. If User disables the push notifications for this web site then a call is made to the web service so that it can delete the device token registration. +1. The WebServer serves the web site content to the user. +2. The client running in the Safari Web browser prompts the user to receive notifications. +3. When the user consents then the Safari client makes a request to a web service which delivers the requisite 'package' to the client. This package contains details about the site in an Apple specified secured package format. +4. Safari client then fetches a secure device token (APNS identifier) which identifies the client instance to receive notifications. +5. Safari client sends this token to the web service URL which must persistently store it. +6. A push agent uses this token to send a notification to the client instance using APNS. +7. If User disables the push notifications for this web site then a call is made to the web service so that it can delete the device token registration. -In the sample we are using **Azure Web Sites** to implement the webserver and the web service APIs and **Azure Notification Hubs** to register the client and send notifications. +In the sample we are using **Azure Web Sites** to implement the webserver and the web service APIs and **Azure Notification Hubs** to register the client and send notifications. ## Generate the certificate signing request Follow the steps in the *Generate the certificate signing request* section of the [Azure Notification Hubs - iOS tutorial] to generate a certificate signing request. Certificate Signing Request (CSR) file is used by Apple to generate a signed certificate. @@ -26,13 +26,13 @@ Follow the steps in the *Generate the certificate signing request* section of th ![8] -2. Registration requires an *iOS Apps developer license* or *Mac Apps developer license*. +2. Registration requires an *iOS Apps developer license* or *Mac Apps developer license*. 3. Click Certificates and click + sign to add a new certificate. ![11] -4. Select *Website Push ID Certificate* in the selection. +4. Select *Website Push ID Certificate* in the selection. ![14] @@ -47,25 +47,25 @@ Follow the steps in the *Generate the certificate signing request* section of th ![10] -7. Select the WebSite Push ID (you may have to navigate to this screen again to select. +7. Select the WebSite Push ID (you may have to navigate to this screen again to select. ![13] -8. Next, you will be asked to upload the *Certificate Signing Request (CSR)* file you generated in the previous step. Once you do this you will be able to download the certificate. +8. Next, you will be asked to upload the *Certificate Signing Request (CSR)* file you generated in the previous step. Once you do this you will be able to download the certificate. + +9. Double click the saved certificate (which is in .CER format) to install it in the login keychain. -9. Double click the saved certificate (which is in .CER format) to install it in the login keychain. - 10. In Keychain Access, right-click this new certificate -> click Export -> name the file -> select the .p12 format and click Save. ## Configure Azure Notification Hubs -Follow the steps in the *Configure your notification hub* section of the [Azure Notification Hubs - iOS tutorial] to provision and configure a Notification Hub with this certificate. Make note of the *DefaultFullSharedAccessSignature* which you will use to communicate with the notification hub. +Follow the steps in the *Configure your notification hub* section of the [Azure Notification Hubs - iOS tutorial] to provision and configure a Notification Hub with this certificate. Make note of the *DefaultFullSharedAccessSignature* which you will use to communicate with the notification hub. ## Setting up the web site & service -1. Login to the Azure Management Portal and create an Azure Web Site. E.g. for the tutorial I created 'http://piyushjosafaripush.azurewebsites.net'. +1. Login to the Azure Management Portal and create an Azure Web Site. E.g. for the tutorial I created 'http://piyushjosafaripush.azurewebsites.net'. -2. Follow the *Building the Push Package* section in the [Apple - Safari Push guidance]. +2. Follow the *Building the Push Package* section in the [Apple - Safari Push guidance]. 3. Here is a sample website.json which goes in the package: @@ -79,36 +79,36 @@ Follow the steps in the *Configure your notification hub* section of the [Azure } View *Table 2-1 Allowed keys in the website.json file* in [Apple - Safari Push guidance] for a description of these fields. - - - websitePushID must match what you provided earlier during Apple provisioning. - - I am using the Azure Web Sites provisioned site for all the URLs. Note that the webServiceURL must be using HTTPS. - - I am not using the authenticationToken later to identify any user so just putting a dummy value there. - - urlFormatString is the URL where the user will go when they click on the notification. '%@' is a placeholder whose values you pass when sending the notification. -4. Next you need to create a pushPacakge.zip. I used the 'createPushPackage.php' file from the [Apple - Safari Push guidance] to create this. You can create one and use it for all the requests as a static file if you are not using the authenticationToken to differentiate the user. Otherwise you will have to create one dynamically for all requests using 'createPushPackage.php'. + - websitePushID must match what you provided earlier during Apple provisioning. + - I am using the Azure Web Sites provisioned site for all the URLs. Note that the webServiceURL must be using HTTPS. + - I am not using the authenticationToken later to identify any user so just putting a dummy value there. + - urlFormatString is the URL where the user will go when they click on the notification. '%@' is a placeholder whose values you pass when sending the notification. + +4. Next you need to create a pushPacakge.zip. I used the 'createPushPackage.php' file from the [Apple - Safari Push guidance] to create this. You can create one and use it for all the requests as a static file if you are not using the authenticationToken to differentiate the user. Otherwise you will have to create one dynamically for all requests using 'createPushPackage.php'. - - If you want to run the PHP script, it will require you to install PHP and OpenSSL. - - While setting up the PHP environment, you will need to uncomment the 'openssl extension' & 'extension_dir' in PHP.ini. - - You may need both the .pem file and the .p12 certificate files to run the script to create the zip file. + - If you want to run the PHP script, it will require you to install PHP and OpenSSL. + - While setting up the PHP environment, you will need to uncomment the 'openssl extension' & 'extension_dir' in PHP.ini. + - You may need both the .pem file and the .p12 certificate files to run the script to create the zip file. -5. Open Visual Studio and create a Web API project. +5. Open Visual Studio and create a Web API project. -6. Create a Notifications folder in the solution and add the pushPackage.zip file in it and add it to the project. +6. Create a Notifications folder in the solution and add the pushPackage.zip file in it and add it to the project. -7. Add the 'WindowsAzure.ServiceBus.2.6.1' package which will allow you to communicate with the Notification Hubs. +7. Add the 'WindowsAzure.ServiceBus.2.6.1' package which will allow you to communicate with the Notification Hubs. -8. Create a 'ValuesController' with the following APIs which are called by the Safari client while generating the pushToken. +8. Create a 'ValuesController' with the following APIs which are called by the Safari client while generating the pushToken. public class ValuesController : ApiController { //https://developer.apple.com/library/mac/documentation/NetworkingInternet/Conceptual/NotificationProgrammingGuideForWebsites/PushNotifications/PushNotifications.html - + static string connString = ""; static string hubName = " ProcessRegistration(string deviceToken) { @@ -137,24 +137,24 @@ Follow the steps in the *Configure your notification hub* section of the [Azure Trace.TraceInformation("Created Registration with id '{0}'", registration.RegistrationId); return registration; } - + [HttpDelete] public async Task DeleteRegistration(string deviceToken) { Trace.TraceInformation("Deleting Registration"); await hub.DeleteRegistrationsByChannelAsync(deviceToken); return true; - } - + } + [HttpPost] public async void LogErrors() { // Write out the body (which contains errors in JSON) Trace.TraceError(await Request.Content.ReadAsStringAsync()); } - } + } -9. Open up the WebAPIConfig file and update it as the following to route all incoming requests to the correct APIs. This follows the pattern of the APIs called by the Safari client and we don't have to write any client side code to call these APIs. +9. Open up the WebAPIConfig file and update it as the following to route all incoming requests to the correct APIs. This follows the pattern of the APIs called by the Safari client and we don't have to write any client side code to call these APIs. public static void Register(HttpConfiguration config) { @@ -198,10 +198,10 @@ Follow the steps in the *Configure your notification hub* section of the [Azure ( name: "LogErrorsRule", routeTemplate: "v1/log", - defaults: new - { - controller = "Values", - action = "LogErrors" + defaults: new + { + controller = "Values", + action = "LogErrors" } ); } @@ -212,10 +212,10 @@ Follow the steps in the *Configure your notification hub* section of the [Azure -11. Add an *Updates.html* to the project at the root. This will be the page which will be called when the user clicks the notification. +11. Add an *Updates.html* to the project at the root. This will be the page which will be called when the user clicks the notification. 12. Open up the Layout.cshtml and update it to the following: - + @@ -239,7 +239,7 @@ Follow the steps in the *Configure your notification hub* section of the [Azure -13. Open up the Index.cshtml and update it to the following: +13. Open up the Index.cshtml and update it to the following:

Apple Safari Notifications

@@ -247,12 +247,12 @@ Follow the steps in the *Configure your notification hub* section of the [Azure + + + + + \ No newline at end of file diff --git a/apache-cordova/www/js/config.js b/apache-cordova/www/js/config.js new file mode 100644 index 0000000..259a6d3 --- /dev/null +++ b/apache-cordova/www/js/config.js @@ -0,0 +1,4 @@ +const config = { + hubName: '', + hubConnectionString: '', +} diff --git a/apache-cordova/www/js/index.js b/apache-cordova/www/js/index.js new file mode 100644 index 0000000..a4101ed --- /dev/null +++ b/apache-cordova/www/js/index.js @@ -0,0 +1,55 @@ +const warningMessage = "You must populate the project's config.js file with your account's Azure Notification Hubs settings before launching the app."; + +var app = { + + initialize: function () { + document.addEventListener('deviceready', this.onDeviceReady.bind(this), false); + }, + + onDeviceReady: function () { + + // validate that the config values aren't empty before attempting to register for push + if (config.hubName && config.hubConnectionString) { + + var push = PushNotification.init({ + notificationHubPath: config.hubName, + connectionString: config.hubConnectionString, + + android: { + sound: true + }, + ios: { + alert: 'true', + badge: true, + sound: 'false' + } + }); + + push.on('registration', function (data) { + console.log('Registration'); + console.log(`Registration ID: ${data.registrationId}`); + console.log(`Azure Reg ID: ${data.azureRegId}`); + // Update the contents of the page with the registration IDs + document.getElementById("regID").innerHTML = `Registration ID:
${data.registrationId}`; + document.getElementById("azureID").innerHTML = `Azure Registration ID:
${data.azureRegId}`; + // alert the user + alert(JSON.stringify(data)); + }); + + push.on('notification', function (data) { + console.log('Notification'); + console.dir(data); + alert(JSON.stringify(data)); + }); + + } else { + // the config file's not populated, so display a warning (and don't attempt to register) + document.getElementById("regID").innerHTML = `Warning: ${warningMessage}`; + alert(warningMessage); + } + + } + +}; + +app.initialize(); \ No newline at end of file diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedTests/GetStartedTests.csproj b/dotnet/GetStartedWindowsUniversal/GetStartedTests/GetStartedTests.csproj deleted file mode 100644 index baff39d..0000000 --- a/dotnet/GetStartedWindowsUniversal/GetStartedTests/GetStartedTests.csproj +++ /dev/null @@ -1,83 +0,0 @@ - - - - Debug - AnyCPU - 58b3027f-71b1-46f4-8cfd-625ed11767c1 - Library - Properties - GetStartedTests - GetStartedTests - v4.5 - 512 - {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages - False - UnitTest - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - - - - - False - - - False - - - False - - - False - - - - - - - - \ No newline at end of file diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedTests/Properties/AssemblyInfo.cs b/dotnet/GetStartedWindowsUniversal/GetStartedTests/Properties/AssemblyInfo.cs deleted file mode 100644 index a94bf31..0000000 --- a/dotnet/GetStartedWindowsUniversal/GetStartedTests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("GetStartedTests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("GetStartedTests")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("58b3027f-71b1-46f4-8cfd-625ed11767c1")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedTests/UnitTest1.cs b/dotnet/GetStartedWindowsUniversal/GetStartedTests/UnitTest1.cs deleted file mode 100644 index 5989288..0000000 --- a/dotnet/GetStartedWindowsUniversal/GetStartedTests/UnitTest1.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace GetStartedTests -{ - [TestClass] - public class UnitTest1 - { - [TestMethod] - public void TestMethod1() - { - } - } -} diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal.sln b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal.sln deleted file mode 100644 index 9fa393c..0000000 --- a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal.sln +++ /dev/null @@ -1,96 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.30723.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GetStartedWindowsUniversal", "GetStartedWindowsUniversal", "{E810AF7D-4BD4-4D97-B2E4-AB5EDD61286F}" -EndProject -Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "GetStartedWindowsUniversal.Shared", "GetStartedWindowsUniversal\GetStartedWindowsUniversal.Shared\GetStartedWindowsUniversal.Shared.shproj", "{29C2DF7F-9121-441E-A7D7-3BA57B2591E6}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GetStartedWindowsUniversal.Windows", "GetStartedWindowsUniversal\GetStartedWindowsUniversal.Windows\GetStartedWindowsUniversal.Windows.csproj", "{E4D9722E-7CC9-42FC-84F7-CBBA4089D732}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GetStartedWindowsUniversal.WindowsPhone", "GetStartedWindowsUniversal\GetStartedWindowsUniversal.WindowsPhone\GetStartedWindowsUniversal.WindowsPhone.csproj", "{BBA63DCB-2D73-4807-B32C-2115756AD699}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SendToNotificationHub", "SendToNotificationHub\SendToNotificationHub.csproj", "{1CF4F8DB-637C-4D07-B4DE-59B1E389BFA6}" -EndProject -Global - GlobalSection(SharedMSBuildProjectFiles) = preSolution - GetStartedWindowsUniversal\GetStartedWindowsUniversal.Shared\GetStartedWindowsUniversal.Shared.projitems*{29c2df7f-9121-441e-a7d7-3ba57b2591e6}*SharedItemsImports = 13 - GetStartedWindowsUniversal\GetStartedWindowsUniversal.Shared\GetStartedWindowsUniversal.Shared.projitems*{bba63dcb-2d73-4807-b32c-2115756ad699}*SharedItemsImports = 4 - GetStartedWindowsUniversal\GetStartedWindowsUniversal.Shared\GetStartedWindowsUniversal.Shared.projitems*{e4d9722e-7cc9-42fc-84f7-cbba4089d732}*SharedItemsImports = 4 - EndGlobalSection - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|ARM = Debug|ARM - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|ARM = Release|ARM - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732}.Debug|Any CPU.Deploy.0 = Debug|Any CPU - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732}.Debug|ARM.ActiveCfg = Debug|ARM - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732}.Debug|ARM.Build.0 = Debug|ARM - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732}.Debug|ARM.Deploy.0 = Debug|ARM - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732}.Debug|x64.ActiveCfg = Debug|x64 - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732}.Debug|x64.Build.0 = Debug|x64 - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732}.Debug|x64.Deploy.0 = Debug|x64 - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732}.Debug|x86.ActiveCfg = Debug|x86 - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732}.Debug|x86.Build.0 = Debug|x86 - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732}.Debug|x86.Deploy.0 = Debug|x86 - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732}.Release|Any CPU.Build.0 = Release|Any CPU - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732}.Release|Any CPU.Deploy.0 = Release|Any CPU - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732}.Release|ARM.ActiveCfg = Release|ARM - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732}.Release|ARM.Build.0 = Release|ARM - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732}.Release|ARM.Deploy.0 = Release|ARM - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732}.Release|x64.ActiveCfg = Release|x64 - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732}.Release|x64.Build.0 = Release|x64 - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732}.Release|x64.Deploy.0 = Release|x64 - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732}.Release|x86.ActiveCfg = Release|x86 - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732}.Release|x86.Build.0 = Release|x86 - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732}.Release|x86.Deploy.0 = Release|x86 - {BBA63DCB-2D73-4807-B32C-2115756AD699}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BBA63DCB-2D73-4807-B32C-2115756AD699}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BBA63DCB-2D73-4807-B32C-2115756AD699}.Debug|Any CPU.Deploy.0 = Debug|Any CPU - {BBA63DCB-2D73-4807-B32C-2115756AD699}.Debug|ARM.ActiveCfg = Debug|ARM - {BBA63DCB-2D73-4807-B32C-2115756AD699}.Debug|ARM.Build.0 = Debug|ARM - {BBA63DCB-2D73-4807-B32C-2115756AD699}.Debug|ARM.Deploy.0 = Debug|ARM - {BBA63DCB-2D73-4807-B32C-2115756AD699}.Debug|x64.ActiveCfg = Debug|Any CPU - {BBA63DCB-2D73-4807-B32C-2115756AD699}.Debug|x86.ActiveCfg = Debug|x86 - {BBA63DCB-2D73-4807-B32C-2115756AD699}.Debug|x86.Build.0 = Debug|x86 - {BBA63DCB-2D73-4807-B32C-2115756AD699}.Debug|x86.Deploy.0 = Debug|x86 - {BBA63DCB-2D73-4807-B32C-2115756AD699}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BBA63DCB-2D73-4807-B32C-2115756AD699}.Release|Any CPU.Build.0 = Release|Any CPU - {BBA63DCB-2D73-4807-B32C-2115756AD699}.Release|Any CPU.Deploy.0 = Release|Any CPU - {BBA63DCB-2D73-4807-B32C-2115756AD699}.Release|ARM.ActiveCfg = Release|ARM - {BBA63DCB-2D73-4807-B32C-2115756AD699}.Release|ARM.Build.0 = Release|ARM - {BBA63DCB-2D73-4807-B32C-2115756AD699}.Release|ARM.Deploy.0 = Release|ARM - {BBA63DCB-2D73-4807-B32C-2115756AD699}.Release|x64.ActiveCfg = Release|Any CPU - {BBA63DCB-2D73-4807-B32C-2115756AD699}.Release|x86.ActiveCfg = Release|x86 - {BBA63DCB-2D73-4807-B32C-2115756AD699}.Release|x86.Build.0 = Release|x86 - {BBA63DCB-2D73-4807-B32C-2115756AD699}.Release|x86.Deploy.0 = Release|x86 - {1CF4F8DB-637C-4D07-B4DE-59B1E389BFA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1CF4F8DB-637C-4D07-B4DE-59B1E389BFA6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1CF4F8DB-637C-4D07-B4DE-59B1E389BFA6}.Debug|ARM.ActiveCfg = Debug|Any CPU - {1CF4F8DB-637C-4D07-B4DE-59B1E389BFA6}.Debug|x64.ActiveCfg = Debug|Any CPU - {1CF4F8DB-637C-4D07-B4DE-59B1E389BFA6}.Debug|x86.ActiveCfg = Debug|Any CPU - {1CF4F8DB-637C-4D07-B4DE-59B1E389BFA6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1CF4F8DB-637C-4D07-B4DE-59B1E389BFA6}.Release|Any CPU.Build.0 = Release|Any CPU - {1CF4F8DB-637C-4D07-B4DE-59B1E389BFA6}.Release|ARM.ActiveCfg = Release|Any CPU - {1CF4F8DB-637C-4D07-B4DE-59B1E389BFA6}.Release|x64.ActiveCfg = Release|Any CPU - {1CF4F8DB-637C-4D07-B4DE-59B1E389BFA6}.Release|x86.ActiveCfg = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {29C2DF7F-9121-441E-A7D7-3BA57B2591E6} = {E810AF7D-4BD4-4D97-B2E4-AB5EDD61286F} - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732} = {E810AF7D-4BD4-4D97-B2E4-AB5EDD61286F} - {BBA63DCB-2D73-4807-B32C-2115756AD699} = {E810AF7D-4BD4-4D97-B2E4-AB5EDD61286F} - EndGlobalSection -EndGlobal diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Shared/App.xaml b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Shared/App.xaml deleted file mode 100644 index f789c98..0000000 --- a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Shared/App.xaml +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Shared/App.xaml.cs b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Shared/App.xaml.cs deleted file mode 100644 index ffecd6d..0000000 --- a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Shared/App.xaml.cs +++ /dev/null @@ -1,160 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices.WindowsRuntime; -using Windows.ApplicationModel; -using Windows.ApplicationModel.Activation; -using Windows.Foundation; -using Windows.Foundation.Collections; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Controls; -using Windows.UI.Xaml.Controls.Primitives; -using Windows.UI.Xaml.Data; -using Windows.UI.Xaml.Input; -using Windows.UI.Xaml.Media; -using Windows.UI.Xaml.Media.Animation; -using Windows.UI.Xaml.Navigation; - -using Windows.Networking.PushNotifications; -using Microsoft.WindowsAzure.Messaging; -using Windows.UI.Popups; - -// The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227 - -namespace GetStartedWindowsUniversal -{ - /// - /// Provides application-specific behavior to supplement the default Application class. - /// - public sealed partial class App : Application - { -#if WINDOWS_PHONE_APP - private TransitionCollection transitions; -#endif - - /// - /// Initializes the singleton application object. This is the first line of authored code - /// executed, and as such is the logical equivalent of main() or WinMain(). - /// - public App() - { - this.InitializeComponent(); - this.Suspending += this.OnSuspending; - } - - private async void InitNotificationsAsync() - { - var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync(); - - var hub = new NotificationHub("", ""); - var result = await hub.RegisterNativeAsync(channel.Uri); - - // Displays the registration ID so you know it was successful - if (result.RegistrationId != null) - { - var dialog = new MessageDialog("Registration successful: " + result.RegistrationId); - dialog.Commands.Add(new UICommand("OK")); - await dialog.ShowAsync(); - } - - } - - /// - /// Invoked when the application is launched normally by the end user. Other entry points - /// will be used when the application is launched to open a specific file, to display - /// search results, and so forth. - /// - /// Details about the launch request and process. - protected override void OnLaunched(LaunchActivatedEventArgs e) - { -#if DEBUG - if (System.Diagnostics.Debugger.IsAttached) - { - this.DebugSettings.EnableFrameRateCounter = true; - } -#endif - - InitNotificationsAsync(); - - Frame rootFrame = Window.Current.Content as Frame; - - // Do not repeat app initialization when the Window already has content, - // just ensure that the window is active - if (rootFrame == null) - { - // Create a Frame to act as the navigation context and navigate to the first page - rootFrame = new Frame(); - - // TODO: change this value to a cache size that is appropriate for your application - rootFrame.CacheSize = 1; - - if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) - { - // TODO: Load state from previously suspended application - } - - // Place the frame in the current Window - Window.Current.Content = rootFrame; - } - - if (rootFrame.Content == null) - { -#if WINDOWS_PHONE_APP - // Removes the turnstile navigation for startup. - if (rootFrame.ContentTransitions != null) - { - this.transitions = new TransitionCollection(); - foreach (var c in rootFrame.ContentTransitions) - { - this.transitions.Add(c); - } - } - - rootFrame.ContentTransitions = null; - rootFrame.Navigated += this.RootFrame_FirstNavigated; -#endif - - // When the navigation stack isn't restored navigate to the first page, - // configuring the new page by passing required information as a navigation - // parameter - if (!rootFrame.Navigate(typeof(MainPage), e.Arguments)) - { - throw new Exception("Failed to create initial page"); - } - } - - // Ensure the current window is active - Window.Current.Activate(); - } - -#if WINDOWS_PHONE_APP - /// - /// Restores the content transitions after the app has launched. - /// - /// The object where the handler is attached. - /// Details about the navigation event. - private void RootFrame_FirstNavigated(object sender, NavigationEventArgs e) - { - var rootFrame = sender as Frame; - rootFrame.ContentTransitions = this.transitions ?? new TransitionCollection() { new NavigationThemeTransition() }; - rootFrame.Navigated -= this.RootFrame_FirstNavigated; - } -#endif - - /// - /// Invoked when application execution is being suspended. Application state is saved - /// without knowing whether the application will be terminated or resumed with the contents - /// of memory still intact. - /// - /// The source of the suspend request. - /// Details about the suspend request. - private void OnSuspending(object sender, SuspendingEventArgs e) - { - var deferral = e.SuspendingOperation.GetDeferral(); - - // TODO: Save application state and stop any background activity - deferral.Complete(); - } - } -} \ No newline at end of file diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Shared/GetStartedWindowsUniversal.Shared.projitems b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Shared/GetStartedWindowsUniversal.Shared.projitems deleted file mode 100644 index b1e07aa..0000000 --- a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Shared/GetStartedWindowsUniversal.Shared.projitems +++ /dev/null @@ -1,19 +0,0 @@ - - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - true - 29c2df7f-9121-441e-a7d7-3ba57b2591e6 - - - GetStartedWindowsUniversal - - - - Designer - - - App.xaml - - - diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Shared/GetStartedWindowsUniversal.Shared.shproj b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Shared/GetStartedWindowsUniversal.Shared.shproj deleted file mode 100644 index 98418e3..0000000 --- a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Shared/GetStartedWindowsUniversal.Shared.shproj +++ /dev/null @@ -1,12 +0,0 @@ - - - - 29c2df7f-9121-441e-a7d7-3ba57b2591e6 - - - - - - - - diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/Assets/Logo.scale-100.png b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/Assets/Logo.scale-100.png deleted file mode 100644 index e26771c..0000000 Binary files a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/Assets/Logo.scale-100.png and /dev/null differ diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/Assets/SmallLogo.scale-100.png b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/Assets/SmallLogo.scale-100.png deleted file mode 100644 index 1eb0d9d..0000000 Binary files a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/Assets/SmallLogo.scale-100.png and /dev/null differ diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/Assets/SplashScreen.scale-100.png b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/Assets/SplashScreen.scale-100.png deleted file mode 100644 index c951e03..0000000 Binary files a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/Assets/SplashScreen.scale-100.png and /dev/null differ diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/Assets/StoreLogo.scale-100.png b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/Assets/StoreLogo.scale-100.png deleted file mode 100644 index dcb6727..0000000 Binary files a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/Assets/StoreLogo.scale-100.png and /dev/null differ diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/GetStartedWindowsUniversal.Windows.csproj b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/GetStartedWindowsUniversal.Windows.csproj deleted file mode 100644 index 92d5297..0000000 --- a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/GetStartedWindowsUniversal.Windows.csproj +++ /dev/null @@ -1,147 +0,0 @@ - - - - - Debug - AnyCPU - {E4D9722E-7CC9-42FC-84F7-CBBA4089D732} - AppContainerExe - Properties - GetStartedWindowsUniversal - GetStartedWindowsUniversal.Windows - en-US - 8.1 - 12 - 512 - true - {BC8A1FFA-BEE3-4634-8014-F334798102B3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - GetStartedWindowsUniversal.Windows_TemporaryKey.pfx - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE;NETFX_CORE;WINDOWS_APP - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE;NETFX_CORE;WINDOWS_APP - prompt - 4 - - - true - bin\ARM\Debug\ - DEBUG;TRACE;NETFX_CORE;WINDOWS_APP - ;2008 - full - ARM - false - prompt - true - - - bin\ARM\Release\ - TRACE;NETFX_CORE;WINDOWS_APP - true - ;2008 - pdbonly - ARM - false - prompt - true - - - true - bin\x64\Debug\ - DEBUG;TRACE;NETFX_CORE;WINDOWS_APP - ;2008 - full - x64 - false - prompt - true - - - bin\x64\Release\ - TRACE;NETFX_CORE;WINDOWS_APP - true - ;2008 - pdbonly - x64 - false - prompt - true - - - true - bin\x86\Debug\ - DEBUG;TRACE;NETFX_CORE;WINDOWS_APP - ;2008 - full - x86 - false - prompt - true - - - bin\x86\Release\ - TRACE;NETFX_CORE;WINDOWS_APP - true - ;2008 - pdbonly - x86 - false - prompt - true - - - - MainPage.xaml - - - - - - Designer - - - - - - - - - - - - - MSBuild:Compile - Designer - - - - - ..\..\packages\WindowsAzure.Messaging.Managed.0.1.7.9\lib\netcore45\Microsoft.WindowsAzure.Messaging.Managed.dll - - - - 12.0 - - - - - \ No newline at end of file diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/MainPage.xaml b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/MainPage.xaml deleted file mode 100644 index b0b25a4..0000000 --- a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/MainPage.xaml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/MainPage.xaml.cs b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/MainPage.xaml.cs deleted file mode 100644 index 9c26d04..0000000 --- a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/MainPage.xaml.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices.WindowsRuntime; -using Windows.Foundation; -using Windows.Foundation.Collections; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Controls; -using Windows.UI.Xaml.Controls.Primitives; -using Windows.UI.Xaml.Data; -using Windows.UI.Xaml.Input; -using Windows.UI.Xaml.Media; -using Windows.UI.Xaml.Navigation; - -// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 - -namespace GetStartedWindowsUniversal -{ - /// - /// An empty page that can be used on its own or navigated to within a Frame. - /// - public sealed partial class MainPage : Page - { - public MainPage() - { - this.InitializeComponent(); - } - } -} diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/Package.appxmanifest b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/Package.appxmanifest deleted file mode 100644 index 7426b71..0000000 --- a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/Package.appxmanifest +++ /dev/null @@ -1,26 +0,0 @@ - - - - - GetStartedWindowsUniversal.Windows - Wesley - Assets\StoreLogo.png - - - 6.3.0 - 6.3.0 - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/Properties/AssemblyInfo.cs b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/Properties/AssemblyInfo.cs deleted file mode 100644 index 4356684..0000000 --- a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("GetStartedWindowsUniversal.Windows")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("GetStartedWindowsUniversal.Windows")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] -[assembly: ComVisible(false)] \ No newline at end of file diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/packages.config b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/packages.config deleted file mode 100644 index 5e53a41..0000000 --- a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.Windows/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/Assets/Logo.scale-240.png b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/Assets/Logo.scale-240.png deleted file mode 100644 index 76921ca..0000000 Binary files a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/Assets/Logo.scale-240.png and /dev/null differ diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/Assets/SmallLogo.scale-240.png b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/Assets/SmallLogo.scale-240.png deleted file mode 100644 index 3166301..0000000 Binary files a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/Assets/SmallLogo.scale-240.png and /dev/null differ diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/Assets/SplashScreen.scale-240.png b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/Assets/SplashScreen.scale-240.png deleted file mode 100644 index 33f26b3..0000000 Binary files a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/Assets/SplashScreen.scale-240.png and /dev/null differ diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/Assets/Square71x71Logo.scale-240.png b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/Assets/Square71x71Logo.scale-240.png deleted file mode 100644 index cfa54be..0000000 Binary files a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/Assets/Square71x71Logo.scale-240.png and /dev/null differ diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/Assets/StoreLogo.scale-240.png b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/Assets/StoreLogo.scale-240.png deleted file mode 100644 index 47e084b..0000000 Binary files a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/Assets/StoreLogo.scale-240.png and /dev/null differ diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/Assets/WideLogo.scale-240.png b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/Assets/WideLogo.scale-240.png deleted file mode 100644 index 6249d29..0000000 Binary files a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/Assets/WideLogo.scale-240.png and /dev/null differ diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/GetStartedWindowsUniversal.WindowsPhone.csproj b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/GetStartedWindowsUniversal.WindowsPhone.csproj deleted file mode 100644 index ac2180e..0000000 --- a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/GetStartedWindowsUniversal.WindowsPhone.csproj +++ /dev/null @@ -1,130 +0,0 @@ - - - - - Debug - AnyCPU - {BBA63DCB-2D73-4807-B32C-2115756AD699} - AppContainerExe - Properties - GetStartedWindowsUniversal - GetStartedWindowsUniversal.WindowsPhone - en-US - 8.1 - 12 - 512 - {76F1466A-8B6D-4E39-A767-685A06062A39};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE;NETFX_CORE;WINDOWS_PHONE_APP - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE;NETFX_CORE;WINDOWS_PHONE_APP - prompt - 4 - - - true - bin\ARM\Debug\ - DEBUG;TRACE;NETFX_CORE;WINDOWS_PHONE_APP - ;2008 - full - ARM - false - prompt - true - - - bin\ARM\Release\ - TRACE;NETFX_CORE;WINDOWS_PHONE_APP - true - ;2008 - pdbonly - ARM - false - prompt - true - - - true - bin\x86\Debug\ - DEBUG;TRACE;NETFX_CORE;WINDOWS_PHONE_APP - ;2008 - full - x86 - false - prompt - true - - - bin\x86\Release\ - TRACE;NETFX_CORE;WINDOWS_PHONE_APP - true - ;2008 - pdbonly - x86 - false - prompt - true - - - - MainPage.xaml - - - - - - Designer - - - - - - - - - - - - - MSBuild:Compile - Designer - - - - - ..\..\packages\WindowsAzure.Messaging.Managed.0.1.7.9\lib\wpa81\Microsoft.WindowsAzure.Messaging.Managed.dll - - - - - - - 12.0 - - - WindowsPhoneApp - - - - - \ No newline at end of file diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/MainPage.xaml b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/MainPage.xaml deleted file mode 100644 index f5efdce..0000000 --- a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/MainPage.xaml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/MainPage.xaml.cs b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/MainPage.xaml.cs deleted file mode 100644 index ba429ff..0000000 --- a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/MainPage.xaml.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices.WindowsRuntime; -using Windows.Foundation; -using Windows.Foundation.Collections; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Controls; -using Windows.UI.Xaml.Controls.Primitives; -using Windows.UI.Xaml.Data; -using Windows.UI.Xaml.Input; -using Windows.UI.Xaml.Media; -using Windows.UI.Xaml.Navigation; - -// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 - -namespace GetStartedWindowsUniversal -{ - /// - /// An empty page that can be used on its own or navigated to within a Frame. - /// - public sealed partial class MainPage : Page - { - public MainPage() - { - this.InitializeComponent(); - - this.NavigationCacheMode = NavigationCacheMode.Required; - } - - /// - /// Invoked when this page is about to be displayed in a Frame. - /// - /// Event data that describes how this page was reached. - /// This parameter is typically used to configure the page. - protected override void OnNavigatedTo(NavigationEventArgs e) - { - // TODO: Prepare page for display here. - - // TODO: If your application contains multiple pages, ensure that you are - // handling the hardware Back button by registering for the - // Windows.Phone.UI.Input.HardwareButtons.BackPressed event. - // If you are using the NavigationHelper provided by some templates, - // this event is handled for you. - } - } -} diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/Package.appxmanifest b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/Package.appxmanifest deleted file mode 100644 index aa5d61d..0000000 --- a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/Package.appxmanifest +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - GetStartedWindowsUniversal.WindowsPhone - Wesley - Assets\StoreLogo.png - - - 6.3.1 - 6.3.1 - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/Properties/AssemblyInfo.cs b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/Properties/AssemblyInfo.cs deleted file mode 100644 index 654af31..0000000 --- a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("GetStartedWindowsUniversal.WindowsPhone")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("GetStartedWindowsUniversal.WindowsPhone")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] -[assembly: ComVisible(false)] \ No newline at end of file diff --git a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/packages.config b/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/packages.config deleted file mode 100644 index 93c6979..0000000 --- a/dotnet/GetStartedWindowsUniversal/GetStartedWindowsUniversal/GetStartedWindowsUniversal.WindowsPhone/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/dotnet/GetStartedWindowsUniversal/README.md b/dotnet/GetStartedWindowsUniversal/README.md deleted file mode 100644 index 1bdf49c..0000000 --- a/dotnet/GetStartedWindowsUniversal/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Get Started with Notification Hubs Windows Universal - -This Visual Studio 2013 project is a copy of the completed code for the [Getting started with Notification Hubs for Windows Store Apps](https://azure.microsoft.com/documentation/articles/notification-hubs-windows-store-dotnet-get-started/) tutorial. - -* To test sending notification with the Windows 10 Action Center use the "ToastGeneric" template instead of "ToastText01". This code will be updated soon for Windows 10. - - // Windows 10 - var toast = @"" + - "Hello from a .NET App!" + - ""; \ No newline at end of file diff --git a/dotnet/GetStartedWindowsUniversal/SendToNotificationHub/App.config b/dotnet/GetStartedWindowsUniversal/SendToNotificationHub/App.config deleted file mode 100644 index 8484610..0000000 --- a/dotnet/GetStartedWindowsUniversal/SendToNotificationHub/App.config +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/dotnet/GetStartedWindowsUniversal/SendToNotificationHub/Program.cs b/dotnet/GetStartedWindowsUniversal/SendToNotificationHub/Program.cs deleted file mode 100644 index 8b5e061..0000000 --- a/dotnet/GetStartedWindowsUniversal/SendToNotificationHub/Program.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Microsoft.ServiceBus.Notifications; - -namespace SendToNotificationHub -{ - class Program - { - static void Main(string[] args) - { - SendNotificationAsync(); - Console.ReadLine(); - } - - private static async void SendNotificationAsync() - { - NotificationHubClient hub = NotificationHubClient - .CreateClientFromConnectionString("", ""); - var toast = @"Hello from a .NET App!"; - await hub.SendWindowsNativeNotificationAsync(toast); - } - } -} diff --git a/dotnet/GetStartedWindowsUniversal/SendToNotificationHub/Properties/AssemblyInfo.cs b/dotnet/GetStartedWindowsUniversal/SendToNotificationHub/Properties/AssemblyInfo.cs deleted file mode 100644 index 1fa8e1e..0000000 --- a/dotnet/GetStartedWindowsUniversal/SendToNotificationHub/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("SendToNotificationHub")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("SendToNotificationHub")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("f0f9b11c-0f4d-482f-87e4-ae8804708204")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/dotnet/GetStartedWindowsUniversal/SendToNotificationHub/SendToNotificationHub.csproj b/dotnet/GetStartedWindowsUniversal/SendToNotificationHub/SendToNotificationHub.csproj deleted file mode 100644 index 955cc21..0000000 --- a/dotnet/GetStartedWindowsUniversal/SendToNotificationHub/SendToNotificationHub.csproj +++ /dev/null @@ -1,67 +0,0 @@ - - - - - Debug - AnyCPU - {1CF4F8DB-637C-4D07-B4DE-59B1E389BFA6} - Exe - Properties - SendToNotificationHub - SendToNotificationHub - v4.5 - 512 - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\WindowsAzure.ServiceBus.2.6.5\lib\net40-full\Microsoft.ServiceBus.dll - - - ..\packages\Microsoft.WindowsAzure.ConfigurationManager.3.1.0\lib\net40\Microsoft.WindowsAzure.Configuration.dll - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/dotnet/GetStartedWindowsUniversal/SendToNotificationHub/packages.config b/dotnet/GetStartedWindowsUniversal/SendToNotificationHub/packages.config deleted file mode 100644 index 41d20de..0000000 --- a/dotnet/GetStartedWindowsUniversal/SendToNotificationHub/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/AppBackend.csproj b/dotnet/NotifyUsers/AppBackend/AppBackend.csproj deleted file mode 100644 index 2416657..0000000 --- a/dotnet/NotifyUsers/AppBackend/AppBackend.csproj +++ /dev/null @@ -1,328 +0,0 @@ - - - - - Debug - AnyCPU - - - 2.0 - {51D91A1F-E926-407F-BB10-10508081F0B6} - {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} - Library - Properties - AppBackend - AppBackend - v4.5 - false - true - - - - - - - true - full - false - bin\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\ - TRACE - prompt - 4 - - - - ..\packages\Microsoft.Azure.NotificationHubs.1.0.3\lib\net45-full\Microsoft.Azure.NotificationHubs.dll - True - - - - ..\packages\Microsoft.WindowsAzure.ConfigurationManager.3.1.0\lib\net40\Microsoft.WindowsAzure.Configuration.dll - True - - - - - - - - - - - - - - - - - - - - True - ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll - - - ..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll - - - - - ..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll - - - - - True - ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll - - - ..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll - - - ..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll - - - True - ..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll - - - ..\packages\Microsoft.AspNet.Web.Optimization.1.1.3\lib\net40\System.Web.Optimization.dll - - - True - ..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll - - - True - ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll - - - True - ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll - - - True - ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll - - - True - ..\packages\WebGrease.1.5.2\lib\WebGrease.dll - - - True - ..\packages\Antlr.3.4.1.9004\lib\Antlr3.Runtime.dll - - - - - ..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.dll - - - ..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.SqlServer.dll - - - ..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll - - - ..\packages\Microsoft.AspNet.Identity.Owin.2.2.1\lib\net45\Microsoft.AspNet.Identity.Owin.dll - - - ..\packages\Microsoft.AspNet.Identity.EntityFramework.2.2.1\lib\net45\Microsoft.AspNet.Identity.EntityFramework.dll - - - ..\packages\Owin.1.0\lib\net40\Owin.dll - - - ..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll - - - ..\packages\Microsoft.Owin.Host.SystemWeb.3.0.1\lib\net45\Microsoft.Owin.Host.SystemWeb.dll - - - ..\packages\Microsoft.Owin.Security.3.0.1\lib\net45\Microsoft.Owin.Security.dll - - - ..\packages\Microsoft.Owin.Security.Facebook.3.0.1\lib\net45\Microsoft.Owin.Security.Facebook.dll - - - ..\packages\Microsoft.Owin.Security.Cookies.3.0.1\lib\net45\Microsoft.Owin.Security.Cookies.dll - - - ..\packages\Microsoft.Owin.Security.OAuth.3.0.1\lib\net45\Microsoft.Owin.Security.OAuth.dll - - - ..\packages\Microsoft.Owin.Security.Google.3.0.1\lib\net45\Microsoft.Owin.Security.Google.dll - - - ..\packages\Microsoft.Owin.Security.Twitter.3.0.1\lib\net45\Microsoft.Owin.Security.Twitter.dll - - - ..\packages\Microsoft.Owin.Security.MicrosoftAccount.3.0.1\lib\net45\Microsoft.Owin.Security.MicrosoftAccount.dll - - - ..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Global.asax - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Web.config - - - Web.config - - - - - - - - - - - - - - - - - - - - - - - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - - - - - - - - True - True - 8741 - / - http://localhost:8741/ - False - False - - - False - - - - - - \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/App_Start/BundleConfig.cs b/dotnet/NotifyUsers/AppBackend/App_Start/BundleConfig.cs deleted file mode 100644 index cfbcdfd..0000000 --- a/dotnet/NotifyUsers/AppBackend/App_Start/BundleConfig.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Web; -using System.Web.Optimization; - -namespace AppBackend -{ - public class BundleConfig - { - // For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862 - public static void RegisterBundles(BundleCollection bundles) - { - bundles.Add(new ScriptBundle("~/bundles/jquery").Include( - "~/Scripts/jquery-{version}.js")); - - // Use the development version of Modernizr to develop with and learn from. Then, when you're - // ready for production, use the build tool at http://modernizr.com to pick only the tests you need. - bundles.Add(new ScriptBundle("~/bundles/modernizr").Include( - "~/Scripts/modernizr-*")); - - bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include( - "~/Scripts/bootstrap.js", - "~/Scripts/respond.js")); - - bundles.Add(new StyleBundle("~/Content/css").Include( - "~/Content/bootstrap.css", - "~/Content/site.css")); - } - } -} diff --git a/dotnet/NotifyUsers/AppBackend/App_Start/FilterConfig.cs b/dotnet/NotifyUsers/AppBackend/App_Start/FilterConfig.cs deleted file mode 100644 index 85f1b28..0000000 --- a/dotnet/NotifyUsers/AppBackend/App_Start/FilterConfig.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Web; -using System.Web.Mvc; - -namespace AppBackend -{ - public class FilterConfig - { - public static void RegisterGlobalFilters(GlobalFilterCollection filters) - { - filters.Add(new HandleErrorAttribute()); - } - } -} diff --git a/dotnet/NotifyUsers/AppBackend/App_Start/IdentityConfig.cs b/dotnet/NotifyUsers/AppBackend/App_Start/IdentityConfig.cs deleted file mode 100644 index 7368422..0000000 --- a/dotnet/NotifyUsers/AppBackend/App_Start/IdentityConfig.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.AspNet.Identity; -using Microsoft.AspNet.Identity.EntityFramework; -using Microsoft.AspNet.Identity.Owin; -using Microsoft.Owin; -using AppBackend.Models; - -namespace AppBackend -{ - // Configure the application user manager used in this application. UserManager is defined in ASP.NET Identity and is used by the application. - - public class ApplicationUserManager : UserManager - { - public ApplicationUserManager(IUserStore store) - : base(store) - { - } - - public static ApplicationUserManager Create(IdentityFactoryOptions options, IOwinContext context) - { - var manager = new ApplicationUserManager(new UserStore(context.Get())); - // Configure validation logic for usernames - manager.UserValidator = new UserValidator(manager) - { - AllowOnlyAlphanumericUserNames = false, - RequireUniqueEmail = true - }; - // Configure validation logic for passwords - manager.PasswordValidator = new PasswordValidator - { - RequiredLength = 6, - RequireNonLetterOrDigit = true, - RequireDigit = true, - RequireLowercase = true, - RequireUppercase = true, - }; - var dataProtectionProvider = options.DataProtectionProvider; - if (dataProtectionProvider != null) - { - manager.UserTokenProvider = new DataProtectorTokenProvider(dataProtectionProvider.Create("ASP.NET Identity")); - } - return manager; - } - } -} diff --git a/dotnet/NotifyUsers/AppBackend/App_Start/RouteConfig.cs b/dotnet/NotifyUsers/AppBackend/App_Start/RouteConfig.cs deleted file mode 100644 index e84bb24..0000000 --- a/dotnet/NotifyUsers/AppBackend/App_Start/RouteConfig.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; -using System.Web.Mvc; -using System.Web.Routing; - -namespace AppBackend -{ - public class RouteConfig - { - public static void RegisterRoutes(RouteCollection routes) - { - routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); - - routes.MapRoute( - name: "Default", - url: "{controller}/{action}/{id}", - defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } - ); - } - } -} diff --git a/dotnet/NotifyUsers/AppBackend/App_Start/Startup.Auth.cs b/dotnet/NotifyUsers/AppBackend/App_Start/Startup.Auth.cs deleted file mode 100644 index e2e67db..0000000 --- a/dotnet/NotifyUsers/AppBackend/App_Start/Startup.Auth.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Microsoft.AspNet.Identity; -using Microsoft.AspNet.Identity.EntityFramework; -using Microsoft.Owin; -using Microsoft.Owin.Security.Cookies; -using Microsoft.Owin.Security.Google; -using Microsoft.Owin.Security.OAuth; -using Owin; -using AppBackend.Providers; -using AppBackend.Models; - -namespace AppBackend -{ - public partial class Startup - { - public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; } - - public static string PublicClientId { get; private set; } - - // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864 - public void ConfigureAuth(IAppBuilder app) - { - // Configure the db context and user manager to use a single instance per request - app.CreatePerOwinContext(ApplicationDbContext.Create); - app.CreatePerOwinContext(ApplicationUserManager.Create); - - // Enable the application to use a cookie to store information for the signed in user - // and to use a cookie to temporarily store information about a user logging in with a third party login provider - app.UseCookieAuthentication(new CookieAuthenticationOptions()); - app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); - - // Configure the application for OAuth based flow - PublicClientId = "self"; - OAuthOptions = new OAuthAuthorizationServerOptions - { - TokenEndpointPath = new PathString("/Token"), - Provider = new ApplicationOAuthProvider(PublicClientId), - AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"), - AccessTokenExpireTimeSpan = TimeSpan.FromDays(14), - // In production mode set AllowInsecureHttp = false - AllowInsecureHttp = true - }; - - // Enable the application to use bearer tokens to authenticate users - app.UseOAuthBearerTokens(OAuthOptions); - - // Uncomment the following lines to enable logging in with third party login providers - //app.UseMicrosoftAccountAuthentication( - // clientId: "", - // clientSecret: ""); - - //app.UseTwitterAuthentication( - // consumerKey: "", - // consumerSecret: ""); - - //app.UseFacebookAuthentication( - // appId: "", - // appSecret: ""); - - //app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions() - //{ - // ClientId = "", - // ClientSecret = "" - //}); - } - } -} diff --git a/dotnet/NotifyUsers/AppBackend/App_Start/WebApiConfig.cs b/dotnet/NotifyUsers/AppBackend/App_Start/WebApiConfig.cs deleted file mode 100644 index d515ac5..0000000 --- a/dotnet/NotifyUsers/AppBackend/App_Start/WebApiConfig.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Http; -using System.Web.Http; -using Microsoft.Owin.Security.OAuth; -using Newtonsoft.Json.Serialization; - -namespace AppBackend -{ - public static class WebApiConfig - { - public static void Register(HttpConfiguration config) - { - // Web API configuration and services - // Configure Web API to use only bearer token authentication. - config.SuppressDefaultHostAuthentication(); - config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); - - // Web API routes - config.MapHttpAttributeRoutes(); - - config.Routes.MapHttpRoute( - name: "DefaultApi", - routeTemplate: "api/{controller}/{id}", - defaults: new { id = RouteParameter.Optional } - ); - - config.MessageHandlers.Add(new AuthenticationTestHandler()); - } - } -} diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ApiDescriptionExtensions.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ApiDescriptionExtensions.cs deleted file mode 100644 index d3eae3e..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ApiDescriptionExtensions.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Text; -using System.Web; -using System.Web.Http.Description; - -namespace AppBackend.Areas.HelpPage -{ - public static class ApiDescriptionExtensions - { - /// - /// Generates an URI-friendly ID for the . E.g. "Get-Values-id_name" instead of "GetValues/{id}?name={name}" - /// - /// The . - /// The ID as a string. - public static string GetFriendlyId(this ApiDescription description) - { - string path = description.RelativePath; - string[] urlParts = path.Split('?'); - string localPath = urlParts[0]; - string queryKeyString = null; - if (urlParts.Length > 1) - { - string query = urlParts[1]; - string[] queryKeys = HttpUtility.ParseQueryString(query).AllKeys; - queryKeyString = String.Join("_", queryKeys); - } - - StringBuilder friendlyPath = new StringBuilder(); - friendlyPath.AppendFormat("{0}-{1}", - description.HttpMethod.Method, - localPath.Replace("/", "-").Replace("{", String.Empty).Replace("}", String.Empty)); - if (queryKeyString != null) - { - friendlyPath.AppendFormat("_{0}", queryKeyString.Replace('.', '-')); - } - return friendlyPath.ToString(); - } - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/App_Start/HelpPageConfig.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/App_Start/HelpPageConfig.cs deleted file mode 100644 index 72c0217..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/App_Start/HelpPageConfig.cs +++ /dev/null @@ -1,113 +0,0 @@ -// Uncomment the following to provide samples for PageResult. Must also add the Microsoft.AspNet.WebApi.OData -// package to your project. -////#define Handle_PageResultOfT - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Net.Http.Headers; -using System.Reflection; -using System.Web; -using System.Web.Http; -#if Handle_PageResultOfT -using System.Web.Http.OData; -#endif - -namespace AppBackend.Areas.HelpPage -{ - /// - /// Use this class to customize the Help Page. - /// For example you can set a custom to supply the documentation - /// or you can provide the samples for the requests/responses. - /// - public static class HelpPageConfig - { - [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", - MessageId = "AppBackend.Areas.HelpPage.TextSample.#ctor(System.String)", - Justification = "End users may choose to merge this string with existing localized resources.")] - [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", - MessageId = "bsonspec", - Justification = "Part of a URI.")] - public static void Register(HttpConfiguration config) - { - //// Uncomment the following to use the documentation from XML documentation file. - //config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/XmlDocument.xml"))); - - //// Uncomment the following to use "sample string" as the sample for all actions that have string as the body parameter or return type. - //// Also, the string arrays will be used for IEnumerable. The sample objects will be serialized into different media type - //// formats by the available formatters. - //config.SetSampleObjects(new Dictionary - //{ - // {typeof(string), "sample string"}, - // {typeof(IEnumerable), new string[]{"sample 1", "sample 2"}} - //}); - - // Extend the following to provide factories for types not handled automatically (those lacking parameterless - // constructors) or for which you prefer to use non-default property values. Line below provides a fallback - // since automatic handling will fail and GeneratePageResult handles only a single type. -#if Handle_PageResultOfT - config.GetHelpPageSampleGenerator().SampleObjectFactories.Add(GeneratePageResult); -#endif - - // Extend the following to use a preset object directly as the sample for all actions that support a media - // type, regardless of the body parameter or return type. The lines below avoid display of binary content. - // The BsonMediaTypeFormatter (if available) is not used to serialize the TextSample object. - config.SetSampleForMediaType( - new TextSample("Binary JSON content. See http://bsonspec.org for details."), - new MediaTypeHeaderValue("application/bson")); - - //// Uncomment the following to use "[0]=foo&[1]=bar" directly as the sample for all actions that support form URL encoded format - //// and have IEnumerable as the body parameter or return type. - //config.SetSampleForType("[0]=foo&[1]=bar", new MediaTypeHeaderValue("application/x-www-form-urlencoded"), typeof(IEnumerable)); - - //// Uncomment the following to use "1234" directly as the request sample for media type "text/plain" on the controller named "Values" - //// and action named "Put". - //config.SetSampleRequest("1234", new MediaTypeHeaderValue("text/plain"), "Values", "Put"); - - //// Uncomment the following to use the image on "../images/aspNetHome.png" directly as the response sample for media type "image/png" - //// on the controller named "Values" and action named "Get" with parameter "id". - //config.SetSampleResponse(new ImageSample("../images/aspNetHome.png"), new MediaTypeHeaderValue("image/png"), "Values", "Get", "id"); - - //// Uncomment the following to correct the sample request when the action expects an HttpRequestMessage with ObjectContent. - //// The sample will be generated as if the controller named "Values" and action named "Get" were having string as the body parameter. - //config.SetActualRequestType(typeof(string), "Values", "Get"); - - //// Uncomment the following to correct the sample response when the action returns an HttpResponseMessage with ObjectContent. - //// The sample will be generated as if the controller named "Values" and action named "Post" were returning a string. - //config.SetActualResponseType(typeof(string), "Values", "Post"); - } - -#if Handle_PageResultOfT - private static object GeneratePageResult(HelpPageSampleGenerator sampleGenerator, Type type) - { - if (type.IsGenericType) - { - Type openGenericType = type.GetGenericTypeDefinition(); - if (openGenericType == typeof(PageResult<>)) - { - // Get the T in PageResult - Type[] typeParameters = type.GetGenericArguments(); - Debug.Assert(typeParameters.Length == 1); - - // Create an enumeration to pass as the first parameter to the PageResult constuctor - Type itemsType = typeof(List<>).MakeGenericType(typeParameters); - object items = sampleGenerator.GetSampleObject(itemsType); - - // Fill in the other information needed to invoke the PageResult constuctor - Type[] parameterTypes = new Type[] { itemsType, typeof(Uri), typeof(long?), }; - object[] parameters = new object[] { items, null, (long)ObjectGenerator.DefaultCollectionSize, }; - - // Call PageResult(IEnumerable items, Uri nextPageLink, long? count) constructor - ConstructorInfo constructor = type.GetConstructor(parameterTypes); - return constructor.Invoke(parameters); - } - } - - return null; - } -#endif - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Controllers/HelpController.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Controllers/HelpController.cs deleted file mode 100644 index 3664857..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Controllers/HelpController.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using System.Web.Http; -using System.Web.Mvc; -using AppBackend.Areas.HelpPage.ModelDescriptions; -using AppBackend.Areas.HelpPage.Models; - -namespace AppBackend.Areas.HelpPage.Controllers -{ - /// - /// The controller that will handle requests for the help page. - /// - public class HelpController : Controller - { - private const string ErrorViewName = "Error"; - - public HelpController() - : this(GlobalConfiguration.Configuration) - { - } - - public HelpController(HttpConfiguration config) - { - Configuration = config; - } - - public HttpConfiguration Configuration { get; private set; } - - public ActionResult Index() - { - ViewBag.DocumentationProvider = Configuration.Services.GetDocumentationProvider(); - return View(Configuration.Services.GetApiExplorer().ApiDescriptions); - } - - public ActionResult Api(string apiId) - { - if (!String.IsNullOrEmpty(apiId)) - { - HelpPageApiModel apiModel = Configuration.GetHelpPageApiModel(apiId); - if (apiModel != null) - { - return View(apiModel); - } - } - - return View(ErrorViewName); - } - - public ActionResult ResourceModel(string modelName) - { - if (!String.IsNullOrEmpty(modelName)) - { - ModelDescriptionGenerator modelDescriptionGenerator = Configuration.GetModelDescriptionGenerator(); - ModelDescription modelDescription; - if (modelDescriptionGenerator.GeneratedModels.TryGetValue(modelName, out modelDescription)) - { - return View(modelDescription); - } - } - - return View(ErrorViewName); - } - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/HelpPage.css b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/HelpPage.css deleted file mode 100644 index aff2230..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/HelpPage.css +++ /dev/null @@ -1,134 +0,0 @@ -.help-page h1, -.help-page .h1, -.help-page h2, -.help-page .h2, -.help-page h3, -.help-page .h3, -#body.help-page, -.help-page-table th, -.help-page-table pre, -.help-page-table p { - font-family: "Segoe UI Light", Frutiger, "Frutiger Linotype", "Dejavu Sans", "Helvetica Neue", Arial, sans-serif; -} - -.help-page pre.wrapped { - white-space: -moz-pre-wrap; - white-space: -pre-wrap; - white-space: -o-pre-wrap; - white-space: pre-wrap; -} - -.help-page .warning-message-container { - margin-top: 20px; - padding: 0 10px; - color: #525252; - background: #EFDCA9; - border: 1px solid #CCCCCC; -} - -.help-page-table { - width: 100%; - border-collapse: collapse; - text-align: left; - margin: 0px 0px 20px 0px; - border-top: 1px solid #D4D4D4; -} - -.help-page-table th { - text-align: left; - font-weight: bold; - border-bottom: 1px solid #D4D4D4; - padding: 5px 6px 5px 6px; -} - -.help-page-table td { - border-bottom: 1px solid #D4D4D4; - padding: 10px 8px 10px 8px; - vertical-align: top; -} - -.help-page-table pre, -.help-page-table p { - margin: 0px; - padding: 0px; - font-family: inherit; - font-size: 100%; -} - -.help-page-table tbody tr:hover td { - background-color: #F3F3F3; -} - -.help-page a:hover { - background-color: transparent; -} - -.help-page .sample-header { - border: 2px solid #D4D4D4; - background: #00497E; - color: #FFFFFF; - padding: 8px 15px; - border-bottom: none; - display: inline-block; - margin: 10px 0px 0px 0px; -} - -.help-page .sample-content { - display: block; - border-width: 0; - padding: 15px 20px; - background: #FFFFFF; - border: 2px solid #D4D4D4; - margin: 0px 0px 10px 0px; -} - -.help-page .api-name { - width: 40%; -} - -.help-page .api-documentation { - width: 60%; -} - -.help-page .parameter-name { - width: 20%; -} - -.help-page .parameter-documentation { - width: 40%; -} - -.help-page .parameter-type { - width: 20%; -} - -.help-page .parameter-annotations { - width: 20%; -} - -.help-page h1, -.help-page .h1 { - font-size: 36px; - line-height: normal; -} - -.help-page h2, -.help-page .h2 { - font-size: 24px; -} - -.help-page h3, -.help-page .h3 { - font-size: 20px; -} - -#body.help-page { - font-size: 14px; - line-height: 143%; - color: #333; -} - -.help-page a { - color: #0000EE; - text-decoration: none; -} diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/HelpPageAreaRegistration.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/HelpPageAreaRegistration.cs deleted file mode 100644 index 73ef426..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/HelpPageAreaRegistration.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Web.Http; -using System.Web.Mvc; - -namespace AppBackend.Areas.HelpPage -{ - public class HelpPageAreaRegistration : AreaRegistration - { - public override string AreaName - { - get - { - return "HelpPage"; - } - } - - public override void RegisterArea(AreaRegistrationContext context) - { - context.MapRoute( - "HelpPage_Default", - "Help/{action}/{apiId}", - new { controller = "Help", action = "Index", apiId = UrlParameter.Optional }); - - HelpPageConfig.Register(GlobalConfiguration.Configuration); - } - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/HelpPageConfigurationExtensions.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/HelpPageConfigurationExtensions.cs deleted file mode 100644 index f4883c3..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/HelpPageConfigurationExtensions.cs +++ /dev/null @@ -1,467 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Linq; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Web.Http; -using System.Web.Http.Controllers; -using System.Web.Http.Description; -using AppBackend.Areas.HelpPage.ModelDescriptions; -using AppBackend.Areas.HelpPage.Models; - -namespace AppBackend.Areas.HelpPage -{ - public static class HelpPageConfigurationExtensions - { - private const string ApiModelPrefix = "MS_HelpPageApiModel_"; - - /// - /// Sets the documentation provider for help page. - /// - /// The . - /// The documentation provider. - public static void SetDocumentationProvider(this HttpConfiguration config, IDocumentationProvider documentationProvider) - { - config.Services.Replace(typeof(IDocumentationProvider), documentationProvider); - } - - /// - /// Sets the objects that will be used by the formatters to produce sample requests/responses. - /// - /// The . - /// The sample objects. - public static void SetSampleObjects(this HttpConfiguration config, IDictionary sampleObjects) - { - config.GetHelpPageSampleGenerator().SampleObjects = sampleObjects; - } - - /// - /// Sets the sample request directly for the specified media type and action. - /// - /// The . - /// The sample request. - /// The media type. - /// Name of the controller. - /// Name of the action. - public static void SetSampleRequest(this HttpConfiguration config, object sample, MediaTypeHeaderValue mediaType, string controllerName, string actionName) - { - config.GetHelpPageSampleGenerator().ActionSamples.Add(new HelpPageSampleKey(mediaType, SampleDirection.Request, controllerName, actionName, new[] { "*" }), sample); - } - - /// - /// Sets the sample request directly for the specified media type and action with parameters. - /// - /// The . - /// The sample request. - /// The media type. - /// Name of the controller. - /// Name of the action. - /// The parameter names. - public static void SetSampleRequest(this HttpConfiguration config, object sample, MediaTypeHeaderValue mediaType, string controllerName, string actionName, params string[] parameterNames) - { - config.GetHelpPageSampleGenerator().ActionSamples.Add(new HelpPageSampleKey(mediaType, SampleDirection.Request, controllerName, actionName, parameterNames), sample); - } - - /// - /// Sets the sample request directly for the specified media type of the action. - /// - /// The . - /// The sample response. - /// The media type. - /// Name of the controller. - /// Name of the action. - public static void SetSampleResponse(this HttpConfiguration config, object sample, MediaTypeHeaderValue mediaType, string controllerName, string actionName) - { - config.GetHelpPageSampleGenerator().ActionSamples.Add(new HelpPageSampleKey(mediaType, SampleDirection.Response, controllerName, actionName, new[] { "*" }), sample); - } - - /// - /// Sets the sample response directly for the specified media type of the action with specific parameters. - /// - /// The . - /// The sample response. - /// The media type. - /// Name of the controller. - /// Name of the action. - /// The parameter names. - public static void SetSampleResponse(this HttpConfiguration config, object sample, MediaTypeHeaderValue mediaType, string controllerName, string actionName, params string[] parameterNames) - { - config.GetHelpPageSampleGenerator().ActionSamples.Add(new HelpPageSampleKey(mediaType, SampleDirection.Response, controllerName, actionName, parameterNames), sample); - } - - /// - /// Sets the sample directly for all actions with the specified media type. - /// - /// The . - /// The sample. - /// The media type. - public static void SetSampleForMediaType(this HttpConfiguration config, object sample, MediaTypeHeaderValue mediaType) - { - config.GetHelpPageSampleGenerator().ActionSamples.Add(new HelpPageSampleKey(mediaType), sample); - } - - /// - /// Sets the sample directly for all actions with the specified type and media type. - /// - /// The . - /// The sample. - /// The media type. - /// The parameter type or return type of an action. - public static void SetSampleForType(this HttpConfiguration config, object sample, MediaTypeHeaderValue mediaType, Type type) - { - config.GetHelpPageSampleGenerator().ActionSamples.Add(new HelpPageSampleKey(mediaType, type), sample); - } - - /// - /// Specifies the actual type of passed to the in an action. - /// The help page will use this information to produce more accurate request samples. - /// - /// The . - /// The type. - /// Name of the controller. - /// Name of the action. - public static void SetActualRequestType(this HttpConfiguration config, Type type, string controllerName, string actionName) - { - config.GetHelpPageSampleGenerator().ActualHttpMessageTypes.Add(new HelpPageSampleKey(SampleDirection.Request, controllerName, actionName, new[] { "*" }), type); - } - - /// - /// Specifies the actual type of passed to the in an action. - /// The help page will use this information to produce more accurate request samples. - /// - /// The . - /// The type. - /// Name of the controller. - /// Name of the action. - /// The parameter names. - public static void SetActualRequestType(this HttpConfiguration config, Type type, string controllerName, string actionName, params string[] parameterNames) - { - config.GetHelpPageSampleGenerator().ActualHttpMessageTypes.Add(new HelpPageSampleKey(SampleDirection.Request, controllerName, actionName, parameterNames), type); - } - - /// - /// Specifies the actual type of returned as part of the in an action. - /// The help page will use this information to produce more accurate response samples. - /// - /// The . - /// The type. - /// Name of the controller. - /// Name of the action. - public static void SetActualResponseType(this HttpConfiguration config, Type type, string controllerName, string actionName) - { - config.GetHelpPageSampleGenerator().ActualHttpMessageTypes.Add(new HelpPageSampleKey(SampleDirection.Response, controllerName, actionName, new[] { "*" }), type); - } - - /// - /// Specifies the actual type of returned as part of the in an action. - /// The help page will use this information to produce more accurate response samples. - /// - /// The . - /// The type. - /// Name of the controller. - /// Name of the action. - /// The parameter names. - public static void SetActualResponseType(this HttpConfiguration config, Type type, string controllerName, string actionName, params string[] parameterNames) - { - config.GetHelpPageSampleGenerator().ActualHttpMessageTypes.Add(new HelpPageSampleKey(SampleDirection.Response, controllerName, actionName, parameterNames), type); - } - - /// - /// Gets the help page sample generator. - /// - /// The . - /// The help page sample generator. - public static HelpPageSampleGenerator GetHelpPageSampleGenerator(this HttpConfiguration config) - { - return (HelpPageSampleGenerator)config.Properties.GetOrAdd( - typeof(HelpPageSampleGenerator), - k => new HelpPageSampleGenerator()); - } - - /// - /// Sets the help page sample generator. - /// - /// The . - /// The help page sample generator. - public static void SetHelpPageSampleGenerator(this HttpConfiguration config, HelpPageSampleGenerator sampleGenerator) - { - config.Properties.AddOrUpdate( - typeof(HelpPageSampleGenerator), - k => sampleGenerator, - (k, o) => sampleGenerator); - } - - /// - /// Gets the model description generator. - /// - /// The configuration. - /// The - public static ModelDescriptionGenerator GetModelDescriptionGenerator(this HttpConfiguration config) - { - return (ModelDescriptionGenerator)config.Properties.GetOrAdd( - typeof(ModelDescriptionGenerator), - k => InitializeModelDescriptionGenerator(config)); - } - - /// - /// Gets the model that represents an API displayed on the help page. The model is initialized on the first call and cached for subsequent calls. - /// - /// The . - /// The ID. - /// - /// An - /// - public static HelpPageApiModel GetHelpPageApiModel(this HttpConfiguration config, string apiDescriptionId) - { - object model; - string modelId = ApiModelPrefix + apiDescriptionId; - if (!config.Properties.TryGetValue(modelId, out model)) - { - Collection apiDescriptions = config.Services.GetApiExplorer().ApiDescriptions; - ApiDescription apiDescription = apiDescriptions.FirstOrDefault(api => String.Equals(api.GetFriendlyId(), apiDescriptionId, StringComparison.OrdinalIgnoreCase)); - if (apiDescription != null) - { - model = GenerateApiModel(apiDescription, config); - config.Properties.TryAdd(modelId, model); - } - } - - return (HelpPageApiModel)model; - } - - private static HelpPageApiModel GenerateApiModel(ApiDescription apiDescription, HttpConfiguration config) - { - HelpPageApiModel apiModel = new HelpPageApiModel() - { - ApiDescription = apiDescription, - }; - - ModelDescriptionGenerator modelGenerator = config.GetModelDescriptionGenerator(); - HelpPageSampleGenerator sampleGenerator = config.GetHelpPageSampleGenerator(); - GenerateUriParameters(apiModel, modelGenerator); - GenerateRequestModelDescription(apiModel, modelGenerator, sampleGenerator); - GenerateResourceDescription(apiModel, modelGenerator); - GenerateSamples(apiModel, sampleGenerator); - - return apiModel; - } - - private static void GenerateUriParameters(HelpPageApiModel apiModel, ModelDescriptionGenerator modelGenerator) - { - ApiDescription apiDescription = apiModel.ApiDescription; - foreach (ApiParameterDescription apiParameter in apiDescription.ParameterDescriptions) - { - if (apiParameter.Source == ApiParameterSource.FromUri) - { - HttpParameterDescriptor parameterDescriptor = apiParameter.ParameterDescriptor; - Type parameterType = null; - ModelDescription typeDescription = null; - ComplexTypeModelDescription complexTypeDescription = null; - if (parameterDescriptor != null) - { - parameterType = parameterDescriptor.ParameterType; - typeDescription = modelGenerator.GetOrCreateModelDescription(parameterType); - complexTypeDescription = typeDescription as ComplexTypeModelDescription; - } - - // Example: - // [TypeConverter(typeof(PointConverter))] - // public class Point - // { - // public Point(int x, int y) - // { - // X = x; - // Y = y; - // } - // public int X { get; set; } - // public int Y { get; set; } - // } - // Class Point is bindable with a TypeConverter, so Point will be added to UriParameters collection. - // - // public class Point - // { - // public int X { get; set; } - // public int Y { get; set; } - // } - // Regular complex class Point will have properties X and Y added to UriParameters collection. - if (complexTypeDescription != null - && !IsBindableWithTypeConverter(parameterType)) - { - foreach (ParameterDescription uriParameter in complexTypeDescription.Properties) - { - apiModel.UriParameters.Add(uriParameter); - } - } - else if (parameterDescriptor != null) - { - ParameterDescription uriParameter = - AddParameterDescription(apiModel, apiParameter, typeDescription); - - if (!parameterDescriptor.IsOptional) - { - uriParameter.Annotations.Add(new ParameterAnnotation() { Documentation = "Required" }); - } - - object defaultValue = parameterDescriptor.DefaultValue; - if (defaultValue != null) - { - uriParameter.Annotations.Add(new ParameterAnnotation() { Documentation = "Default value is " + Convert.ToString(defaultValue, CultureInfo.InvariantCulture) }); - } - } - else - { - Debug.Assert(parameterDescriptor == null); - - // If parameterDescriptor is null, this is an undeclared route parameter which only occurs - // when source is FromUri. Ignored in request model and among resource parameters but listed - // as a simple string here. - ModelDescription modelDescription = modelGenerator.GetOrCreateModelDescription(typeof(string)); - AddParameterDescription(apiModel, apiParameter, modelDescription); - } - } - } - } - - private static bool IsBindableWithTypeConverter(Type parameterType) - { - if (parameterType == null) - { - return false; - } - - return TypeDescriptor.GetConverter(parameterType).CanConvertFrom(typeof(string)); - } - - private static ParameterDescription AddParameterDescription(HelpPageApiModel apiModel, - ApiParameterDescription apiParameter, ModelDescription typeDescription) - { - ParameterDescription parameterDescription = new ParameterDescription - { - Name = apiParameter.Name, - Documentation = apiParameter.Documentation, - TypeDescription = typeDescription, - }; - - apiModel.UriParameters.Add(parameterDescription); - return parameterDescription; - } - - private static void GenerateRequestModelDescription(HelpPageApiModel apiModel, ModelDescriptionGenerator modelGenerator, HelpPageSampleGenerator sampleGenerator) - { - ApiDescription apiDescription = apiModel.ApiDescription; - foreach (ApiParameterDescription apiParameter in apiDescription.ParameterDescriptions) - { - if (apiParameter.Source == ApiParameterSource.FromBody) - { - Type parameterType = apiParameter.ParameterDescriptor.ParameterType; - apiModel.RequestModelDescription = modelGenerator.GetOrCreateModelDescription(parameterType); - apiModel.RequestDocumentation = apiParameter.Documentation; - } - else if (apiParameter.ParameterDescriptor != null && - apiParameter.ParameterDescriptor.ParameterType == typeof(HttpRequestMessage)) - { - Type parameterType = sampleGenerator.ResolveHttpRequestMessageType(apiDescription); - - if (parameterType != null) - { - apiModel.RequestModelDescription = modelGenerator.GetOrCreateModelDescription(parameterType); - } - } - } - } - - private static void GenerateResourceDescription(HelpPageApiModel apiModel, ModelDescriptionGenerator modelGenerator) - { - ResponseDescription response = apiModel.ApiDescription.ResponseDescription; - Type responseType = response.ResponseType ?? response.DeclaredType; - if (responseType != null && responseType != typeof(void)) - { - apiModel.ResourceDescription = modelGenerator.GetOrCreateModelDescription(responseType); - } - } - - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "The exception is recorded as ErrorMessages.")] - private static void GenerateSamples(HelpPageApiModel apiModel, HelpPageSampleGenerator sampleGenerator) - { - try - { - foreach (var item in sampleGenerator.GetSampleRequests(apiModel.ApiDescription)) - { - apiModel.SampleRequests.Add(item.Key, item.Value); - LogInvalidSampleAsError(apiModel, item.Value); - } - - foreach (var item in sampleGenerator.GetSampleResponses(apiModel.ApiDescription)) - { - apiModel.SampleResponses.Add(item.Key, item.Value); - LogInvalidSampleAsError(apiModel, item.Value); - } - } - catch (Exception e) - { - apiModel.ErrorMessages.Add(String.Format(CultureInfo.CurrentCulture, - "An exception has occurred while generating the sample. Exception message: {0}", - HelpPageSampleGenerator.UnwrapException(e).Message)); - } - } - - private static bool TryGetResourceParameter(ApiDescription apiDescription, HttpConfiguration config, out ApiParameterDescription parameterDescription, out Type resourceType) - { - parameterDescription = apiDescription.ParameterDescriptions.FirstOrDefault( - p => p.Source == ApiParameterSource.FromBody || - (p.ParameterDescriptor != null && p.ParameterDescriptor.ParameterType == typeof(HttpRequestMessage))); - - if (parameterDescription == null) - { - resourceType = null; - return false; - } - - resourceType = parameterDescription.ParameterDescriptor.ParameterType; - - if (resourceType == typeof(HttpRequestMessage)) - { - HelpPageSampleGenerator sampleGenerator = config.GetHelpPageSampleGenerator(); - resourceType = sampleGenerator.ResolveHttpRequestMessageType(apiDescription); - } - - if (resourceType == null) - { - parameterDescription = null; - return false; - } - - return true; - } - - private static ModelDescriptionGenerator InitializeModelDescriptionGenerator(HttpConfiguration config) - { - ModelDescriptionGenerator modelGenerator = new ModelDescriptionGenerator(config); - Collection apis = config.Services.GetApiExplorer().ApiDescriptions; - foreach (ApiDescription api in apis) - { - ApiParameterDescription parameterDescription; - Type parameterType; - if (TryGetResourceParameter(api, config, out parameterDescription, out parameterType)) - { - modelGenerator.GetOrCreateModelDescription(parameterType); - } - } - return modelGenerator; - } - - private static void LogInvalidSampleAsError(HelpPageApiModel apiModel, object sample) - { - InvalidSample invalidSample = sample as InvalidSample; - if (invalidSample != null) - { - apiModel.ErrorMessages.Add(invalidSample.ErrorMessage); - } - } - } -} diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/CollectionModelDescription.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/CollectionModelDescription.cs deleted file mode 100644 index 3608423..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/CollectionModelDescription.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace AppBackend.Areas.HelpPage.ModelDescriptions -{ - public class CollectionModelDescription : ModelDescription - { - public ModelDescription ElementDescription { get; set; } - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/ComplexTypeModelDescription.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/ComplexTypeModelDescription.cs deleted file mode 100644 index ae5cfba..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/ComplexTypeModelDescription.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Collections.ObjectModel; - -namespace AppBackend.Areas.HelpPage.ModelDescriptions -{ - public class ComplexTypeModelDescription : ModelDescription - { - public ComplexTypeModelDescription() - { - Properties = new Collection(); - } - - public Collection Properties { get; private set; } - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/DictionaryModelDescription.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/DictionaryModelDescription.cs deleted file mode 100644 index 057b2d5..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/DictionaryModelDescription.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace AppBackend.Areas.HelpPage.ModelDescriptions -{ - public class DictionaryModelDescription : KeyValuePairModelDescription - { - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/EnumTypeModelDescription.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/EnumTypeModelDescription.cs deleted file mode 100644 index e49702c..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/EnumTypeModelDescription.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Collections.Generic; -using System.Collections.ObjectModel; - -namespace AppBackend.Areas.HelpPage.ModelDescriptions -{ - public class EnumTypeModelDescription : ModelDescription - { - public EnumTypeModelDescription() - { - Values = new Collection(); - } - - public Collection Values { get; private set; } - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/EnumValueDescription.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/EnumValueDescription.cs deleted file mode 100644 index bb0d4ce..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/EnumValueDescription.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace AppBackend.Areas.HelpPage.ModelDescriptions -{ - public class EnumValueDescription - { - public string Documentation { get; set; } - - public string Name { get; set; } - - public string Value { get; set; } - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/IModelDocumentationProvider.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/IModelDocumentationProvider.cs deleted file mode 100644 index 34c8c67..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/IModelDocumentationProvider.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Reflection; - -namespace AppBackend.Areas.HelpPage.ModelDescriptions -{ - public interface IModelDocumentationProvider - { - string GetDocumentation(MemberInfo member); - - string GetDocumentation(Type type); - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/KeyValuePairModelDescription.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/KeyValuePairModelDescription.cs deleted file mode 100644 index d297f88..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/KeyValuePairModelDescription.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace AppBackend.Areas.HelpPage.ModelDescriptions -{ - public class KeyValuePairModelDescription : ModelDescription - { - public ModelDescription KeyModelDescription { get; set; } - - public ModelDescription ValueModelDescription { get; set; } - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/ModelDescription.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/ModelDescription.cs deleted file mode 100644 index 1b918ab..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/ModelDescription.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; - -namespace AppBackend.Areas.HelpPage.ModelDescriptions -{ - /// - /// Describes a type model. - /// - public abstract class ModelDescription - { - public string Documentation { get; set; } - - public Type ModelType { get; set; } - - public string Name { get; set; } - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/ModelDescriptionGenerator.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/ModelDescriptionGenerator.cs deleted file mode 100644 index 60cb74d..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/ModelDescriptionGenerator.cs +++ /dev/null @@ -1,451 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.ComponentModel.DataAnnotations; -using System.Globalization; -using System.Reflection; -using System.Runtime.Serialization; -using System.Web.Http; -using System.Web.Http.Description; -using System.Xml.Serialization; -using Newtonsoft.Json; - -namespace AppBackend.Areas.HelpPage.ModelDescriptions -{ - /// - /// Generates model descriptions for given types. - /// - public class ModelDescriptionGenerator - { - // Modify this to support more data annotation attributes. - private readonly IDictionary> AnnotationTextGenerator = new Dictionary> - { - { typeof(RequiredAttribute), a => "Required" }, - { typeof(RangeAttribute), a => - { - RangeAttribute range = (RangeAttribute)a; - return String.Format(CultureInfo.CurrentCulture, "Range: inclusive between {0} and {1}", range.Minimum, range.Maximum); - } - }, - { typeof(MaxLengthAttribute), a => - { - MaxLengthAttribute maxLength = (MaxLengthAttribute)a; - return String.Format(CultureInfo.CurrentCulture, "Max length: {0}", maxLength.Length); - } - }, - { typeof(MinLengthAttribute), a => - { - MinLengthAttribute minLength = (MinLengthAttribute)a; - return String.Format(CultureInfo.CurrentCulture, "Min length: {0}", minLength.Length); - } - }, - { typeof(StringLengthAttribute), a => - { - StringLengthAttribute strLength = (StringLengthAttribute)a; - return String.Format(CultureInfo.CurrentCulture, "String length: inclusive between {0} and {1}", strLength.MinimumLength, strLength.MaximumLength); - } - }, - { typeof(DataTypeAttribute), a => - { - DataTypeAttribute dataType = (DataTypeAttribute)a; - return String.Format(CultureInfo.CurrentCulture, "Data type: {0}", dataType.CustomDataType ?? dataType.DataType.ToString()); - } - }, - { typeof(RegularExpressionAttribute), a => - { - RegularExpressionAttribute regularExpression = (RegularExpressionAttribute)a; - return String.Format(CultureInfo.CurrentCulture, "Matching regular expression pattern: {0}", regularExpression.Pattern); - } - }, - }; - - // Modify this to add more default documentations. - private readonly IDictionary DefaultTypeDocumentation = new Dictionary - { - { typeof(Int16), "integer" }, - { typeof(Int32), "integer" }, - { typeof(Int64), "integer" }, - { typeof(UInt16), "unsigned integer" }, - { typeof(UInt32), "unsigned integer" }, - { typeof(UInt64), "unsigned integer" }, - { typeof(Byte), "byte" }, - { typeof(Char), "character" }, - { typeof(SByte), "signed byte" }, - { typeof(Uri), "URI" }, - { typeof(Single), "decimal number" }, - { typeof(Double), "decimal number" }, - { typeof(Decimal), "decimal number" }, - { typeof(String), "string" }, - { typeof(Guid), "globally unique identifier" }, - { typeof(TimeSpan), "time interval" }, - { typeof(DateTime), "date" }, - { typeof(DateTimeOffset), "date" }, - { typeof(Boolean), "boolean" }, - }; - - private Lazy _documentationProvider; - - public ModelDescriptionGenerator(HttpConfiguration config) - { - if (config == null) - { - throw new ArgumentNullException("config"); - } - - _documentationProvider = new Lazy(() => config.Services.GetDocumentationProvider() as IModelDocumentationProvider); - GeneratedModels = new Dictionary(StringComparer.OrdinalIgnoreCase); - } - - public Dictionary GeneratedModels { get; private set; } - - private IModelDocumentationProvider DocumentationProvider - { - get - { - return _documentationProvider.Value; - } - } - - public ModelDescription GetOrCreateModelDescription(Type modelType) - { - if (modelType == null) - { - throw new ArgumentNullException("modelType"); - } - - Type underlyingType = Nullable.GetUnderlyingType(modelType); - if (underlyingType != null) - { - modelType = underlyingType; - } - - ModelDescription modelDescription; - string modelName = ModelNameHelper.GetModelName(modelType); - if (GeneratedModels.TryGetValue(modelName, out modelDescription)) - { - if (modelType != modelDescription.ModelType) - { - throw new InvalidOperationException( - String.Format( - CultureInfo.CurrentCulture, - "A model description could not be created. Duplicate model name '{0}' was found for types '{1}' and '{2}'. " + - "Use the [ModelName] attribute to change the model name for at least one of the types so that it has a unique name.", - modelName, - modelDescription.ModelType.FullName, - modelType.FullName)); - } - - return modelDescription; - } - - if (DefaultTypeDocumentation.ContainsKey(modelType)) - { - return GenerateSimpleTypeModelDescription(modelType); - } - - if (modelType.IsEnum) - { - return GenerateEnumTypeModelDescription(modelType); - } - - if (modelType.IsGenericType) - { - Type[] genericArguments = modelType.GetGenericArguments(); - - if (genericArguments.Length == 1) - { - Type enumerableType = typeof(IEnumerable<>).MakeGenericType(genericArguments); - if (enumerableType.IsAssignableFrom(modelType)) - { - return GenerateCollectionModelDescription(modelType, genericArguments[0]); - } - } - if (genericArguments.Length == 2) - { - Type dictionaryType = typeof(IDictionary<,>).MakeGenericType(genericArguments); - if (dictionaryType.IsAssignableFrom(modelType)) - { - return GenerateDictionaryModelDescription(modelType, genericArguments[0], genericArguments[1]); - } - - Type keyValuePairType = typeof(KeyValuePair<,>).MakeGenericType(genericArguments); - if (keyValuePairType.IsAssignableFrom(modelType)) - { - return GenerateKeyValuePairModelDescription(modelType, genericArguments[0], genericArguments[1]); - } - } - } - - if (modelType.IsArray) - { - Type elementType = modelType.GetElementType(); - return GenerateCollectionModelDescription(modelType, elementType); - } - - if (modelType == typeof(NameValueCollection)) - { - return GenerateDictionaryModelDescription(modelType, typeof(string), typeof(string)); - } - - if (typeof(IDictionary).IsAssignableFrom(modelType)) - { - return GenerateDictionaryModelDescription(modelType, typeof(object), typeof(object)); - } - - if (typeof(IEnumerable).IsAssignableFrom(modelType)) - { - return GenerateCollectionModelDescription(modelType, typeof(object)); - } - - return GenerateComplexTypeModelDescription(modelType); - } - - // Change this to provide different name for the member. - private static string GetMemberName(MemberInfo member, bool hasDataContractAttribute) - { - JsonPropertyAttribute jsonProperty = member.GetCustomAttribute(); - if (jsonProperty != null && !String.IsNullOrEmpty(jsonProperty.PropertyName)) - { - return jsonProperty.PropertyName; - } - - if (hasDataContractAttribute) - { - DataMemberAttribute dataMember = member.GetCustomAttribute(); - if (dataMember != null && !String.IsNullOrEmpty(dataMember.Name)) - { - return dataMember.Name; - } - } - - return member.Name; - } - - private static bool ShouldDisplayMember(MemberInfo member, bool hasDataContractAttribute) - { - JsonIgnoreAttribute jsonIgnore = member.GetCustomAttribute(); - XmlIgnoreAttribute xmlIgnore = member.GetCustomAttribute(); - IgnoreDataMemberAttribute ignoreDataMember = member.GetCustomAttribute(); - NonSerializedAttribute nonSerialized = member.GetCustomAttribute(); - ApiExplorerSettingsAttribute apiExplorerSetting = member.GetCustomAttribute(); - - bool hasMemberAttribute = member.DeclaringType.IsEnum ? - member.GetCustomAttribute() != null : - member.GetCustomAttribute() != null; - - // Display member only if all the followings are true: - // no JsonIgnoreAttribute - // no XmlIgnoreAttribute - // no IgnoreDataMemberAttribute - // no NonSerializedAttribute - // no ApiExplorerSettingsAttribute with IgnoreApi set to true - // no DataContractAttribute without DataMemberAttribute or EnumMemberAttribute - return jsonIgnore == null && - xmlIgnore == null && - ignoreDataMember == null && - nonSerialized == null && - (apiExplorerSetting == null || !apiExplorerSetting.IgnoreApi) && - (!hasDataContractAttribute || hasMemberAttribute); - } - - private string CreateDefaultDocumentation(Type type) - { - string documentation; - if (DefaultTypeDocumentation.TryGetValue(type, out documentation)) - { - return documentation; - } - if (DocumentationProvider != null) - { - documentation = DocumentationProvider.GetDocumentation(type); - } - - return documentation; - } - - private void GenerateAnnotations(MemberInfo property, ParameterDescription propertyModel) - { - List annotations = new List(); - - IEnumerable attributes = property.GetCustomAttributes(); - foreach (Attribute attribute in attributes) - { - Func textGenerator; - if (AnnotationTextGenerator.TryGetValue(attribute.GetType(), out textGenerator)) - { - annotations.Add( - new ParameterAnnotation - { - AnnotationAttribute = attribute, - Documentation = textGenerator(attribute) - }); - } - } - - // Rearrange the annotations - annotations.Sort((x, y) => - { - // Special-case RequiredAttribute so that it shows up on top - if (x.AnnotationAttribute is RequiredAttribute) - { - return -1; - } - if (y.AnnotationAttribute is RequiredAttribute) - { - return 1; - } - - // Sort the rest based on alphabetic order of the documentation - return String.Compare(x.Documentation, y.Documentation, StringComparison.OrdinalIgnoreCase); - }); - - foreach (ParameterAnnotation annotation in annotations) - { - propertyModel.Annotations.Add(annotation); - } - } - - private CollectionModelDescription GenerateCollectionModelDescription(Type modelType, Type elementType) - { - ModelDescription collectionModelDescription = GetOrCreateModelDescription(elementType); - if (collectionModelDescription != null) - { - return new CollectionModelDescription - { - Name = ModelNameHelper.GetModelName(modelType), - ModelType = modelType, - ElementDescription = collectionModelDescription - }; - } - - return null; - } - - private ModelDescription GenerateComplexTypeModelDescription(Type modelType) - { - ComplexTypeModelDescription complexModelDescription = new ComplexTypeModelDescription - { - Name = ModelNameHelper.GetModelName(modelType), - ModelType = modelType, - Documentation = CreateDefaultDocumentation(modelType) - }; - - GeneratedModels.Add(complexModelDescription.Name, complexModelDescription); - bool hasDataContractAttribute = modelType.GetCustomAttribute() != null; - PropertyInfo[] properties = modelType.GetProperties(BindingFlags.Public | BindingFlags.Instance); - foreach (PropertyInfo property in properties) - { - if (ShouldDisplayMember(property, hasDataContractAttribute)) - { - ParameterDescription propertyModel = new ParameterDescription - { - Name = GetMemberName(property, hasDataContractAttribute) - }; - - if (DocumentationProvider != null) - { - propertyModel.Documentation = DocumentationProvider.GetDocumentation(property); - } - - GenerateAnnotations(property, propertyModel); - complexModelDescription.Properties.Add(propertyModel); - propertyModel.TypeDescription = GetOrCreateModelDescription(property.PropertyType); - } - } - - FieldInfo[] fields = modelType.GetFields(BindingFlags.Public | BindingFlags.Instance); - foreach (FieldInfo field in fields) - { - if (ShouldDisplayMember(field, hasDataContractAttribute)) - { - ParameterDescription propertyModel = new ParameterDescription - { - Name = GetMemberName(field, hasDataContractAttribute) - }; - - if (DocumentationProvider != null) - { - propertyModel.Documentation = DocumentationProvider.GetDocumentation(field); - } - - complexModelDescription.Properties.Add(propertyModel); - propertyModel.TypeDescription = GetOrCreateModelDescription(field.FieldType); - } - } - - return complexModelDescription; - } - - private DictionaryModelDescription GenerateDictionaryModelDescription(Type modelType, Type keyType, Type valueType) - { - ModelDescription keyModelDescription = GetOrCreateModelDescription(keyType); - ModelDescription valueModelDescription = GetOrCreateModelDescription(valueType); - - return new DictionaryModelDescription - { - Name = ModelNameHelper.GetModelName(modelType), - ModelType = modelType, - KeyModelDescription = keyModelDescription, - ValueModelDescription = valueModelDescription - }; - } - - private EnumTypeModelDescription GenerateEnumTypeModelDescription(Type modelType) - { - EnumTypeModelDescription enumDescription = new EnumTypeModelDescription - { - Name = ModelNameHelper.GetModelName(modelType), - ModelType = modelType, - Documentation = CreateDefaultDocumentation(modelType) - }; - bool hasDataContractAttribute = modelType.GetCustomAttribute() != null; - foreach (FieldInfo field in modelType.GetFields(BindingFlags.Public | BindingFlags.Static)) - { - if (ShouldDisplayMember(field, hasDataContractAttribute)) - { - EnumValueDescription enumValue = new EnumValueDescription - { - Name = field.Name, - Value = field.GetRawConstantValue().ToString() - }; - if (DocumentationProvider != null) - { - enumValue.Documentation = DocumentationProvider.GetDocumentation(field); - } - enumDescription.Values.Add(enumValue); - } - } - GeneratedModels.Add(enumDescription.Name, enumDescription); - - return enumDescription; - } - - private KeyValuePairModelDescription GenerateKeyValuePairModelDescription(Type modelType, Type keyType, Type valueType) - { - ModelDescription keyModelDescription = GetOrCreateModelDescription(keyType); - ModelDescription valueModelDescription = GetOrCreateModelDescription(valueType); - - return new KeyValuePairModelDescription - { - Name = ModelNameHelper.GetModelName(modelType), - ModelType = modelType, - KeyModelDescription = keyModelDescription, - ValueModelDescription = valueModelDescription - }; - } - - private ModelDescription GenerateSimpleTypeModelDescription(Type modelType) - { - SimpleTypeModelDescription simpleModelDescription = new SimpleTypeModelDescription - { - Name = ModelNameHelper.GetModelName(modelType), - ModelType = modelType, - Documentation = CreateDefaultDocumentation(modelType) - }; - GeneratedModels.Add(simpleModelDescription.Name, simpleModelDescription); - - return simpleModelDescription; - } - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/ModelNameAttribute.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/ModelNameAttribute.cs deleted file mode 100644 index 76e1bee..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/ModelNameAttribute.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; - -namespace AppBackend.Areas.HelpPage.ModelDescriptions -{ - /// - /// Use this attribute to change the name of the generated for a type. - /// - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum, AllowMultiple = false, Inherited = false)] - public sealed class ModelNameAttribute : Attribute - { - public ModelNameAttribute(string name) - { - Name = name; - } - - public string Name { get; private set; } - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/ModelNameHelper.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/ModelNameHelper.cs deleted file mode 100644 index 406272a..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/ModelNameHelper.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Globalization; -using System.Linq; -using System.Reflection; - -namespace AppBackend.Areas.HelpPage.ModelDescriptions -{ - internal static class ModelNameHelper - { - // Modify this to provide custom model name mapping. - public static string GetModelName(Type type) - { - ModelNameAttribute modelNameAttribute = type.GetCustomAttribute(); - if (modelNameAttribute != null && !String.IsNullOrEmpty(modelNameAttribute.Name)) - { - return modelNameAttribute.Name; - } - - string modelName = type.Name; - if (type.IsGenericType) - { - // Format the generic type name to something like: GenericOfAgurment1AndArgument2 - Type genericType = type.GetGenericTypeDefinition(); - Type[] genericArguments = type.GetGenericArguments(); - string genericTypeName = genericType.Name; - - // Trim the generic parameter counts from the name - genericTypeName = genericTypeName.Substring(0, genericTypeName.IndexOf('`')); - string[] argumentTypeNames = genericArguments.Select(t => GetModelName(t)).ToArray(); - modelName = String.Format(CultureInfo.InvariantCulture, "{0}Of{1}", genericTypeName, String.Join("And", argumentTypeNames)); - } - - return modelName; - } - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/ParameterAnnotation.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/ParameterAnnotation.cs deleted file mode 100644 index a1da1ae..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/ParameterAnnotation.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace AppBackend.Areas.HelpPage.ModelDescriptions -{ - public class ParameterAnnotation - { - public Attribute AnnotationAttribute { get; set; } - - public string Documentation { get; set; } - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/ParameterDescription.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/ParameterDescription.cs deleted file mode 100644 index 947f743..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/ParameterDescription.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Collections.Generic; -using System.Collections.ObjectModel; - -namespace AppBackend.Areas.HelpPage.ModelDescriptions -{ - public class ParameterDescription - { - public ParameterDescription() - { - Annotations = new Collection(); - } - - public Collection Annotations { get; private set; } - - public string Documentation { get; set; } - - public string Name { get; set; } - - public ModelDescription TypeDescription { get; set; } - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/SimpleTypeModelDescription.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/SimpleTypeModelDescription.cs deleted file mode 100644 index 6e260a9..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/ModelDescriptions/SimpleTypeModelDescription.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace AppBackend.Areas.HelpPage.ModelDescriptions -{ - public class SimpleTypeModelDescription : ModelDescription - { - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Models/HelpPageApiModel.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Models/HelpPageApiModel.cs deleted file mode 100644 index 259041b..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Models/HelpPageApiModel.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Net.Http.Headers; -using System.Web.Http.Description; -using AppBackend.Areas.HelpPage.ModelDescriptions; - -namespace AppBackend.Areas.HelpPage.Models -{ - /// - /// The model that represents an API displayed on the help page. - /// - public class HelpPageApiModel - { - /// - /// Initializes a new instance of the class. - /// - public HelpPageApiModel() - { - UriParameters = new Collection(); - SampleRequests = new Dictionary(); - SampleResponses = new Dictionary(); - ErrorMessages = new Collection(); - } - - /// - /// Gets or sets the that describes the API. - /// - public ApiDescription ApiDescription { get; set; } - - /// - /// Gets or sets the collection that describes the URI parameters for the API. - /// - public Collection UriParameters { get; private set; } - - /// - /// Gets or sets the documentation for the request. - /// - public string RequestDocumentation { get; set; } - - /// - /// Gets or sets the that describes the request body. - /// - public ModelDescription RequestModelDescription { get; set; } - - /// - /// Gets the request body parameter descriptions. - /// - public IList RequestBodyParameters - { - get - { - return GetParameterDescriptions(RequestModelDescription); - } - } - - /// - /// Gets or sets the that describes the resource. - /// - public ModelDescription ResourceDescription { get; set; } - - /// - /// Gets the resource property descriptions. - /// - public IList ResourceProperties - { - get - { - return GetParameterDescriptions(ResourceDescription); - } - } - - /// - /// Gets the sample requests associated with the API. - /// - public IDictionary SampleRequests { get; private set; } - - /// - /// Gets the sample responses associated with the API. - /// - public IDictionary SampleResponses { get; private set; } - - /// - /// Gets the error messages associated with this model. - /// - public Collection ErrorMessages { get; private set; } - - private static IList GetParameterDescriptions(ModelDescription modelDescription) - { - ComplexTypeModelDescription complexTypeModelDescription = modelDescription as ComplexTypeModelDescription; - if (complexTypeModelDescription != null) - { - return complexTypeModelDescription.Properties; - } - - CollectionModelDescription collectionModelDescription = modelDescription as CollectionModelDescription; - if (collectionModelDescription != null) - { - complexTypeModelDescription = collectionModelDescription.ElementDescription as ComplexTypeModelDescription; - if (complexTypeModelDescription != null) - { - return complexTypeModelDescription.Properties; - } - } - - return null; - } - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/SampleGeneration/HelpPageSampleGenerator.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/SampleGeneration/HelpPageSampleGenerator.cs deleted file mode 100644 index 5bca496..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/SampleGeneration/HelpPageSampleGenerator.cs +++ /dev/null @@ -1,444 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Net.Http; -using System.Net.Http.Formatting; -using System.Net.Http.Headers; -using System.Web.Http.Description; -using System.Xml.Linq; -using Newtonsoft.Json; - -namespace AppBackend.Areas.HelpPage -{ - /// - /// This class will generate the samples for the help page. - /// - public class HelpPageSampleGenerator - { - /// - /// Initializes a new instance of the class. - /// - public HelpPageSampleGenerator() - { - ActualHttpMessageTypes = new Dictionary(); - ActionSamples = new Dictionary(); - SampleObjects = new Dictionary(); - SampleObjectFactories = new List> - { - DefaultSampleObjectFactory, - }; - } - - /// - /// Gets CLR types that are used as the content of or . - /// - public IDictionary ActualHttpMessageTypes { get; internal set; } - - /// - /// Gets the objects that are used directly as samples for certain actions. - /// - public IDictionary ActionSamples { get; internal set; } - - /// - /// Gets the objects that are serialized as samples by the supported formatters. - /// - public IDictionary SampleObjects { get; internal set; } - - /// - /// Gets factories for the objects that the supported formatters will serialize as samples. Processed in order, - /// stopping when the factory successfully returns a non- object. - /// - /// - /// Collection includes just initially. Use - /// SampleObjectFactories.Insert(0, func) to provide an override and - /// SampleObjectFactories.Add(func) to provide a fallback. - [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", - Justification = "This is an appropriate nesting of generic types")] - public IList> SampleObjectFactories { get; private set; } - - /// - /// Gets the request body samples for a given . - /// - /// The . - /// The samples keyed by media type. - public IDictionary GetSampleRequests(ApiDescription api) - { - return GetSample(api, SampleDirection.Request); - } - - /// - /// Gets the response body samples for a given . - /// - /// The . - /// The samples keyed by media type. - public IDictionary GetSampleResponses(ApiDescription api) - { - return GetSample(api, SampleDirection.Response); - } - - /// - /// Gets the request or response body samples. - /// - /// The . - /// The value indicating whether the sample is for a request or for a response. - /// The samples keyed by media type. - public virtual IDictionary GetSample(ApiDescription api, SampleDirection sampleDirection) - { - if (api == null) - { - throw new ArgumentNullException("api"); - } - string controllerName = api.ActionDescriptor.ControllerDescriptor.ControllerName; - string actionName = api.ActionDescriptor.ActionName; - IEnumerable parameterNames = api.ParameterDescriptions.Select(p => p.Name); - Collection formatters; - Type type = ResolveType(api, controllerName, actionName, parameterNames, sampleDirection, out formatters); - var samples = new Dictionary(); - - // Use the samples provided directly for actions - var actionSamples = GetAllActionSamples(controllerName, actionName, parameterNames, sampleDirection); - foreach (var actionSample in actionSamples) - { - samples.Add(actionSample.Key.MediaType, WrapSampleIfString(actionSample.Value)); - } - - // Do the sample generation based on formatters only if an action doesn't return an HttpResponseMessage. - // Here we cannot rely on formatters because we don't know what's in the HttpResponseMessage, it might not even use formatters. - if (type != null && !typeof(HttpResponseMessage).IsAssignableFrom(type)) - { - object sampleObject = GetSampleObject(type); - foreach (var formatter in formatters) - { - foreach (MediaTypeHeaderValue mediaType in formatter.SupportedMediaTypes) - { - if (!samples.ContainsKey(mediaType)) - { - object sample = GetActionSample(controllerName, actionName, parameterNames, type, formatter, mediaType, sampleDirection); - - // If no sample found, try generate sample using formatter and sample object - if (sample == null && sampleObject != null) - { - sample = WriteSampleObjectUsingFormatter(formatter, sampleObject, type, mediaType); - } - - samples.Add(mediaType, WrapSampleIfString(sample)); - } - } - } - } - - return samples; - } - - /// - /// Search for samples that are provided directly through . - /// - /// Name of the controller. - /// Name of the action. - /// The parameter names. - /// The CLR type. - /// The formatter. - /// The media type. - /// The value indicating whether the sample is for a request or for a response. - /// The sample that matches the parameters. - public virtual object GetActionSample(string controllerName, string actionName, IEnumerable parameterNames, Type type, MediaTypeFormatter formatter, MediaTypeHeaderValue mediaType, SampleDirection sampleDirection) - { - object sample; - - // First, try to get the sample provided for the specified mediaType, sampleDirection, controllerName, actionName and parameterNames. - // If not found, try to get the sample provided for the specified mediaType, sampleDirection, controllerName and actionName regardless of the parameterNames. - // If still not found, try to get the sample provided for the specified mediaType and type. - // Finally, try to get the sample provided for the specified mediaType. - if (ActionSamples.TryGetValue(new HelpPageSampleKey(mediaType, sampleDirection, controllerName, actionName, parameterNames), out sample) || - ActionSamples.TryGetValue(new HelpPageSampleKey(mediaType, sampleDirection, controllerName, actionName, new[] { "*" }), out sample) || - ActionSamples.TryGetValue(new HelpPageSampleKey(mediaType, type), out sample) || - ActionSamples.TryGetValue(new HelpPageSampleKey(mediaType), out sample)) - { - return sample; - } - - return null; - } - - /// - /// Gets the sample object that will be serialized by the formatters. - /// First, it will look at the . If no sample object is found, it will try to create - /// one using (which wraps an ) and other - /// factories in . - /// - /// The type. - /// The sample object. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", - Justification = "Even if all items in SampleObjectFactories throw, problem will be visible as missing sample.")] - public virtual object GetSampleObject(Type type) - { - object sampleObject; - - if (!SampleObjects.TryGetValue(type, out sampleObject)) - { - // No specific object available, try our factories. - foreach (Func factory in SampleObjectFactories) - { - if (factory == null) - { - continue; - } - - try - { - sampleObject = factory(this, type); - if (sampleObject != null) - { - break; - } - } - catch - { - // Ignore any problems encountered in the factory; go on to the next one (if any). - } - } - } - - return sampleObject; - } - - /// - /// Resolves the actual type of passed to the in an action. - /// - /// The . - /// The type. - public virtual Type ResolveHttpRequestMessageType(ApiDescription api) - { - string controllerName = api.ActionDescriptor.ControllerDescriptor.ControllerName; - string actionName = api.ActionDescriptor.ActionName; - IEnumerable parameterNames = api.ParameterDescriptions.Select(p => p.Name); - Collection formatters; - return ResolveType(api, controllerName, actionName, parameterNames, SampleDirection.Request, out formatters); - } - - /// - /// Resolves the type of the action parameter or return value when or is used. - /// - /// The . - /// Name of the controller. - /// Name of the action. - /// The parameter names. - /// The value indicating whether the sample is for a request or a response. - /// The formatters. - [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", Justification = "This is only used in advanced scenarios.")] - public virtual Type ResolveType(ApiDescription api, string controllerName, string actionName, IEnumerable parameterNames, SampleDirection sampleDirection, out Collection formatters) - { - if (!Enum.IsDefined(typeof(SampleDirection), sampleDirection)) - { - throw new InvalidEnumArgumentException("sampleDirection", (int)sampleDirection, typeof(SampleDirection)); - } - if (api == null) - { - throw new ArgumentNullException("api"); - } - Type type; - if (ActualHttpMessageTypes.TryGetValue(new HelpPageSampleKey(sampleDirection, controllerName, actionName, parameterNames), out type) || - ActualHttpMessageTypes.TryGetValue(new HelpPageSampleKey(sampleDirection, controllerName, actionName, new[] { "*" }), out type)) - { - // Re-compute the supported formatters based on type - Collection newFormatters = new Collection(); - foreach (var formatter in api.ActionDescriptor.Configuration.Formatters) - { - if (IsFormatSupported(sampleDirection, formatter, type)) - { - newFormatters.Add(formatter); - } - } - formatters = newFormatters; - } - else - { - switch (sampleDirection) - { - case SampleDirection.Request: - ApiParameterDescription requestBodyParameter = api.ParameterDescriptions.FirstOrDefault(p => p.Source == ApiParameterSource.FromBody); - type = requestBodyParameter == null ? null : requestBodyParameter.ParameterDescriptor.ParameterType; - formatters = api.SupportedRequestBodyFormatters; - break; - case SampleDirection.Response: - default: - type = api.ResponseDescription.ResponseType ?? api.ResponseDescription.DeclaredType; - formatters = api.SupportedResponseFormatters; - break; - } - } - - return type; - } - - /// - /// Writes the sample object using formatter. - /// - /// The formatter. - /// The value. - /// The type. - /// Type of the media. - /// - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "The exception is recorded as InvalidSample.")] - public virtual object WriteSampleObjectUsingFormatter(MediaTypeFormatter formatter, object value, Type type, MediaTypeHeaderValue mediaType) - { - if (formatter == null) - { - throw new ArgumentNullException("formatter"); - } - if (mediaType == null) - { - throw new ArgumentNullException("mediaType"); - } - - object sample = String.Empty; - MemoryStream ms = null; - HttpContent content = null; - try - { - if (formatter.CanWriteType(type)) - { - ms = new MemoryStream(); - content = new ObjectContent(type, value, formatter, mediaType); - formatter.WriteToStreamAsync(type, value, ms, content, null).Wait(); - ms.Position = 0; - StreamReader reader = new StreamReader(ms); - string serializedSampleString = reader.ReadToEnd(); - if (mediaType.MediaType.ToUpperInvariant().Contains("XML")) - { - serializedSampleString = TryFormatXml(serializedSampleString); - } - else if (mediaType.MediaType.ToUpperInvariant().Contains("JSON")) - { - serializedSampleString = TryFormatJson(serializedSampleString); - } - - sample = new TextSample(serializedSampleString); - } - else - { - sample = new InvalidSample(String.Format( - CultureInfo.CurrentCulture, - "Failed to generate the sample for media type '{0}'. Cannot use formatter '{1}' to write type '{2}'.", - mediaType, - formatter.GetType().Name, - type.Name)); - } - } - catch (Exception e) - { - sample = new InvalidSample(String.Format( - CultureInfo.CurrentCulture, - "An exception has occurred while using the formatter '{0}' to generate sample for media type '{1}'. Exception message: {2}", - formatter.GetType().Name, - mediaType.MediaType, - UnwrapException(e).Message)); - } - finally - { - if (ms != null) - { - ms.Dispose(); - } - if (content != null) - { - content.Dispose(); - } - } - - return sample; - } - - internal static Exception UnwrapException(Exception exception) - { - AggregateException aggregateException = exception as AggregateException; - if (aggregateException != null) - { - return aggregateException.Flatten().InnerException; - } - return exception; - } - - // Default factory for sample objects - private static object DefaultSampleObjectFactory(HelpPageSampleGenerator sampleGenerator, Type type) - { - // Try to create a default sample object - ObjectGenerator objectGenerator = new ObjectGenerator(); - return objectGenerator.GenerateObject(type); - } - - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Handling the failure by returning the original string.")] - private static string TryFormatJson(string str) - { - try - { - object parsedJson = JsonConvert.DeserializeObject(str); - return JsonConvert.SerializeObject(parsedJson, Formatting.Indented); - } - catch - { - // can't parse JSON, return the original string - return str; - } - } - - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Handling the failure by returning the original string.")] - private static string TryFormatXml(string str) - { - try - { - XDocument xml = XDocument.Parse(str); - return xml.ToString(); - } - catch - { - // can't parse XML, return the original string - return str; - } - } - - private static bool IsFormatSupported(SampleDirection sampleDirection, MediaTypeFormatter formatter, Type type) - { - switch (sampleDirection) - { - case SampleDirection.Request: - return formatter.CanReadType(type); - case SampleDirection.Response: - return formatter.CanWriteType(type); - } - return false; - } - - private IEnumerable> GetAllActionSamples(string controllerName, string actionName, IEnumerable parameterNames, SampleDirection sampleDirection) - { - HashSet parameterNamesSet = new HashSet(parameterNames, StringComparer.OrdinalIgnoreCase); - foreach (var sample in ActionSamples) - { - HelpPageSampleKey sampleKey = sample.Key; - if (String.Equals(controllerName, sampleKey.ControllerName, StringComparison.OrdinalIgnoreCase) && - String.Equals(actionName, sampleKey.ActionName, StringComparison.OrdinalIgnoreCase) && - (sampleKey.ParameterNames.SetEquals(new[] { "*" }) || parameterNamesSet.SetEquals(sampleKey.ParameterNames)) && - sampleDirection == sampleKey.SampleDirection) - { - yield return sample; - } - } - } - - private static object WrapSampleIfString(object sample) - { - string stringSample = sample as string; - if (stringSample != null) - { - return new TextSample(stringSample); - } - - return sample; - } - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/SampleGeneration/HelpPageSampleKey.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/SampleGeneration/HelpPageSampleKey.cs deleted file mode 100644 index c5cacf8..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/SampleGeneration/HelpPageSampleKey.cs +++ /dev/null @@ -1,172 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Net.Http.Headers; - -namespace AppBackend.Areas.HelpPage -{ - /// - /// This is used to identify the place where the sample should be applied. - /// - public class HelpPageSampleKey - { - /// - /// Creates a new based on media type. - /// - /// The media type. - public HelpPageSampleKey(MediaTypeHeaderValue mediaType) - { - if (mediaType == null) - { - throw new ArgumentNullException("mediaType"); - } - - ActionName = String.Empty; - ControllerName = String.Empty; - MediaType = mediaType; - ParameterNames = new HashSet(StringComparer.OrdinalIgnoreCase); - } - - /// - /// Creates a new based on media type and CLR type. - /// - /// The media type. - /// The CLR type. - public HelpPageSampleKey(MediaTypeHeaderValue mediaType, Type type) - : this(mediaType) - { - if (type == null) - { - throw new ArgumentNullException("type"); - } - - ParameterType = type; - } - - /// - /// Creates a new based on , controller name, action name and parameter names. - /// - /// The . - /// Name of the controller. - /// Name of the action. - /// The parameter names. - public HelpPageSampleKey(SampleDirection sampleDirection, string controllerName, string actionName, IEnumerable parameterNames) - { - if (!Enum.IsDefined(typeof(SampleDirection), sampleDirection)) - { - throw new InvalidEnumArgumentException("sampleDirection", (int)sampleDirection, typeof(SampleDirection)); - } - if (controllerName == null) - { - throw new ArgumentNullException("controllerName"); - } - if (actionName == null) - { - throw new ArgumentNullException("actionName"); - } - if (parameterNames == null) - { - throw new ArgumentNullException("parameterNames"); - } - - ControllerName = controllerName; - ActionName = actionName; - ParameterNames = new HashSet(parameterNames, StringComparer.OrdinalIgnoreCase); - SampleDirection = sampleDirection; - } - - /// - /// Creates a new based on media type, , controller name, action name and parameter names. - /// - /// The media type. - /// The . - /// Name of the controller. - /// Name of the action. - /// The parameter names. - public HelpPageSampleKey(MediaTypeHeaderValue mediaType, SampleDirection sampleDirection, string controllerName, string actionName, IEnumerable parameterNames) - : this(sampleDirection, controllerName, actionName, parameterNames) - { - if (mediaType == null) - { - throw new ArgumentNullException("mediaType"); - } - - MediaType = mediaType; - } - - /// - /// Gets the name of the controller. - /// - /// - /// The name of the controller. - /// - public string ControllerName { get; private set; } - - /// - /// Gets the name of the action. - /// - /// - /// The name of the action. - /// - public string ActionName { get; private set; } - - /// - /// Gets the media type. - /// - /// - /// The media type. - /// - public MediaTypeHeaderValue MediaType { get; private set; } - - /// - /// Gets the parameter names. - /// - public HashSet ParameterNames { get; private set; } - - public Type ParameterType { get; private set; } - - /// - /// Gets the . - /// - public SampleDirection? SampleDirection { get; private set; } - - public override bool Equals(object obj) - { - HelpPageSampleKey otherKey = obj as HelpPageSampleKey; - if (otherKey == null) - { - return false; - } - - return String.Equals(ControllerName, otherKey.ControllerName, StringComparison.OrdinalIgnoreCase) && - String.Equals(ActionName, otherKey.ActionName, StringComparison.OrdinalIgnoreCase) && - (MediaType == otherKey.MediaType || (MediaType != null && MediaType.Equals(otherKey.MediaType))) && - ParameterType == otherKey.ParameterType && - SampleDirection == otherKey.SampleDirection && - ParameterNames.SetEquals(otherKey.ParameterNames); - } - - public override int GetHashCode() - { - int hashCode = ControllerName.ToUpperInvariant().GetHashCode() ^ ActionName.ToUpperInvariant().GetHashCode(); - if (MediaType != null) - { - hashCode ^= MediaType.GetHashCode(); - } - if (SampleDirection != null) - { - hashCode ^= SampleDirection.GetHashCode(); - } - if (ParameterType != null) - { - hashCode ^= ParameterType.GetHashCode(); - } - foreach (string parameterName in ParameterNames) - { - hashCode ^= parameterName.ToUpperInvariant().GetHashCode(); - } - - return hashCode; - } - } -} diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/SampleGeneration/ImageSample.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/SampleGeneration/ImageSample.cs deleted file mode 100644 index 5bb718c..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/SampleGeneration/ImageSample.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; - -namespace AppBackend.Areas.HelpPage -{ - /// - /// This represents an image sample on the help page. There's a display template named ImageSample associated with this class. - /// - public class ImageSample - { - /// - /// Initializes a new instance of the class. - /// - /// The URL of an image. - public ImageSample(string src) - { - if (src == null) - { - throw new ArgumentNullException("src"); - } - Src = src; - } - - public string Src { get; private set; } - - public override bool Equals(object obj) - { - ImageSample other = obj as ImageSample; - return other != null && Src == other.Src; - } - - public override int GetHashCode() - { - return Src.GetHashCode(); - } - - public override string ToString() - { - return Src; - } - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/SampleGeneration/InvalidSample.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/SampleGeneration/InvalidSample.cs deleted file mode 100644 index 1bb283d..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/SampleGeneration/InvalidSample.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; - -namespace AppBackend.Areas.HelpPage -{ - /// - /// This represents an invalid sample on the help page. There's a display template named InvalidSample associated with this class. - /// - public class InvalidSample - { - public InvalidSample(string errorMessage) - { - if (errorMessage == null) - { - throw new ArgumentNullException("errorMessage"); - } - ErrorMessage = errorMessage; - } - - public string ErrorMessage { get; private set; } - - public override bool Equals(object obj) - { - InvalidSample other = obj as InvalidSample; - return other != null && ErrorMessage == other.ErrorMessage; - } - - public override int GetHashCode() - { - return ErrorMessage.GetHashCode(); - } - - public override string ToString() - { - return ErrorMessage; - } - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/SampleGeneration/ObjectGenerator.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/SampleGeneration/ObjectGenerator.cs deleted file mode 100644 index 970efd0..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/SampleGeneration/ObjectGenerator.cs +++ /dev/null @@ -1,456 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Linq; -using System.Reflection; - -namespace AppBackend.Areas.HelpPage -{ - /// - /// This class will create an object of a given type and populate it with sample data. - /// - public class ObjectGenerator - { - internal const int DefaultCollectionSize = 2; - private readonly SimpleTypeObjectGenerator SimpleObjectGenerator = new SimpleTypeObjectGenerator(); - - /// - /// Generates an object for a given type. The type needs to be public, have a public default constructor and settable public properties/fields. Currently it supports the following types: - /// Simple types: , , , , , etc. - /// Complex types: POCO types. - /// Nullables: . - /// Arrays: arrays of simple types or complex types. - /// Key value pairs: - /// Tuples: , , etc - /// Dictionaries: or anything deriving from . - /// Collections: , , , , , or anything deriving from or . - /// Queryables: , . - /// - /// The type. - /// An object of the given type. - public object GenerateObject(Type type) - { - return GenerateObject(type, new Dictionary()); - } - - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Here we just want to return null if anything goes wrong.")] - private object GenerateObject(Type type, Dictionary createdObjectReferences) - { - try - { - if (SimpleTypeObjectGenerator.CanGenerateObject(type)) - { - return SimpleObjectGenerator.GenerateObject(type); - } - - if (type.IsArray) - { - return GenerateArray(type, DefaultCollectionSize, createdObjectReferences); - } - - if (type.IsGenericType) - { - return GenerateGenericType(type, DefaultCollectionSize, createdObjectReferences); - } - - if (type == typeof(IDictionary)) - { - return GenerateDictionary(typeof(Hashtable), DefaultCollectionSize, createdObjectReferences); - } - - if (typeof(IDictionary).IsAssignableFrom(type)) - { - return GenerateDictionary(type, DefaultCollectionSize, createdObjectReferences); - } - - if (type == typeof(IList) || - type == typeof(IEnumerable) || - type == typeof(ICollection)) - { - return GenerateCollection(typeof(ArrayList), DefaultCollectionSize, createdObjectReferences); - } - - if (typeof(IList).IsAssignableFrom(type)) - { - return GenerateCollection(type, DefaultCollectionSize, createdObjectReferences); - } - - if (type == typeof(IQueryable)) - { - return GenerateQueryable(type, DefaultCollectionSize, createdObjectReferences); - } - - if (type.IsEnum) - { - return GenerateEnum(type); - } - - if (type.IsPublic || type.IsNestedPublic) - { - return GenerateComplexObject(type, createdObjectReferences); - } - } - catch - { - // Returns null if anything fails - return null; - } - - return null; - } - - private static object GenerateGenericType(Type type, int collectionSize, Dictionary createdObjectReferences) - { - Type genericTypeDefinition = type.GetGenericTypeDefinition(); - if (genericTypeDefinition == typeof(Nullable<>)) - { - return GenerateNullable(type, createdObjectReferences); - } - - if (genericTypeDefinition == typeof(KeyValuePair<,>)) - { - return GenerateKeyValuePair(type, createdObjectReferences); - } - - if (IsTuple(genericTypeDefinition)) - { - return GenerateTuple(type, createdObjectReferences); - } - - Type[] genericArguments = type.GetGenericArguments(); - if (genericArguments.Length == 1) - { - if (genericTypeDefinition == typeof(IList<>) || - genericTypeDefinition == typeof(IEnumerable<>) || - genericTypeDefinition == typeof(ICollection<>)) - { - Type collectionType = typeof(List<>).MakeGenericType(genericArguments); - return GenerateCollection(collectionType, collectionSize, createdObjectReferences); - } - - if (genericTypeDefinition == typeof(IQueryable<>)) - { - return GenerateQueryable(type, collectionSize, createdObjectReferences); - } - - Type closedCollectionType = typeof(ICollection<>).MakeGenericType(genericArguments[0]); - if (closedCollectionType.IsAssignableFrom(type)) - { - return GenerateCollection(type, collectionSize, createdObjectReferences); - } - } - - if (genericArguments.Length == 2) - { - if (genericTypeDefinition == typeof(IDictionary<,>)) - { - Type dictionaryType = typeof(Dictionary<,>).MakeGenericType(genericArguments); - return GenerateDictionary(dictionaryType, collectionSize, createdObjectReferences); - } - - Type closedDictionaryType = typeof(IDictionary<,>).MakeGenericType(genericArguments[0], genericArguments[1]); - if (closedDictionaryType.IsAssignableFrom(type)) - { - return GenerateDictionary(type, collectionSize, createdObjectReferences); - } - } - - if (type.IsPublic || type.IsNestedPublic) - { - return GenerateComplexObject(type, createdObjectReferences); - } - - return null; - } - - private static object GenerateTuple(Type type, Dictionary createdObjectReferences) - { - Type[] genericArgs = type.GetGenericArguments(); - object[] parameterValues = new object[genericArgs.Length]; - bool failedToCreateTuple = true; - ObjectGenerator objectGenerator = new ObjectGenerator(); - for (int i = 0; i < genericArgs.Length; i++) - { - parameterValues[i] = objectGenerator.GenerateObject(genericArgs[i], createdObjectReferences); - failedToCreateTuple &= parameterValues[i] == null; - } - if (failedToCreateTuple) - { - return null; - } - object result = Activator.CreateInstance(type, parameterValues); - return result; - } - - private static bool IsTuple(Type genericTypeDefinition) - { - return genericTypeDefinition == typeof(Tuple<>) || - genericTypeDefinition == typeof(Tuple<,>) || - genericTypeDefinition == typeof(Tuple<,,>) || - genericTypeDefinition == typeof(Tuple<,,,>) || - genericTypeDefinition == typeof(Tuple<,,,,>) || - genericTypeDefinition == typeof(Tuple<,,,,,>) || - genericTypeDefinition == typeof(Tuple<,,,,,,>) || - genericTypeDefinition == typeof(Tuple<,,,,,,,>); - } - - private static object GenerateKeyValuePair(Type keyValuePairType, Dictionary createdObjectReferences) - { - Type[] genericArgs = keyValuePairType.GetGenericArguments(); - Type typeK = genericArgs[0]; - Type typeV = genericArgs[1]; - ObjectGenerator objectGenerator = new ObjectGenerator(); - object keyObject = objectGenerator.GenerateObject(typeK, createdObjectReferences); - object valueObject = objectGenerator.GenerateObject(typeV, createdObjectReferences); - if (keyObject == null && valueObject == null) - { - // Failed to create key and values - return null; - } - object result = Activator.CreateInstance(keyValuePairType, keyObject, valueObject); - return result; - } - - private static object GenerateArray(Type arrayType, int size, Dictionary createdObjectReferences) - { - Type type = arrayType.GetElementType(); - Array result = Array.CreateInstance(type, size); - bool areAllElementsNull = true; - ObjectGenerator objectGenerator = new ObjectGenerator(); - for (int i = 0; i < size; i++) - { - object element = objectGenerator.GenerateObject(type, createdObjectReferences); - result.SetValue(element, i); - areAllElementsNull &= element == null; - } - - if (areAllElementsNull) - { - return null; - } - - return result; - } - - private static object GenerateDictionary(Type dictionaryType, int size, Dictionary createdObjectReferences) - { - Type typeK = typeof(object); - Type typeV = typeof(object); - if (dictionaryType.IsGenericType) - { - Type[] genericArgs = dictionaryType.GetGenericArguments(); - typeK = genericArgs[0]; - typeV = genericArgs[1]; - } - - object result = Activator.CreateInstance(dictionaryType); - MethodInfo addMethod = dictionaryType.GetMethod("Add") ?? dictionaryType.GetMethod("TryAdd"); - MethodInfo containsMethod = dictionaryType.GetMethod("Contains") ?? dictionaryType.GetMethod("ContainsKey"); - ObjectGenerator objectGenerator = new ObjectGenerator(); - for (int i = 0; i < size; i++) - { - object newKey = objectGenerator.GenerateObject(typeK, createdObjectReferences); - if (newKey == null) - { - // Cannot generate a valid key - return null; - } - - bool containsKey = (bool)containsMethod.Invoke(result, new object[] { newKey }); - if (!containsKey) - { - object newValue = objectGenerator.GenerateObject(typeV, createdObjectReferences); - addMethod.Invoke(result, new object[] { newKey, newValue }); - } - } - - return result; - } - - private static object GenerateEnum(Type enumType) - { - Array possibleValues = Enum.GetValues(enumType); - if (possibleValues.Length > 0) - { - return possibleValues.GetValue(0); - } - return null; - } - - private static object GenerateQueryable(Type queryableType, int size, Dictionary createdObjectReferences) - { - bool isGeneric = queryableType.IsGenericType; - object list; - if (isGeneric) - { - Type listType = typeof(List<>).MakeGenericType(queryableType.GetGenericArguments()); - list = GenerateCollection(listType, size, createdObjectReferences); - } - else - { - list = GenerateArray(typeof(object[]), size, createdObjectReferences); - } - if (list == null) - { - return null; - } - if (isGeneric) - { - Type argumentType = typeof(IEnumerable<>).MakeGenericType(queryableType.GetGenericArguments()); - MethodInfo asQueryableMethod = typeof(Queryable).GetMethod("AsQueryable", new[] { argumentType }); - return asQueryableMethod.Invoke(null, new[] { list }); - } - - return Queryable.AsQueryable((IEnumerable)list); - } - - private static object GenerateCollection(Type collectionType, int size, Dictionary createdObjectReferences) - { - Type type = collectionType.IsGenericType ? - collectionType.GetGenericArguments()[0] : - typeof(object); - object result = Activator.CreateInstance(collectionType); - MethodInfo addMethod = collectionType.GetMethod("Add"); - bool areAllElementsNull = true; - ObjectGenerator objectGenerator = new ObjectGenerator(); - for (int i = 0; i < size; i++) - { - object element = objectGenerator.GenerateObject(type, createdObjectReferences); - addMethod.Invoke(result, new object[] { element }); - areAllElementsNull &= element == null; - } - - if (areAllElementsNull) - { - return null; - } - - return result; - } - - private static object GenerateNullable(Type nullableType, Dictionary createdObjectReferences) - { - Type type = nullableType.GetGenericArguments()[0]; - ObjectGenerator objectGenerator = new ObjectGenerator(); - return objectGenerator.GenerateObject(type, createdObjectReferences); - } - - private static object GenerateComplexObject(Type type, Dictionary createdObjectReferences) - { - object result = null; - - if (createdObjectReferences.TryGetValue(type, out result)) - { - // The object has been created already, just return it. This will handle the circular reference case. - return result; - } - - if (type.IsValueType) - { - result = Activator.CreateInstance(type); - } - else - { - ConstructorInfo defaultCtor = type.GetConstructor(Type.EmptyTypes); - if (defaultCtor == null) - { - // Cannot instantiate the type because it doesn't have a default constructor - return null; - } - - result = defaultCtor.Invoke(new object[0]); - } - createdObjectReferences.Add(type, result); - SetPublicProperties(type, result, createdObjectReferences); - SetPublicFields(type, result, createdObjectReferences); - return result; - } - - private static void SetPublicProperties(Type type, object obj, Dictionary createdObjectReferences) - { - PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); - ObjectGenerator objectGenerator = new ObjectGenerator(); - foreach (PropertyInfo property in properties) - { - if (property.CanWrite) - { - object propertyValue = objectGenerator.GenerateObject(property.PropertyType, createdObjectReferences); - property.SetValue(obj, propertyValue, null); - } - } - } - - private static void SetPublicFields(Type type, object obj, Dictionary createdObjectReferences) - { - FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance); - ObjectGenerator objectGenerator = new ObjectGenerator(); - foreach (FieldInfo field in fields) - { - object fieldValue = objectGenerator.GenerateObject(field.FieldType, createdObjectReferences); - field.SetValue(obj, fieldValue); - } - } - - private class SimpleTypeObjectGenerator - { - private long _index = 0; - private static readonly Dictionary> DefaultGenerators = InitializeGenerators(); - - [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "These are simple type factories and cannot be split up.")] - private static Dictionary> InitializeGenerators() - { - return new Dictionary> - { - { typeof(Boolean), index => true }, - { typeof(Byte), index => (Byte)64 }, - { typeof(Char), index => (Char)65 }, - { typeof(DateTime), index => DateTime.Now }, - { typeof(DateTimeOffset), index => new DateTimeOffset(DateTime.Now) }, - { typeof(DBNull), index => DBNull.Value }, - { typeof(Decimal), index => (Decimal)index }, - { typeof(Double), index => (Double)(index + 0.1) }, - { typeof(Guid), index => Guid.NewGuid() }, - { typeof(Int16), index => (Int16)(index % Int16.MaxValue) }, - { typeof(Int32), index => (Int32)(index % Int32.MaxValue) }, - { typeof(Int64), index => (Int64)index }, - { typeof(Object), index => new object() }, - { typeof(SByte), index => (SByte)64 }, - { typeof(Single), index => (Single)(index + 0.1) }, - { - typeof(String), index => - { - return String.Format(CultureInfo.CurrentCulture, "sample string {0}", index); - } - }, - { - typeof(TimeSpan), index => - { - return TimeSpan.FromTicks(1234567); - } - }, - { typeof(UInt16), index => (UInt16)(index % UInt16.MaxValue) }, - { typeof(UInt32), index => (UInt32)(index % UInt32.MaxValue) }, - { typeof(UInt64), index => (UInt64)index }, - { - typeof(Uri), index => - { - return new Uri(String.Format(CultureInfo.CurrentCulture, "http://webapihelppage{0}.com", index)); - } - }, - }; - } - - public static bool CanGenerateObject(Type type) - { - return DefaultGenerators.ContainsKey(type); - } - - public object GenerateObject(Type type) - { - return DefaultGenerators[type](++_index); - } - } - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/SampleGeneration/SampleDirection.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/SampleGeneration/SampleDirection.cs deleted file mode 100644 index 3191a21..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/SampleGeneration/SampleDirection.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace AppBackend.Areas.HelpPage -{ - /// - /// Indicates whether the sample is used for request or response - /// - public enum SampleDirection - { - Request = 0, - Response - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/SampleGeneration/TextSample.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/SampleGeneration/TextSample.cs deleted file mode 100644 index 599d913..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/SampleGeneration/TextSample.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; - -namespace AppBackend.Areas.HelpPage -{ - /// - /// This represents a preformatted text sample on the help page. There's a display template named TextSample associated with this class. - /// - public class TextSample - { - public TextSample(string text) - { - if (text == null) - { - throw new ArgumentNullException("text"); - } - Text = text; - } - - public string Text { get; private set; } - - public override bool Equals(object obj) - { - TextSample other = obj as TextSample; - return other != null && Text == other.Text; - } - - public override int GetHashCode() - { - return Text.GetHashCode(); - } - - public override string ToString() - { - return Text; - } - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/Api.cshtml b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/Api.cshtml deleted file mode 100644 index 543ee37..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/Api.cshtml +++ /dev/null @@ -1,22 +0,0 @@ -@using System.Web.Http -@using AppBackend.Areas.HelpPage.Models -@model HelpPageApiModel - -@{ - var description = Model.ApiDescription; - ViewBag.Title = description.HttpMethod.Method + " " + description.RelativePath; -} - - -
- -
- @Html.DisplayForModel() -
-
diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/ApiGroup.cshtml b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/ApiGroup.cshtml deleted file mode 100644 index e1cebf3..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/ApiGroup.cshtml +++ /dev/null @@ -1,41 +0,0 @@ -@using System.Web.Http -@using System.Web.Http.Controllers -@using System.Web.Http.Description -@using AppBackend.Areas.HelpPage -@using AppBackend.Areas.HelpPage.Models -@model IGrouping - -@{ - var controllerDocumentation = ViewBag.DocumentationProvider != null ? - ViewBag.DocumentationProvider.GetDocumentation(Model.Key) : - null; -} - -

@Model.Key.ControllerName

-@if (!String.IsNullOrEmpty(controllerDocumentation)) -{ -

@controllerDocumentation

-} - - - - - - @foreach (var api in Model) - { - - - - - } - -
APIDescription
@api.HttpMethod.Method @api.RelativePath - @if (api.Documentation != null) - { -

@api.Documentation

- } - else - { -

No documentation available.

- } -
\ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/CollectionModelDescription.cshtml b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/CollectionModelDescription.cshtml deleted file mode 100644 index 09cacf2..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/CollectionModelDescription.cshtml +++ /dev/null @@ -1,6 +0,0 @@ -@using AppBackend.Areas.HelpPage.ModelDescriptions -@model CollectionModelDescription -@if (Model.ElementDescription is ComplexTypeModelDescription) -{ - @Html.DisplayFor(m => m.ElementDescription) -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/ComplexTypeModelDescription.cshtml b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/ComplexTypeModelDescription.cshtml deleted file mode 100644 index 4084dea..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/ComplexTypeModelDescription.cshtml +++ /dev/null @@ -1,3 +0,0 @@ -@using AppBackend.Areas.HelpPage.ModelDescriptions -@model ComplexTypeModelDescription -@Html.DisplayFor(m => m.Properties, "Parameters") \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/DictionaryModelDescription.cshtml b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/DictionaryModelDescription.cshtml deleted file mode 100644 index f0fbadf..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/DictionaryModelDescription.cshtml +++ /dev/null @@ -1,4 +0,0 @@ -@using AppBackend.Areas.HelpPage.ModelDescriptions -@model DictionaryModelDescription -Dictionary of @Html.DisplayFor(m => Model.KeyModelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.KeyModelDescription }) [key] -and @Html.DisplayFor(m => Model.ValueModelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.ValueModelDescription }) [value] \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/EnumTypeModelDescription.cshtml b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/EnumTypeModelDescription.cshtml deleted file mode 100644 index 181b696..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/EnumTypeModelDescription.cshtml +++ /dev/null @@ -1,24 +0,0 @@ -@using AppBackend.Areas.HelpPage.ModelDescriptions -@model EnumTypeModelDescription - -

Possible enumeration values:

- - - - - - - @foreach (EnumValueDescription value in Model.Values) - { - - - - - - } - -
NameValueDescription
@value.Name -

@value.Value

-
-

@value.Documentation

-
\ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/HelpPageApiModel.cshtml b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/HelpPageApiModel.cshtml deleted file mode 100644 index f445dd9..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/HelpPageApiModel.cshtml +++ /dev/null @@ -1,67 +0,0 @@ -@using System.Web.Http -@using System.Web.Http.Description -@using AppBackend.Areas.HelpPage.Models -@using AppBackend.Areas.HelpPage.ModelDescriptions -@model HelpPageApiModel - -@{ - ApiDescription description = Model.ApiDescription; -} -

@description.HttpMethod.Method @description.RelativePath

-
-

@description.Documentation

- -

Request Information

- -

URI Parameters

- @Html.DisplayFor(m => m.UriParameters, "Parameters") - -

Body Parameters

- -

@Model.RequestDocumentation

- - @if (Model.RequestModelDescription != null) - { - @Html.DisplayFor(m => m.RequestModelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.RequestModelDescription }) - if (Model.RequestBodyParameters != null) - { - @Html.DisplayFor(m => m.RequestBodyParameters, "Parameters") - } - } - else - { -

None.

- } - - @if (Model.SampleRequests.Count > 0) - { -

Request Formats

- @Html.DisplayFor(m => m.SampleRequests, "Samples") - } - -

Response Information

- -

Resource Description

- -

@description.ResponseDescription.Documentation

- - @if (Model.ResourceDescription != null) - { - @Html.DisplayFor(m => m.ResourceDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.ResourceDescription }) - if (Model.ResourceProperties != null) - { - @Html.DisplayFor(m => m.ResourceProperties, "Parameters") - } - } - else - { -

None.

- } - - @if (Model.SampleResponses.Count > 0) - { -

Response Formats

- @Html.DisplayFor(m => m.SampleResponses, "Samples") - } - -
\ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/ImageSample.cshtml b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/ImageSample.cshtml deleted file mode 100644 index 9c96546..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/ImageSample.cshtml +++ /dev/null @@ -1,4 +0,0 @@ -@using AppBackend.Areas.HelpPage -@model ImageSample - - \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/InvalidSample.cshtml b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/InvalidSample.cshtml deleted file mode 100644 index affcc23..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/InvalidSample.cshtml +++ /dev/null @@ -1,13 +0,0 @@ -@using AppBackend.Areas.HelpPage -@model InvalidSample - -@if (HttpContext.Current.IsDebuggingEnabled) -{ -
-

@Model.ErrorMessage

-
-} -else -{ -

Sample not available.

-} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/KeyValuePairModelDescription.cshtml b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/KeyValuePairModelDescription.cshtml deleted file mode 100644 index 4f97890..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/KeyValuePairModelDescription.cshtml +++ /dev/null @@ -1,4 +0,0 @@ -@using AppBackend.Areas.HelpPage.ModelDescriptions -@model KeyValuePairModelDescription -Pair of @Html.DisplayFor(m => Model.KeyModelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.KeyModelDescription }) [key] -and @Html.DisplayFor(m => Model.ValueModelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.ValueModelDescription }) [value] \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/ModelDescriptionLink.cshtml b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/ModelDescriptionLink.cshtml deleted file mode 100644 index 73c6008..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/ModelDescriptionLink.cshtml +++ /dev/null @@ -1,26 +0,0 @@ -@using AppBackend.Areas.HelpPage.ModelDescriptions -@model Type -@{ - ModelDescription modelDescription = ViewBag.modelDescription; - if (modelDescription is ComplexTypeModelDescription || modelDescription is EnumTypeModelDescription) - { - if (Model == typeof(Object)) - { - @:Object - } - else - { - @Html.ActionLink(modelDescription.Name, "ResourceModel", "Help", new { modelName = modelDescription.Name }, null) - } - } - else if (modelDescription is CollectionModelDescription) - { - var collectionDescription = modelDescription as CollectionModelDescription; - var elementDescription = collectionDescription.ElementDescription; - @:Collection of @Html.DisplayFor(m => elementDescription.ModelType, "ModelDescriptionLink", new { modelDescription = elementDescription }) - } - else - { - @Html.DisplayFor(m => modelDescription) - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/Parameters.cshtml b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/Parameters.cshtml deleted file mode 100644 index 4182260..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/Parameters.cshtml +++ /dev/null @@ -1,48 +0,0 @@ -@using System.Collections.Generic -@using System.Collections.ObjectModel -@using System.Web.Http.Description -@using System.Threading -@using AppBackend.Areas.HelpPage.ModelDescriptions -@model IList - -@if (Model.Count > 0) -{ - - - - - - @foreach (ParameterDescription parameter in Model) - { - ModelDescription modelDescription = parameter.TypeDescription; - - - - - - - } - -
NameDescriptionTypeAdditional information
@parameter.Name -

@parameter.Documentation

-
- @Html.DisplayFor(m => modelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = modelDescription }) - - @if (parameter.Annotations.Count > 0) - { - foreach (var annotation in parameter.Annotations) - { -

@annotation.Documentation

- } - } - else - { -

None.

- } -
-} -else -{ -

None.

-} - diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/Samples.cshtml b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/Samples.cshtml deleted file mode 100644 index c19596f..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/Samples.cshtml +++ /dev/null @@ -1,30 +0,0 @@ -@using System.Net.Http.Headers -@model Dictionary - -@{ - // Group the samples into a single tab if they are the same. - Dictionary samples = Model.GroupBy(pair => pair.Value).ToDictionary( - pair => String.Join(", ", pair.Select(m => m.Key.ToString()).ToArray()), - pair => pair.Key); - var mediaTypes = samples.Keys; -} -
- @foreach (var mediaType in mediaTypes) - { -

@mediaType

-
- Sample: - @{ - var sample = samples[mediaType]; - if (sample == null) - { -

Sample not available.

- } - else - { - @Html.DisplayFor(s => sample); - } - } -
- } -
\ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/SimpleTypeModelDescription.cshtml b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/SimpleTypeModelDescription.cshtml deleted file mode 100644 index 339660b..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/SimpleTypeModelDescription.cshtml +++ /dev/null @@ -1,3 +0,0 @@ -@using AppBackend.Areas.HelpPage.ModelDescriptions -@model SimpleTypeModelDescription -@Model.Documentation \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/TextSample.cshtml b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/TextSample.cshtml deleted file mode 100644 index 924b175..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/DisplayTemplates/TextSample.cshtml +++ /dev/null @@ -1,6 +0,0 @@ -@using AppBackend.Areas.HelpPage -@model TextSample - -
-@Model.Text
-
\ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/Index.cshtml b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/Index.cshtml deleted file mode 100644 index 427a4d8..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/Index.cshtml +++ /dev/null @@ -1,38 +0,0 @@ -@using System.Web.Http -@using System.Web.Http.Controllers -@using System.Web.Http.Description -@using System.Collections.ObjectModel -@using AppBackend.Areas.HelpPage.Models -@model Collection - -@{ - ViewBag.Title = "ASP.NET Web API Help Page"; - - // Group APIs by controller - ILookup apiGroups = Model.ToLookup(api => api.ActionDescriptor.ControllerDescriptor); -} - - -
-
-
-

@ViewBag.Title

-
-
-
-
- -
- @foreach (var group in apiGroups) - { - @Html.DisplayFor(m => group, "ApiGroup") - } -
-
diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/ResourceModel.cshtml b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/ResourceModel.cshtml deleted file mode 100644 index bc56d3f..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Help/ResourceModel.cshtml +++ /dev/null @@ -1,19 +0,0 @@ -@using System.Web.Http -@using AppBackend.Areas.HelpPage.ModelDescriptions -@model ModelDescription - - -
- -

@Model.Name

-

@Model.Documentation

-
- @Html.DisplayFor(m => Model) -
-
diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Shared/_Layout.cshtml b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Shared/_Layout.cshtml deleted file mode 100644 index 896c833..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Shared/_Layout.cshtml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - @ViewBag.Title - @RenderSection("scripts", required: false) - - - @RenderBody() - - \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Web.config b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Web.config deleted file mode 100644 index 0971732..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/Web.config +++ /dev/null @@ -1,41 +0,0 @@ - - - - - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/_ViewStart.cshtml b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/_ViewStart.cshtml deleted file mode 100644 index d735b1c..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/Views/_ViewStart.cshtml +++ /dev/null @@ -1,4 +0,0 @@ -@{ - // Change the Layout path below to blend the look and feel of the help page with your existing web pages - Layout = "~/Views/Shared/_Layout.cshtml"; -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/XmlDocumentationProvider.cs b/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/XmlDocumentationProvider.cs deleted file mode 100644 index 29f89d2..0000000 --- a/dotnet/NotifyUsers/AppBackend/Areas/HelpPage/XmlDocumentationProvider.cs +++ /dev/null @@ -1,161 +0,0 @@ -using System; -using System.Globalization; -using System.Linq; -using System.Reflection; -using System.Web.Http.Controllers; -using System.Web.Http.Description; -using System.Xml.XPath; -using AppBackend.Areas.HelpPage.ModelDescriptions; - -namespace AppBackend.Areas.HelpPage -{ - /// - /// A custom that reads the API documentation from an XML documentation file. - /// - public class XmlDocumentationProvider : IDocumentationProvider, IModelDocumentationProvider - { - private XPathNavigator _documentNavigator; - private const string TypeExpression = "/doc/members/member[@name='T:{0}']"; - private const string MethodExpression = "/doc/members/member[@name='M:{0}']"; - private const string PropertyExpression = "/doc/members/member[@name='P:{0}']"; - private const string FieldExpression = "/doc/members/member[@name='F:{0}']"; - private const string ParameterExpression = "param[@name='{0}']"; - - /// - /// Initializes a new instance of the class. - /// - /// The physical path to XML document. - public XmlDocumentationProvider(string documentPath) - { - if (documentPath == null) - { - throw new ArgumentNullException("documentPath"); - } - XPathDocument xpath = new XPathDocument(documentPath); - _documentNavigator = xpath.CreateNavigator(); - } - - public string GetDocumentation(HttpControllerDescriptor controllerDescriptor) - { - XPathNavigator typeNode = GetTypeNode(controllerDescriptor.ControllerType); - return GetTagValue(typeNode, "summary"); - } - - public virtual string GetDocumentation(HttpActionDescriptor actionDescriptor) - { - XPathNavigator methodNode = GetMethodNode(actionDescriptor); - return GetTagValue(methodNode, "summary"); - } - - public virtual string GetDocumentation(HttpParameterDescriptor parameterDescriptor) - { - ReflectedHttpParameterDescriptor reflectedParameterDescriptor = parameterDescriptor as ReflectedHttpParameterDescriptor; - if (reflectedParameterDescriptor != null) - { - XPathNavigator methodNode = GetMethodNode(reflectedParameterDescriptor.ActionDescriptor); - if (methodNode != null) - { - string parameterName = reflectedParameterDescriptor.ParameterInfo.Name; - XPathNavigator parameterNode = methodNode.SelectSingleNode(String.Format(CultureInfo.InvariantCulture, ParameterExpression, parameterName)); - if (parameterNode != null) - { - return parameterNode.Value.Trim(); - } - } - } - - return null; - } - - public string GetResponseDocumentation(HttpActionDescriptor actionDescriptor) - { - XPathNavigator methodNode = GetMethodNode(actionDescriptor); - return GetTagValue(methodNode, "returns"); - } - - public string GetDocumentation(MemberInfo member) - { - string memberName = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", GetTypeName(member.DeclaringType), member.Name); - string expression = member.MemberType == MemberTypes.Field ? FieldExpression : PropertyExpression; - string selectExpression = String.Format(CultureInfo.InvariantCulture, expression, memberName); - XPathNavigator propertyNode = _documentNavigator.SelectSingleNode(selectExpression); - return GetTagValue(propertyNode, "summary"); - } - - public string GetDocumentation(Type type) - { - XPathNavigator typeNode = GetTypeNode(type); - return GetTagValue(typeNode, "summary"); - } - - private XPathNavigator GetMethodNode(HttpActionDescriptor actionDescriptor) - { - ReflectedHttpActionDescriptor reflectedActionDescriptor = actionDescriptor as ReflectedHttpActionDescriptor; - if (reflectedActionDescriptor != null) - { - string selectExpression = String.Format(CultureInfo.InvariantCulture, MethodExpression, GetMemberName(reflectedActionDescriptor.MethodInfo)); - return _documentNavigator.SelectSingleNode(selectExpression); - } - - return null; - } - - private static string GetMemberName(MethodInfo method) - { - string name = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", GetTypeName(method.DeclaringType), method.Name); - ParameterInfo[] parameters = method.GetParameters(); - if (parameters.Length != 0) - { - string[] parameterTypeNames = parameters.Select(param => GetTypeName(param.ParameterType)).ToArray(); - name += String.Format(CultureInfo.InvariantCulture, "({0})", String.Join(",", parameterTypeNames)); - } - - return name; - } - - private static string GetTagValue(XPathNavigator parentNode, string tagName) - { - if (parentNode != null) - { - XPathNavigator node = parentNode.SelectSingleNode(tagName); - if (node != null) - { - return node.Value.Trim(); - } - } - - return null; - } - - private XPathNavigator GetTypeNode(Type type) - { - string controllerTypeName = GetTypeName(type); - string selectExpression = String.Format(CultureInfo.InvariantCulture, TypeExpression, controllerTypeName); - return _documentNavigator.SelectSingleNode(selectExpression); - } - - private static string GetTypeName(Type type) - { - string name = type.FullName; - if (type.IsGenericType) - { - // Format the generic type name to something like: Generic{System.Int32,System.String} - Type genericType = type.GetGenericTypeDefinition(); - Type[] genericArguments = type.GetGenericArguments(); - string genericTypeName = genericType.FullName; - - // Trim the generic parameter counts from the name - genericTypeName = genericTypeName.Substring(0, genericTypeName.IndexOf('`')); - string[] argumentTypeNames = genericArguments.Select(t => GetTypeName(t)).ToArray(); - name = String.Format(CultureInfo.InvariantCulture, "{0}{{{1}}}", genericTypeName, String.Join(",", argumentTypeNames)); - } - if (type.IsNested) - { - // Changing the nested type name from OuterType+InnerType to OuterType.InnerType to match the XML documentation syntax. - name = name.Replace("+", "."); - } - - return name; - } - } -} diff --git a/dotnet/NotifyUsers/AppBackend/AuthenticationTestHandler.cs b/dotnet/NotifyUsers/AppBackend/AuthenticationTestHandler.cs deleted file mode 100644 index e5a0b03..0000000 --- a/dotnet/NotifyUsers/AppBackend/AuthenticationTestHandler.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using System.Net.Http; -using System.Threading; -using System.Security.Principal; -using System.Net; -using System.Web; - - -namespace AppBackend -{ - public class AuthenticationTestHandler : DelegatingHandler - { - protected override Task SendAsync( - HttpRequestMessage request, CancellationToken cancellationToken) - { - var authorizationHeader = request.Headers.GetValues("Authorization").First(); - - if (authorizationHeader != null && authorizationHeader - .StartsWith("Basic ", StringComparison.InvariantCultureIgnoreCase)) - { - string authorizationUserAndPwdBase64 = - authorizationHeader.Substring("Basic ".Length); - string authorizationUserAndPwd = Encoding.Default - .GetString(Convert.FromBase64String(authorizationUserAndPwdBase64)); - string user = authorizationUserAndPwd.Split(':')[0]; - string password = authorizationUserAndPwd.Split(':')[1]; - - if (verifyUserAndPwd(user, password)) - { - // Attach the new principal object to the current HttpContext object - HttpContext.Current.User = - new GenericPrincipal(new GenericIdentity(user), new string[0]); - System.Threading.Thread.CurrentPrincipal = - System.Web.HttpContext.Current.User; - } - else return Unauthorized(); - } - else return Unauthorized(); - - return base.SendAsync(request, cancellationToken); - } - - private bool verifyUserAndPwd(string user, string password) - { - // This is not a real authentication scheme. - return user == password; - } - - private Task Unauthorized() - { - var response = new HttpResponseMessage(HttpStatusCode.Forbidden); - var tsc = new TaskCompletionSource(); - tsc.SetResult(response); - return tsc.Task; - } - } -} diff --git a/dotnet/NotifyUsers/AppBackend/Content/Site.css b/dotnet/NotifyUsers/AppBackend/Content/Site.css deleted file mode 100644 index d825a52..0000000 --- a/dotnet/NotifyUsers/AppBackend/Content/Site.css +++ /dev/null @@ -1,17 +0,0 @@ -body { - padding-top: 50px; - padding-bottom: 20px; -} - -/* Set padding to keep content from hitting the edges */ -.body-content { - padding-left: 15px; - padding-right: 15px; -} - -/* Set width on the form input elements since they're 100% wide by default */ -input, -select, -textarea { - max-width: 280px; -} diff --git a/dotnet/NotifyUsers/AppBackend/Content/bootstrap.css b/dotnet/NotifyUsers/AppBackend/Content/bootstrap.css deleted file mode 100644 index 6d6e682..0000000 --- a/dotnet/NotifyUsers/AppBackend/Content/bootstrap.css +++ /dev/null @@ -1,6816 +0,0 @@ -/* NUGET: BEGIN LICENSE TEXT - * - * Microsoft grants you the right to use these script files for the sole - * purpose of either: (i) interacting through your browser with the Microsoft - * website or online service, subject to the applicable licensing or use - * terms; or (ii) using the files as included with a Microsoft product subject - * to that product's license terms. Microsoft reserves all other rights to the - * files not expressly granted by Microsoft, whether by implication, estoppel - * or otherwise. The notices and licenses below are for informational purposes only. - * - * NUGET: END LICENSE TEXT */ -/*! - * Bootstrap v3.0.0 - * - * Copyright 2013 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world by @mdo and @fat. - */ - -/*! normalize.css v2.1.0 | MIT License | git.io/normalize */ - -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -main, -nav, -section, -summary { - display: block; -} - -audio, -canvas, -video { - display: inline-block; -} - -audio:not([controls]) { - display: none; - height: 0; -} - -[hidden] { - display: none; -} - -html { - font-family: sans-serif; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; -} - -body { - margin: 0; -} - -a:focus { - outline: thin dotted; -} - -a:active, -a:hover { - outline: 0; -} - -h1 { - margin: 0.67em 0; - font-size: 2em; -} - -abbr[title] { - border-bottom: 1px dotted; -} - -b, -strong { - font-weight: bold; -} - -dfn { - font-style: italic; -} - -hr { - height: 0; - -moz-box-sizing: content-box; - box-sizing: content-box; -} - -mark { - color: #000; - background: #ff0; -} - -code, -kbd, -pre, -samp { - font-family: monospace, serif; - font-size: 1em; -} - -pre { - white-space: pre-wrap; -} - -q { - quotes: "\201C" "\201D" "\2018" "\2019"; -} - -small { - font-size: 80%; -} - -sub, -sup { - position: relative; - font-size: 75%; - line-height: 0; - vertical-align: baseline; -} - -sup { - top: -0.5em; -} - -sub { - bottom: -0.25em; -} - -img { - border: 0; -} - -svg:not(:root) { - overflow: hidden; -} - -figure { - margin: 0; -} - -fieldset { - padding: 0.35em 0.625em 0.75em; - margin: 0 2px; - border: 1px solid #c0c0c0; -} - -legend { - padding: 0; - border: 0; -} - -button, -input, -select, -textarea { - margin: 0; - font-family: inherit; - font-size: 100%; -} - -button, -input { - line-height: normal; -} - -button, -select { - text-transform: none; -} - -button, -html input[type="button"], -input[type="reset"], -input[type="submit"] { - cursor: pointer; - -webkit-appearance: button; -} - -button[disabled], -html input[disabled] { - cursor: default; -} - -input[type="checkbox"], -input[type="radio"] { - padding: 0; - box-sizing: border-box; -} - -input[type="search"] { - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; - -webkit-appearance: textfield; -} - -input[type="search"]::-webkit-search-cancel-button, -input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} - -button::-moz-focus-inner, -input::-moz-focus-inner { - padding: 0; - border: 0; -} - -textarea { - overflow: auto; - vertical-align: top; -} - -table { - border-collapse: collapse; - border-spacing: 0; -} - -@media print { - * { - color: #000 !important; - text-shadow: none !important; - background: transparent !important; - box-shadow: none !important; - } - a, - a:visited { - text-decoration: underline; - } - a[href]:after { - content: " (" attr(href) ")"; - } - abbr[title]:after { - content: " (" attr(title) ")"; - } - .ir a:after, - a[href^="javascript:"]:after, - a[href^="#"]:after { - content: ""; - } - pre, - blockquote { - border: 1px solid #999; - page-break-inside: avoid; - } - thead { - display: table-header-group; - } - tr, - img { - page-break-inside: avoid; - } - img { - max-width: 100% !important; - } - @page { - margin: 2cm .5cm; - } - p, - h2, - h3 { - orphans: 3; - widows: 3; - } - h2, - h3 { - page-break-after: avoid; - } - .navbar { - display: none; - } - .table td, - .table th { - background-color: #fff !important; - } - .btn > .caret, - .dropup > .btn > .caret { - border-top-color: #000 !important; - } - .label { - border: 1px solid #000; - } - .table { - border-collapse: collapse !important; - } - .table-bordered th, - .table-bordered td { - border: 1px solid #ddd !important; - } -} - -*, -*:before, -*:after { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -html { - font-size: 62.5%; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); -} - -body { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 14px; - line-height: 1.428571429; - color: #333333; - background-color: #ffffff; -} - -input, -button, -select, -textarea { - font-family: inherit; - font-size: inherit; - line-height: inherit; -} - -button, -input, -select[multiple], -textarea { - background-image: none; -} - -a { - color: #428bca; - text-decoration: none; -} - -a:hover, -a:focus { - color: #2a6496; - text-decoration: underline; -} - -a:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} - -img { - vertical-align: middle; -} - -.img-responsive { - display: block; - height: auto; - max-width: 100%; -} - -.img-rounded { - border-radius: 6px; -} - -.img-thumbnail { - display: inline-block; - height: auto; - max-width: 100%; - padding: 4px; - line-height: 1.428571429; - background-color: #ffffff; - border: 1px solid #dddddd; - border-radius: 4px; - -webkit-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; -} - -.img-circle { - border-radius: 50%; -} - -hr { - margin-top: 20px; - margin-bottom: 20px; - border: 0; - border-top: 1px solid #eeeeee; -} - -.sr-only { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip: rect(0 0 0 0); - border: 0; -} - -p { - margin: 0 0 10px; -} - -.lead { - margin-bottom: 20px; - font-size: 16.099999999999998px; - font-weight: 200; - line-height: 1.4; -} - -@media (min-width: 768px) { - .lead { - font-size: 21px; - } -} - -small { - font-size: 85%; -} - -cite { - font-style: normal; -} - -.text-muted { - color: #999999; -} - -.text-primary { - color: #428bca; -} - -.text-warning { - color: #c09853; -} - -.text-danger { - color: #b94a48; -} - -.text-success { - color: #468847; -} - -.text-info { - color: #3a87ad; -} - -.text-left { - text-align: left; -} - -.text-right { - text-align: right; -} - -.text-center { - text-align: center; -} - -h1, -h2, -h3, -h4, -h5, -h6, -.h1, -.h2, -.h3, -.h4, -.h5, -.h6 { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-weight: 500; - line-height: 1.1; -} - -h1 small, -h2 small, -h3 small, -h4 small, -h5 small, -h6 small, -.h1 small, -.h2 small, -.h3 small, -.h4 small, -.h5 small, -.h6 small { - font-weight: normal; - line-height: 1; - color: #999999; -} - -h1, -h2, -h3 { - margin-top: 20px; - margin-bottom: 10px; -} - -h4, -h5, -h6 { - margin-top: 10px; - margin-bottom: 10px; -} - -h1, -.h1 { - font-size: 36px; -} - -h2, -.h2 { - font-size: 30px; -} - -h3, -.h3 { - font-size: 24px; -} - -h4, -.h4 { - font-size: 18px; -} - -h5, -.h5 { - font-size: 14px; -} - -h6, -.h6 { - font-size: 12px; -} - -h1 small, -.h1 small { - font-size: 24px; -} - -h2 small, -.h2 small { - font-size: 18px; -} - -h3 small, -.h3 small, -h4 small, -.h4 small { - font-size: 14px; -} - -.page-header { - padding-bottom: 9px; - margin: 40px 0 20px; - border-bottom: 1px solid #eeeeee; -} - -ul, -ol { - margin-top: 0; - margin-bottom: 10px; -} - -ul ul, -ol ul, -ul ol, -ol ol { - margin-bottom: 0; -} - -.list-unstyled { - padding-left: 0; - list-style: none; -} - -.list-inline { - padding-left: 0; - list-style: none; -} - -.list-inline > li { - display: inline-block; - padding-right: 5px; - padding-left: 5px; -} - -dl { - margin-bottom: 20px; -} - -dt, -dd { - line-height: 1.428571429; -} - -dt { - font-weight: bold; -} - -dd { - margin-left: 0; -} - -@media (min-width: 768px) { - .dl-horizontal dt { - float: left; - width: 160px; - overflow: hidden; - clear: left; - text-align: right; - text-overflow: ellipsis; - white-space: nowrap; - } - .dl-horizontal dd { - margin-left: 180px; - } - .dl-horizontal dd:before, - .dl-horizontal dd:after { - display: table; - content: " "; - } - .dl-horizontal dd:after { - clear: both; - } - .dl-horizontal dd:before, - .dl-horizontal dd:after { - display: table; - content: " "; - } - .dl-horizontal dd:after { - clear: both; - } -} - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; -} - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; -} - -blockquote { - padding: 10px 20px; - margin: 0 0 20px; - border-left: 5px solid #eeeeee; -} - -blockquote p { - font-size: 17.5px; - font-weight: 300; - line-height: 1.25; -} - -blockquote p:last-child { - margin-bottom: 0; -} - -blockquote small { - display: block; - line-height: 1.428571429; - color: #999999; -} - -blockquote small:before { - content: '\2014 \00A0'; -} - -blockquote.pull-right { - padding-right: 15px; - padding-left: 0; - border-right: 5px solid #eeeeee; - border-left: 0; -} - -blockquote.pull-right p, -blockquote.pull-right small { - text-align: right; -} - -blockquote.pull-right small:before { - content: ''; -} - -blockquote.pull-right small:after { - content: '\00A0 \2014'; -} - -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; -} - -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 1.428571429; -} - -code, -pre { - font-family: Monaco, Menlo, Consolas, "Courier New", monospace; -} - -code { - padding: 2px 4px; - font-size: 90%; - color: #c7254e; - white-space: nowrap; - background-color: #f9f2f4; - border-radius: 4px; -} - -pre { - display: block; - padding: 9.5px; - margin: 0 0 10px; - font-size: 13px; - line-height: 1.428571429; - color: #333333; - word-break: break-all; - word-wrap: break-word; - background-color: #f5f5f5; - border: 1px solid #cccccc; - border-radius: 4px; -} - -pre.prettyprint { - margin-bottom: 20px; -} - -pre code { - padding: 0; - font-size: inherit; - color: inherit; - white-space: pre-wrap; - background-color: transparent; - border: 0; -} - -.pre-scrollable { - max-height: 340px; - overflow-y: scroll; -} - -.container { - padding-right: 15px; - padding-left: 15px; - margin-right: auto; - margin-left: auto; -} - -.container:before, -.container:after { - display: table; - content: " "; -} - -.container:after { - clear: both; -} - -.container:before, -.container:after { - display: table; - content: " "; -} - -.container:after { - clear: both; -} - -.row { - margin-right: -15px; - margin-left: -15px; -} - -.row:before, -.row:after { - display: table; - content: " "; -} - -.row:after { - clear: both; -} - -.row:before, -.row:after { - display: table; - content: " "; -} - -.row:after { - clear: both; -} - -.col-xs-1, -.col-xs-2, -.col-xs-3, -.col-xs-4, -.col-xs-5, -.col-xs-6, -.col-xs-7, -.col-xs-8, -.col-xs-9, -.col-xs-10, -.col-xs-11, -.col-xs-12, -.col-sm-1, -.col-sm-2, -.col-sm-3, -.col-sm-4, -.col-sm-5, -.col-sm-6, -.col-sm-7, -.col-sm-8, -.col-sm-9, -.col-sm-10, -.col-sm-11, -.col-sm-12, -.col-md-1, -.col-md-2, -.col-md-3, -.col-md-4, -.col-md-5, -.col-md-6, -.col-md-7, -.col-md-8, -.col-md-9, -.col-md-10, -.col-md-11, -.col-md-12, -.col-lg-1, -.col-lg-2, -.col-lg-3, -.col-lg-4, -.col-lg-5, -.col-lg-6, -.col-lg-7, -.col-lg-8, -.col-lg-9, -.col-lg-10, -.col-lg-11, -.col-lg-12 { - position: relative; - min-height: 1px; - padding-right: 15px; - padding-left: 15px; -} - -.col-xs-1, -.col-xs-2, -.col-xs-3, -.col-xs-4, -.col-xs-5, -.col-xs-6, -.col-xs-7, -.col-xs-8, -.col-xs-9, -.col-xs-10, -.col-xs-11 { - float: left; -} - -.col-xs-1 { - width: 8.333333333333332%; -} - -.col-xs-2 { - width: 16.666666666666664%; -} - -.col-xs-3 { - width: 25%; -} - -.col-xs-4 { - width: 33.33333333333333%; -} - -.col-xs-5 { - width: 41.66666666666667%; -} - -.col-xs-6 { - width: 50%; -} - -.col-xs-7 { - width: 58.333333333333336%; -} - -.col-xs-8 { - width: 66.66666666666666%; -} - -.col-xs-9 { - width: 75%; -} - -.col-xs-10 { - width: 83.33333333333334%; -} - -.col-xs-11 { - width: 91.66666666666666%; -} - -.col-xs-12 { - width: 100%; -} - -@media (min-width: 768px) { - .container { - max-width: 750px; - } - .col-sm-1, - .col-sm-2, - .col-sm-3, - .col-sm-4, - .col-sm-5, - .col-sm-6, - .col-sm-7, - .col-sm-8, - .col-sm-9, - .col-sm-10, - .col-sm-11 { - float: left; - } - .col-sm-1 { - width: 8.333333333333332%; - } - .col-sm-2 { - width: 16.666666666666664%; - } - .col-sm-3 { - width: 25%; - } - .col-sm-4 { - width: 33.33333333333333%; - } - .col-sm-5 { - width: 41.66666666666667%; - } - .col-sm-6 { - width: 50%; - } - .col-sm-7 { - width: 58.333333333333336%; - } - .col-sm-8 { - width: 66.66666666666666%; - } - .col-sm-9 { - width: 75%; - } - .col-sm-10 { - width: 83.33333333333334%; - } - .col-sm-11 { - width: 91.66666666666666%; - } - .col-sm-12 { - width: 100%; - } - .col-sm-push-1 { - left: 8.333333333333332%; - } - .col-sm-push-2 { - left: 16.666666666666664%; - } - .col-sm-push-3 { - left: 25%; - } - .col-sm-push-4 { - left: 33.33333333333333%; - } - .col-sm-push-5 { - left: 41.66666666666667%; - } - .col-sm-push-6 { - left: 50%; - } - .col-sm-push-7 { - left: 58.333333333333336%; - } - .col-sm-push-8 { - left: 66.66666666666666%; - } - .col-sm-push-9 { - left: 75%; - } - .col-sm-push-10 { - left: 83.33333333333334%; - } - .col-sm-push-11 { - left: 91.66666666666666%; - } - .col-sm-pull-1 { - right: 8.333333333333332%; - } - .col-sm-pull-2 { - right: 16.666666666666664%; - } - .col-sm-pull-3 { - right: 25%; - } - .col-sm-pull-4 { - right: 33.33333333333333%; - } - .col-sm-pull-5 { - right: 41.66666666666667%; - } - .col-sm-pull-6 { - right: 50%; - } - .col-sm-pull-7 { - right: 58.333333333333336%; - } - .col-sm-pull-8 { - right: 66.66666666666666%; - } - .col-sm-pull-9 { - right: 75%; - } - .col-sm-pull-10 { - right: 83.33333333333334%; - } - .col-sm-pull-11 { - right: 91.66666666666666%; - } - .col-sm-offset-1 { - margin-left: 8.333333333333332%; - } - .col-sm-offset-2 { - margin-left: 16.666666666666664%; - } - .col-sm-offset-3 { - margin-left: 25%; - } - .col-sm-offset-4 { - margin-left: 33.33333333333333%; - } - .col-sm-offset-5 { - margin-left: 41.66666666666667%; - } - .col-sm-offset-6 { - margin-left: 50%; - } - .col-sm-offset-7 { - margin-left: 58.333333333333336%; - } - .col-sm-offset-8 { - margin-left: 66.66666666666666%; - } - .col-sm-offset-9 { - margin-left: 75%; - } - .col-sm-offset-10 { - margin-left: 83.33333333333334%; - } - .col-sm-offset-11 { - margin-left: 91.66666666666666%; - } -} - -@media (min-width: 992px) { - .container { - max-width: 970px; - } - .col-md-1, - .col-md-2, - .col-md-3, - .col-md-4, - .col-md-5, - .col-md-6, - .col-md-7, - .col-md-8, - .col-md-9, - .col-md-10, - .col-md-11 { - float: left; - } - .col-md-1 { - width: 8.333333333333332%; - } - .col-md-2 { - width: 16.666666666666664%; - } - .col-md-3 { - width: 25%; - } - .col-md-4 { - width: 33.33333333333333%; - } - .col-md-5 { - width: 41.66666666666667%; - } - .col-md-6 { - width: 50%; - } - .col-md-7 { - width: 58.333333333333336%; - } - .col-md-8 { - width: 66.66666666666666%; - } - .col-md-9 { - width: 75%; - } - .col-md-10 { - width: 83.33333333333334%; - } - .col-md-11 { - width: 91.66666666666666%; - } - .col-md-12 { - width: 100%; - } - .col-md-push-0 { - left: auto; - } - .col-md-push-1 { - left: 8.333333333333332%; - } - .col-md-push-2 { - left: 16.666666666666664%; - } - .col-md-push-3 { - left: 25%; - } - .col-md-push-4 { - left: 33.33333333333333%; - } - .col-md-push-5 { - left: 41.66666666666667%; - } - .col-md-push-6 { - left: 50%; - } - .col-md-push-7 { - left: 58.333333333333336%; - } - .col-md-push-8 { - left: 66.66666666666666%; - } - .col-md-push-9 { - left: 75%; - } - .col-md-push-10 { - left: 83.33333333333334%; - } - .col-md-push-11 { - left: 91.66666666666666%; - } - .col-md-pull-0 { - right: auto; - } - .col-md-pull-1 { - right: 8.333333333333332%; - } - .col-md-pull-2 { - right: 16.666666666666664%; - } - .col-md-pull-3 { - right: 25%; - } - .col-md-pull-4 { - right: 33.33333333333333%; - } - .col-md-pull-5 { - right: 41.66666666666667%; - } - .col-md-pull-6 { - right: 50%; - } - .col-md-pull-7 { - right: 58.333333333333336%; - } - .col-md-pull-8 { - right: 66.66666666666666%; - } - .col-md-pull-9 { - right: 75%; - } - .col-md-pull-10 { - right: 83.33333333333334%; - } - .col-md-pull-11 { - right: 91.66666666666666%; - } - .col-md-offset-0 { - margin-left: 0; - } - .col-md-offset-1 { - margin-left: 8.333333333333332%; - } - .col-md-offset-2 { - margin-left: 16.666666666666664%; - } - .col-md-offset-3 { - margin-left: 25%; - } - .col-md-offset-4 { - margin-left: 33.33333333333333%; - } - .col-md-offset-5 { - margin-left: 41.66666666666667%; - } - .col-md-offset-6 { - margin-left: 50%; - } - .col-md-offset-7 { - margin-left: 58.333333333333336%; - } - .col-md-offset-8 { - margin-left: 66.66666666666666%; - } - .col-md-offset-9 { - margin-left: 75%; - } - .col-md-offset-10 { - margin-left: 83.33333333333334%; - } - .col-md-offset-11 { - margin-left: 91.66666666666666%; - } -} - -@media (min-width: 1200px) { - .container { - max-width: 1170px; - } - .col-lg-1, - .col-lg-2, - .col-lg-3, - .col-lg-4, - .col-lg-5, - .col-lg-6, - .col-lg-7, - .col-lg-8, - .col-lg-9, - .col-lg-10, - .col-lg-11 { - float: left; - } - .col-lg-1 { - width: 8.333333333333332%; - } - .col-lg-2 { - width: 16.666666666666664%; - } - .col-lg-3 { - width: 25%; - } - .col-lg-4 { - width: 33.33333333333333%; - } - .col-lg-5 { - width: 41.66666666666667%; - } - .col-lg-6 { - width: 50%; - } - .col-lg-7 { - width: 58.333333333333336%; - } - .col-lg-8 { - width: 66.66666666666666%; - } - .col-lg-9 { - width: 75%; - } - .col-lg-10 { - width: 83.33333333333334%; - } - .col-lg-11 { - width: 91.66666666666666%; - } - .col-lg-12 { - width: 100%; - } - .col-lg-push-0 { - left: auto; - } - .col-lg-push-1 { - left: 8.333333333333332%; - } - .col-lg-push-2 { - left: 16.666666666666664%; - } - .col-lg-push-3 { - left: 25%; - } - .col-lg-push-4 { - left: 33.33333333333333%; - } - .col-lg-push-5 { - left: 41.66666666666667%; - } - .col-lg-push-6 { - left: 50%; - } - .col-lg-push-7 { - left: 58.333333333333336%; - } - .col-lg-push-8 { - left: 66.66666666666666%; - } - .col-lg-push-9 { - left: 75%; - } - .col-lg-push-10 { - left: 83.33333333333334%; - } - .col-lg-push-11 { - left: 91.66666666666666%; - } - .col-lg-pull-0 { - right: auto; - } - .col-lg-pull-1 { - right: 8.333333333333332%; - } - .col-lg-pull-2 { - right: 16.666666666666664%; - } - .col-lg-pull-3 { - right: 25%; - } - .col-lg-pull-4 { - right: 33.33333333333333%; - } - .col-lg-pull-5 { - right: 41.66666666666667%; - } - .col-lg-pull-6 { - right: 50%; - } - .col-lg-pull-7 { - right: 58.333333333333336%; - } - .col-lg-pull-8 { - right: 66.66666666666666%; - } - .col-lg-pull-9 { - right: 75%; - } - .col-lg-pull-10 { - right: 83.33333333333334%; - } - .col-lg-pull-11 { - right: 91.66666666666666%; - } - .col-lg-offset-0 { - margin-left: 0; - } - .col-lg-offset-1 { - margin-left: 8.333333333333332%; - } - .col-lg-offset-2 { - margin-left: 16.666666666666664%; - } - .col-lg-offset-3 { - margin-left: 25%; - } - .col-lg-offset-4 { - margin-left: 33.33333333333333%; - } - .col-lg-offset-5 { - margin-left: 41.66666666666667%; - } - .col-lg-offset-6 { - margin-left: 50%; - } - .col-lg-offset-7 { - margin-left: 58.333333333333336%; - } - .col-lg-offset-8 { - margin-left: 66.66666666666666%; - } - .col-lg-offset-9 { - margin-left: 75%; - } - .col-lg-offset-10 { - margin-left: 83.33333333333334%; - } - .col-lg-offset-11 { - margin-left: 91.66666666666666%; - } -} - -table { - max-width: 100%; - background-color: transparent; -} - -th { - text-align: left; -} - -.table { - width: 100%; - margin-bottom: 20px; -} - -.table thead > tr > th, -.table tbody > tr > th, -.table tfoot > tr > th, -.table thead > tr > td, -.table tbody > tr > td, -.table tfoot > tr > td { - padding: 8px; - line-height: 1.428571429; - vertical-align: top; - border-top: 1px solid #dddddd; -} - -.table thead > tr > th { - vertical-align: bottom; - border-bottom: 2px solid #dddddd; -} - -.table caption + thead tr:first-child th, -.table colgroup + thead tr:first-child th, -.table thead:first-child tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child td { - border-top: 0; -} - -.table tbody + tbody { - border-top: 2px solid #dddddd; -} - -.table .table { - background-color: #ffffff; -} - -.table-condensed thead > tr > th, -.table-condensed tbody > tr > th, -.table-condensed tfoot > tr > th, -.table-condensed thead > tr > td, -.table-condensed tbody > tr > td, -.table-condensed tfoot > tr > td { - padding: 5px; -} - -.table-bordered { - border: 1px solid #dddddd; -} - -.table-bordered > thead > tr > th, -.table-bordered > tbody > tr > th, -.table-bordered > tfoot > tr > th, -.table-bordered > thead > tr > td, -.table-bordered > tbody > tr > td, -.table-bordered > tfoot > tr > td { - border: 1px solid #dddddd; -} - -.table-bordered > thead > tr > th, -.table-bordered > thead > tr > td { - border-bottom-width: 2px; -} - -.table-striped > tbody > tr:nth-child(odd) > td, -.table-striped > tbody > tr:nth-child(odd) > th { - background-color: #f9f9f9; -} - -.table-hover > tbody > tr:hover > td, -.table-hover > tbody > tr:hover > th { - background-color: #f5f5f5; -} - -table col[class*="col-"] { - display: table-column; - float: none; -} - -table td[class*="col-"], -table th[class*="col-"] { - display: table-cell; - float: none; -} - -.table > thead > tr > td.active, -.table > tbody > tr > td.active, -.table > tfoot > tr > td.active, -.table > thead > tr > th.active, -.table > tbody > tr > th.active, -.table > tfoot > tr > th.active, -.table > thead > tr.active > td, -.table > tbody > tr.active > td, -.table > tfoot > tr.active > td, -.table > thead > tr.active > th, -.table > tbody > tr.active > th, -.table > tfoot > tr.active > th { - background-color: #f5f5f5; -} - -.table > thead > tr > td.success, -.table > tbody > tr > td.success, -.table > tfoot > tr > td.success, -.table > thead > tr > th.success, -.table > tbody > tr > th.success, -.table > tfoot > tr > th.success, -.table > thead > tr.success > td, -.table > tbody > tr.success > td, -.table > tfoot > tr.success > td, -.table > thead > tr.success > th, -.table > tbody > tr.success > th, -.table > tfoot > tr.success > th { - background-color: #dff0d8; - border-color: #d6e9c6; -} - -.table-hover > tbody > tr > td.success:hover, -.table-hover > tbody > tr > th.success:hover, -.table-hover > tbody > tr.success:hover > td { - background-color: #d0e9c6; - border-color: #c9e2b3; -} - -.table > thead > tr > td.danger, -.table > tbody > tr > td.danger, -.table > tfoot > tr > td.danger, -.table > thead > tr > th.danger, -.table > tbody > tr > th.danger, -.table > tfoot > tr > th.danger, -.table > thead > tr.danger > td, -.table > tbody > tr.danger > td, -.table > tfoot > tr.danger > td, -.table > thead > tr.danger > th, -.table > tbody > tr.danger > th, -.table > tfoot > tr.danger > th { - background-color: #f2dede; - border-color: #eed3d7; -} - -.table-hover > tbody > tr > td.danger:hover, -.table-hover > tbody > tr > th.danger:hover, -.table-hover > tbody > tr.danger:hover > td { - background-color: #ebcccc; - border-color: #e6c1c7; -} - -.table > thead > tr > td.warning, -.table > tbody > tr > td.warning, -.table > tfoot > tr > td.warning, -.table > thead > tr > th.warning, -.table > tbody > tr > th.warning, -.table > tfoot > tr > th.warning, -.table > thead > tr.warning > td, -.table > tbody > tr.warning > td, -.table > tfoot > tr.warning > td, -.table > thead > tr.warning > th, -.table > tbody > tr.warning > th, -.table > tfoot > tr.warning > th { - background-color: #fcf8e3; - border-color: #fbeed5; -} - -.table-hover > tbody > tr > td.warning:hover, -.table-hover > tbody > tr > th.warning:hover, -.table-hover > tbody > tr.warning:hover > td { - background-color: #faf2cc; - border-color: #f8e5be; -} - -@media (max-width: 768px) { - .table-responsive { - width: 100%; - margin-bottom: 15px; - overflow-x: scroll; - overflow-y: hidden; - border: 1px solid #dddddd; - } - .table-responsive > .table { - margin-bottom: 0; - background-color: #fff; - } - .table-responsive > .table > thead > tr > th, - .table-responsive > .table > tbody > tr > th, - .table-responsive > .table > tfoot > tr > th, - .table-responsive > .table > thead > tr > td, - .table-responsive > .table > tbody > tr > td, - .table-responsive > .table > tfoot > tr > td { - white-space: nowrap; - } - .table-responsive > .table-bordered { - border: 0; - } - .table-responsive > .table-bordered > thead > tr > th:first-child, - .table-responsive > .table-bordered > tbody > tr > th:first-child, - .table-responsive > .table-bordered > tfoot > tr > th:first-child, - .table-responsive > .table-bordered > thead > tr > td:first-child, - .table-responsive > .table-bordered > tbody > tr > td:first-child, - .table-responsive > .table-bordered > tfoot > tr > td:first-child { - border-left: 0; - } - .table-responsive > .table-bordered > thead > tr > th:last-child, - .table-responsive > .table-bordered > tbody > tr > th:last-child, - .table-responsive > .table-bordered > tfoot > tr > th:last-child, - .table-responsive > .table-bordered > thead > tr > td:last-child, - .table-responsive > .table-bordered > tbody > tr > td:last-child, - .table-responsive > .table-bordered > tfoot > tr > td:last-child { - border-right: 0; - } - .table-responsive > .table-bordered > thead > tr:last-child > th, - .table-responsive > .table-bordered > tbody > tr:last-child > th, - .table-responsive > .table-bordered > tfoot > tr:last-child > th, - .table-responsive > .table-bordered > thead > tr:last-child > td, - .table-responsive > .table-bordered > tbody > tr:last-child > td, - .table-responsive > .table-bordered > tfoot > tr:last-child > td { - border-bottom: 0; - } -} - -fieldset { - padding: 0; - margin: 0; - border: 0; -} - -legend { - display: block; - width: 100%; - padding: 0; - margin-bottom: 20px; - font-size: 21px; - line-height: inherit; - color: #333333; - border: 0; - border-bottom: 1px solid #e5e5e5; -} - -label { - display: inline-block; - margin-bottom: 5px; - font-weight: bold; -} - -input[type="search"] { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -input[type="radio"], -input[type="checkbox"] { - margin: 4px 0 0; - margin-top: 1px \9; - /* IE8-9 */ - - line-height: normal; -} - -input[type="file"] { - display: block; -} - -select[multiple], -select[size] { - height: auto; -} - -select optgroup { - font-family: inherit; - font-size: inherit; - font-style: inherit; -} - -input[type="file"]:focus, -input[type="radio"]:focus, -input[type="checkbox"]:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} - -input[type="number"]::-webkit-outer-spin-button, -input[type="number"]::-webkit-inner-spin-button { - height: auto; -} - -.form-control:-moz-placeholder { - color: #999999; -} - -.form-control::-moz-placeholder { - color: #999999; -} - -.form-control:-ms-input-placeholder { - color: #999999; -} - -.form-control::-webkit-input-placeholder { - color: #999999; -} - -.form-control { - display: block; - width: 100%; - height: 34px; - padding: 6px 12px; - font-size: 14px; - line-height: 1.428571429; - color: #555555; - vertical-align: middle; - background-color: #ffffff; - border: 1px solid #cccccc; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; - transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; -} - -.form-control:focus { - border-color: #66afe9; - outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); -} - -.form-control[disabled], -.form-control[readonly], -fieldset[disabled] .form-control { - cursor: not-allowed; - background-color: #eeeeee; -} - -textarea.form-control { - height: auto; -} - -.form-group { - margin-bottom: 15px; -} - -.radio, -.checkbox { - display: block; - min-height: 20px; - padding-left: 20px; - margin-top: 10px; - margin-bottom: 10px; - vertical-align: middle; -} - -.radio label, -.checkbox label { - display: inline; - margin-bottom: 0; - font-weight: normal; - cursor: pointer; -} - -.radio input[type="radio"], -.radio-inline input[type="radio"], -.checkbox input[type="checkbox"], -.checkbox-inline input[type="checkbox"] { - float: left; - margin-left: -20px; -} - -.radio + .radio, -.checkbox + .checkbox { - margin-top: -5px; -} - -.radio-inline, -.checkbox-inline { - display: inline-block; - padding-left: 20px; - margin-bottom: 0; - font-weight: normal; - vertical-align: middle; - cursor: pointer; -} - -.radio-inline + .radio-inline, -.checkbox-inline + .checkbox-inline { - margin-top: 0; - margin-left: 10px; -} - -input[type="radio"][disabled], -input[type="checkbox"][disabled], -.radio[disabled], -.radio-inline[disabled], -.checkbox[disabled], -.checkbox-inline[disabled], -fieldset[disabled] input[type="radio"], -fieldset[disabled] input[type="checkbox"], -fieldset[disabled] .radio, -fieldset[disabled] .radio-inline, -fieldset[disabled] .checkbox, -fieldset[disabled] .checkbox-inline { - cursor: not-allowed; -} - -.input-sm { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} - -select.input-sm { - height: 30px; - line-height: 30px; -} - -textarea.input-sm { - height: auto; -} - -.input-lg { - height: 45px; - padding: 10px 16px; - font-size: 18px; - line-height: 1.33; - border-radius: 6px; -} - -select.input-lg { - height: 45px; - line-height: 45px; -} - -textarea.input-lg { - height: auto; -} - -.has-warning .help-block, -.has-warning .control-label { - color: #c09853; -} - -.has-warning .form-control { - border-color: #c09853; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} - -.has-warning .form-control:focus { - border-color: #a47e3c; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; -} - -.has-warning .input-group-addon { - color: #c09853; - background-color: #fcf8e3; - border-color: #c09853; -} - -.has-error .help-block, -.has-error .control-label { - color: #b94a48; -} - -.has-error .form-control { - border-color: #b94a48; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} - -.has-error .form-control:focus { - border-color: #953b39; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; -} - -.has-error .input-group-addon { - color: #b94a48; - background-color: #f2dede; - border-color: #b94a48; -} - -.has-success .help-block, -.has-success .control-label { - color: #468847; -} - -.has-success .form-control { - border-color: #468847; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} - -.has-success .form-control:focus { - border-color: #356635; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; -} - -.has-success .input-group-addon { - color: #468847; - background-color: #dff0d8; - border-color: #468847; -} - -.form-control-static { - padding-top: 7px; - margin-bottom: 0; -} - -.help-block { - display: block; - margin-top: 5px; - margin-bottom: 10px; - color: #737373; -} - -@media (min-width: 768px) { - .form-inline .form-group { - display: inline-block; - margin-bottom: 0; - vertical-align: middle; - } - .form-inline .form-control { - display: inline-block; - } - .form-inline .radio, - .form-inline .checkbox { - display: inline-block; - padding-left: 0; - margin-top: 0; - margin-bottom: 0; - } - .form-inline .radio input[type="radio"], - .form-inline .checkbox input[type="checkbox"] { - float: none; - margin-left: 0; - } -} - -.form-horizontal .control-label, -.form-horizontal .radio, -.form-horizontal .checkbox, -.form-horizontal .radio-inline, -.form-horizontal .checkbox-inline { - padding-top: 7px; - margin-top: 0; - margin-bottom: 0; -} - -.form-horizontal .form-group { - margin-right: -15px; - margin-left: -15px; -} - -.form-horizontal .form-group:before, -.form-horizontal .form-group:after { - display: table; - content: " "; -} - -.form-horizontal .form-group:after { - clear: both; -} - -.form-horizontal .form-group:before, -.form-horizontal .form-group:after { - display: table; - content: " "; -} - -.form-horizontal .form-group:after { - clear: both; -} - -@media (min-width: 768px) { - .form-horizontal .control-label { - text-align: right; - } -} - -.btn { - display: inline-block; - padding: 6px 12px; - margin-bottom: 0; - font-size: 14px; - font-weight: normal; - line-height: 1.428571429; - text-align: center; - white-space: nowrap; - vertical-align: middle; - cursor: pointer; - border: 1px solid transparent; - border-radius: 4px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - -o-user-select: none; - user-select: none; -} - -.btn:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} - -.btn:hover, -.btn:focus { - color: #333333; - text-decoration: none; -} - -.btn:active, -.btn.active { - background-image: none; - outline: 0; - -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); -} - -.btn.disabled, -.btn[disabled], -fieldset[disabled] .btn { - pointer-events: none; - cursor: not-allowed; - opacity: 0.65; - filter: alpha(opacity=65); - -webkit-box-shadow: none; - box-shadow: none; -} - -.btn-default { - color: #333333; - background-color: #ffffff; - border-color: #cccccc; -} - -.btn-default:hover, -.btn-default:focus, -.btn-default:active, -.btn-default.active, -.open .dropdown-toggle.btn-default { - color: #333333; - background-color: #ebebeb; - border-color: #adadad; -} - -.btn-default:active, -.btn-default.active, -.open .dropdown-toggle.btn-default { - background-image: none; -} - -.btn-default.disabled, -.btn-default[disabled], -fieldset[disabled] .btn-default, -.btn-default.disabled:hover, -.btn-default[disabled]:hover, -fieldset[disabled] .btn-default:hover, -.btn-default.disabled:focus, -.btn-default[disabled]:focus, -fieldset[disabled] .btn-default:focus, -.btn-default.disabled:active, -.btn-default[disabled]:active, -fieldset[disabled] .btn-default:active, -.btn-default.disabled.active, -.btn-default[disabled].active, -fieldset[disabled] .btn-default.active { - background-color: #ffffff; - border-color: #cccccc; -} - -.btn-primary { - color: #ffffff; - background-color: #428bca; - border-color: #357ebd; -} - -.btn-primary:hover, -.btn-primary:focus, -.btn-primary:active, -.btn-primary.active, -.open .dropdown-toggle.btn-primary { - color: #ffffff; - background-color: #3276b1; - border-color: #285e8e; -} - -.btn-primary:active, -.btn-primary.active, -.open .dropdown-toggle.btn-primary { - background-image: none; -} - -.btn-primary.disabled, -.btn-primary[disabled], -fieldset[disabled] .btn-primary, -.btn-primary.disabled:hover, -.btn-primary[disabled]:hover, -fieldset[disabled] .btn-primary:hover, -.btn-primary.disabled:focus, -.btn-primary[disabled]:focus, -fieldset[disabled] .btn-primary:focus, -.btn-primary.disabled:active, -.btn-primary[disabled]:active, -fieldset[disabled] .btn-primary:active, -.btn-primary.disabled.active, -.btn-primary[disabled].active, -fieldset[disabled] .btn-primary.active { - background-color: #428bca; - border-color: #357ebd; -} - -.btn-warning { - color: #ffffff; - background-color: #f0ad4e; - border-color: #eea236; -} - -.btn-warning:hover, -.btn-warning:focus, -.btn-warning:active, -.btn-warning.active, -.open .dropdown-toggle.btn-warning { - color: #ffffff; - background-color: #ed9c28; - border-color: #d58512; -} - -.btn-warning:active, -.btn-warning.active, -.open .dropdown-toggle.btn-warning { - background-image: none; -} - -.btn-warning.disabled, -.btn-warning[disabled], -fieldset[disabled] .btn-warning, -.btn-warning.disabled:hover, -.btn-warning[disabled]:hover, -fieldset[disabled] .btn-warning:hover, -.btn-warning.disabled:focus, -.btn-warning[disabled]:focus, -fieldset[disabled] .btn-warning:focus, -.btn-warning.disabled:active, -.btn-warning[disabled]:active, -fieldset[disabled] .btn-warning:active, -.btn-warning.disabled.active, -.btn-warning[disabled].active, -fieldset[disabled] .btn-warning.active { - background-color: #f0ad4e; - border-color: #eea236; -} - -.btn-danger { - color: #ffffff; - background-color: #d9534f; - border-color: #d43f3a; -} - -.btn-danger:hover, -.btn-danger:focus, -.btn-danger:active, -.btn-danger.active, -.open .dropdown-toggle.btn-danger { - color: #ffffff; - background-color: #d2322d; - border-color: #ac2925; -} - -.btn-danger:active, -.btn-danger.active, -.open .dropdown-toggle.btn-danger { - background-image: none; -} - -.btn-danger.disabled, -.btn-danger[disabled], -fieldset[disabled] .btn-danger, -.btn-danger.disabled:hover, -.btn-danger[disabled]:hover, -fieldset[disabled] .btn-danger:hover, -.btn-danger.disabled:focus, -.btn-danger[disabled]:focus, -fieldset[disabled] .btn-danger:focus, -.btn-danger.disabled:active, -.btn-danger[disabled]:active, -fieldset[disabled] .btn-danger:active, -.btn-danger.disabled.active, -.btn-danger[disabled].active, -fieldset[disabled] .btn-danger.active { - background-color: #d9534f; - border-color: #d43f3a; -} - -.btn-success { - color: #ffffff; - background-color: #5cb85c; - border-color: #4cae4c; -} - -.btn-success:hover, -.btn-success:focus, -.btn-success:active, -.btn-success.active, -.open .dropdown-toggle.btn-success { - color: #ffffff; - background-color: #47a447; - border-color: #398439; -} - -.btn-success:active, -.btn-success.active, -.open .dropdown-toggle.btn-success { - background-image: none; -} - -.btn-success.disabled, -.btn-success[disabled], -fieldset[disabled] .btn-success, -.btn-success.disabled:hover, -.btn-success[disabled]:hover, -fieldset[disabled] .btn-success:hover, -.btn-success.disabled:focus, -.btn-success[disabled]:focus, -fieldset[disabled] .btn-success:focus, -.btn-success.disabled:active, -.btn-success[disabled]:active, -fieldset[disabled] .btn-success:active, -.btn-success.disabled.active, -.btn-success[disabled].active, -fieldset[disabled] .btn-success.active { - background-color: #5cb85c; - border-color: #4cae4c; -} - -.btn-info { - color: #ffffff; - background-color: #5bc0de; - border-color: #46b8da; -} - -.btn-info:hover, -.btn-info:focus, -.btn-info:active, -.btn-info.active, -.open .dropdown-toggle.btn-info { - color: #ffffff; - background-color: #39b3d7; - border-color: #269abc; -} - -.btn-info:active, -.btn-info.active, -.open .dropdown-toggle.btn-info { - background-image: none; -} - -.btn-info.disabled, -.btn-info[disabled], -fieldset[disabled] .btn-info, -.btn-info.disabled:hover, -.btn-info[disabled]:hover, -fieldset[disabled] .btn-info:hover, -.btn-info.disabled:focus, -.btn-info[disabled]:focus, -fieldset[disabled] .btn-info:focus, -.btn-info.disabled:active, -.btn-info[disabled]:active, -fieldset[disabled] .btn-info:active, -.btn-info.disabled.active, -.btn-info[disabled].active, -fieldset[disabled] .btn-info.active { - background-color: #5bc0de; - border-color: #46b8da; -} - -.btn-link { - font-weight: normal; - color: #428bca; - cursor: pointer; - border-radius: 0; -} - -.btn-link, -.btn-link:active, -.btn-link[disabled], -fieldset[disabled] .btn-link { - background-color: transparent; - -webkit-box-shadow: none; - box-shadow: none; -} - -.btn-link, -.btn-link:hover, -.btn-link:focus, -.btn-link:active { - border-color: transparent; -} - -.btn-link:hover, -.btn-link:focus { - color: #2a6496; - text-decoration: underline; - background-color: transparent; -} - -.btn-link[disabled]:hover, -fieldset[disabled] .btn-link:hover, -.btn-link[disabled]:focus, -fieldset[disabled] .btn-link:focus { - color: #999999; - text-decoration: none; -} - -.btn-lg { - padding: 10px 16px; - font-size: 18px; - line-height: 1.33; - border-radius: 6px; -} - -.btn-sm, -.btn-xs { - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} - -.btn-xs { - padding: 1px 5px; -} - -.btn-block { - display: block; - width: 100%; - padding-right: 0; - padding-left: 0; -} - -.btn-block + .btn-block { - margin-top: 5px; -} - -input[type="submit"].btn-block, -input[type="reset"].btn-block, -input[type="button"].btn-block { - width: 100%; -} - -.fade { - opacity: 0; - -webkit-transition: opacity 0.15s linear; - transition: opacity 0.15s linear; -} - -.fade.in { - opacity: 1; -} - -.collapse { - display: none; -} - -.collapse.in { - display: block; -} - -.collapsing { - position: relative; - height: 0; - overflow: hidden; - -webkit-transition: height 0.35s ease; - transition: height 0.35s ease; -} - -@font-face { - font-family: 'Glyphicons Halflings'; - src: url('../fonts/glyphicons-halflings-regular.eot'); - src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular') format('svg'); -} - -.glyphicon { - position: relative; - top: 1px; - display: inline-block; - font-family: 'Glyphicons Halflings'; - -webkit-font-smoothing: antialiased; - font-style: normal; - font-weight: normal; - line-height: 1; -} - -.glyphicon-asterisk:before { - content: "\2a"; -} - -.glyphicon-plus:before { - content: "\2b"; -} - -.glyphicon-euro:before { - content: "\20ac"; -} - -.glyphicon-minus:before { - content: "\2212"; -} - -.glyphicon-cloud:before { - content: "\2601"; -} - -.glyphicon-envelope:before { - content: "\2709"; -} - -.glyphicon-pencil:before { - content: "\270f"; -} - -.glyphicon-glass:before { - content: "\e001"; -} - -.glyphicon-music:before { - content: "\e002"; -} - -.glyphicon-search:before { - content: "\e003"; -} - -.glyphicon-heart:before { - content: "\e005"; -} - -.glyphicon-star:before { - content: "\e006"; -} - -.glyphicon-star-empty:before { - content: "\e007"; -} - -.glyphicon-user:before { - content: "\e008"; -} - -.glyphicon-film:before { - content: "\e009"; -} - -.glyphicon-th-large:before { - content: "\e010"; -} - -.glyphicon-th:before { - content: "\e011"; -} - -.glyphicon-th-list:before { - content: "\e012"; -} - -.glyphicon-ok:before { - content: "\e013"; -} - -.glyphicon-remove:before { - content: "\e014"; -} - -.glyphicon-zoom-in:before { - content: "\e015"; -} - -.glyphicon-zoom-out:before { - content: "\e016"; -} - -.glyphicon-off:before { - content: "\e017"; -} - -.glyphicon-signal:before { - content: "\e018"; -} - -.glyphicon-cog:before { - content: "\e019"; -} - -.glyphicon-trash:before { - content: "\e020"; -} - -.glyphicon-home:before { - content: "\e021"; -} - -.glyphicon-file:before { - content: "\e022"; -} - -.glyphicon-time:before { - content: "\e023"; -} - -.glyphicon-road:before { - content: "\e024"; -} - -.glyphicon-download-alt:before { - content: "\e025"; -} - -.glyphicon-download:before { - content: "\e026"; -} - -.glyphicon-upload:before { - content: "\e027"; -} - -.glyphicon-inbox:before { - content: "\e028"; -} - -.glyphicon-play-circle:before { - content: "\e029"; -} - -.glyphicon-repeat:before { - content: "\e030"; -} - -.glyphicon-refresh:before { - content: "\e031"; -} - -.glyphicon-list-alt:before { - content: "\e032"; -} - -.glyphicon-flag:before { - content: "\e034"; -} - -.glyphicon-headphones:before { - content: "\e035"; -} - -.glyphicon-volume-off:before { - content: "\e036"; -} - -.glyphicon-volume-down:before { - content: "\e037"; -} - -.glyphicon-volume-up:before { - content: "\e038"; -} - -.glyphicon-qrcode:before { - content: "\e039"; -} - -.glyphicon-barcode:before { - content: "\e040"; -} - -.glyphicon-tag:before { - content: "\e041"; -} - -.glyphicon-tags:before { - content: "\e042"; -} - -.glyphicon-book:before { - content: "\e043"; -} - -.glyphicon-print:before { - content: "\e045"; -} - -.glyphicon-font:before { - content: "\e047"; -} - -.glyphicon-bold:before { - content: "\e048"; -} - -.glyphicon-italic:before { - content: "\e049"; -} - -.glyphicon-text-height:before { - content: "\e050"; -} - -.glyphicon-text-width:before { - content: "\e051"; -} - -.glyphicon-align-left:before { - content: "\e052"; -} - -.glyphicon-align-center:before { - content: "\e053"; -} - -.glyphicon-align-right:before { - content: "\e054"; -} - -.glyphicon-align-justify:before { - content: "\e055"; -} - -.glyphicon-list:before { - content: "\e056"; -} - -.glyphicon-indent-left:before { - content: "\e057"; -} - -.glyphicon-indent-right:before { - content: "\e058"; -} - -.glyphicon-facetime-video:before { - content: "\e059"; -} - -.glyphicon-picture:before { - content: "\e060"; -} - -.glyphicon-map-marker:before { - content: "\e062"; -} - -.glyphicon-adjust:before { - content: "\e063"; -} - -.glyphicon-tint:before { - content: "\e064"; -} - -.glyphicon-edit:before { - content: "\e065"; -} - -.glyphicon-share:before { - content: "\e066"; -} - -.glyphicon-check:before { - content: "\e067"; -} - -.glyphicon-move:before { - content: "\e068"; -} - -.glyphicon-step-backward:before { - content: "\e069"; -} - -.glyphicon-fast-backward:before { - content: "\e070"; -} - -.glyphicon-backward:before { - content: "\e071"; -} - -.glyphicon-play:before { - content: "\e072"; -} - -.glyphicon-pause:before { - content: "\e073"; -} - -.glyphicon-stop:before { - content: "\e074"; -} - -.glyphicon-forward:before { - content: "\e075"; -} - -.glyphicon-fast-forward:before { - content: "\e076"; -} - -.glyphicon-step-forward:before { - content: "\e077"; -} - -.glyphicon-eject:before { - content: "\e078"; -} - -.glyphicon-chevron-left:before { - content: "\e079"; -} - -.glyphicon-chevron-right:before { - content: "\e080"; -} - -.glyphicon-plus-sign:before { - content: "\e081"; -} - -.glyphicon-minus-sign:before { - content: "\e082"; -} - -.glyphicon-remove-sign:before { - content: "\e083"; -} - -.glyphicon-ok-sign:before { - content: "\e084"; -} - -.glyphicon-question-sign:before { - content: "\e085"; -} - -.glyphicon-info-sign:before { - content: "\e086"; -} - -.glyphicon-screenshot:before { - content: "\e087"; -} - -.glyphicon-remove-circle:before { - content: "\e088"; -} - -.glyphicon-ok-circle:before { - content: "\e089"; -} - -.glyphicon-ban-circle:before { - content: "\e090"; -} - -.glyphicon-arrow-left:before { - content: "\e091"; -} - -.glyphicon-arrow-right:before { - content: "\e092"; -} - -.glyphicon-arrow-up:before { - content: "\e093"; -} - -.glyphicon-arrow-down:before { - content: "\e094"; -} - -.glyphicon-share-alt:before { - content: "\e095"; -} - -.glyphicon-resize-full:before { - content: "\e096"; -} - -.glyphicon-resize-small:before { - content: "\e097"; -} - -.glyphicon-exclamation-sign:before { - content: "\e101"; -} - -.glyphicon-gift:before { - content: "\e102"; -} - -.glyphicon-leaf:before { - content: "\e103"; -} - -.glyphicon-eye-open:before { - content: "\e105"; -} - -.glyphicon-eye-close:before { - content: "\e106"; -} - -.glyphicon-warning-sign:before { - content: "\e107"; -} - -.glyphicon-plane:before { - content: "\e108"; -} - -.glyphicon-random:before { - content: "\e110"; -} - -.glyphicon-comment:before { - content: "\e111"; -} - -.glyphicon-magnet:before { - content: "\e112"; -} - -.glyphicon-chevron-up:before { - content: "\e113"; -} - -.glyphicon-chevron-down:before { - content: "\e114"; -} - -.glyphicon-retweet:before { - content: "\e115"; -} - -.glyphicon-shopping-cart:before { - content: "\e116"; -} - -.glyphicon-folder-close:before { - content: "\e117"; -} - -.glyphicon-folder-open:before { - content: "\e118"; -} - -.glyphicon-resize-vertical:before { - content: "\e119"; -} - -.glyphicon-resize-horizontal:before { - content: "\e120"; -} - -.glyphicon-hdd:before { - content: "\e121"; -} - -.glyphicon-bullhorn:before { - content: "\e122"; -} - -.glyphicon-certificate:before { - content: "\e124"; -} - -.glyphicon-thumbs-up:before { - content: "\e125"; -} - -.glyphicon-thumbs-down:before { - content: "\e126"; -} - -.glyphicon-hand-right:before { - content: "\e127"; -} - -.glyphicon-hand-left:before { - content: "\e128"; -} - -.glyphicon-hand-up:before { - content: "\e129"; -} - -.glyphicon-hand-down:before { - content: "\e130"; -} - -.glyphicon-circle-arrow-right:before { - content: "\e131"; -} - -.glyphicon-circle-arrow-left:before { - content: "\e132"; -} - -.glyphicon-circle-arrow-up:before { - content: "\e133"; -} - -.glyphicon-circle-arrow-down:before { - content: "\e134"; -} - -.glyphicon-globe:before { - content: "\e135"; -} - -.glyphicon-tasks:before { - content: "\e137"; -} - -.glyphicon-filter:before { - content: "\e138"; -} - -.glyphicon-fullscreen:before { - content: "\e140"; -} - -.glyphicon-dashboard:before { - content: "\e141"; -} - -.glyphicon-heart-empty:before { - content: "\e143"; -} - -.glyphicon-link:before { - content: "\e144"; -} - -.glyphicon-phone:before { - content: "\e145"; -} - -.glyphicon-usd:before { - content: "\e148"; -} - -.glyphicon-gbp:before { - content: "\e149"; -} - -.glyphicon-sort:before { - content: "\e150"; -} - -.glyphicon-sort-by-alphabet:before { - content: "\e151"; -} - -.glyphicon-sort-by-alphabet-alt:before { - content: "\e152"; -} - -.glyphicon-sort-by-order:before { - content: "\e153"; -} - -.glyphicon-sort-by-order-alt:before { - content: "\e154"; -} - -.glyphicon-sort-by-attributes:before { - content: "\e155"; -} - -.glyphicon-sort-by-attributes-alt:before { - content: "\e156"; -} - -.glyphicon-unchecked:before { - content: "\e157"; -} - -.glyphicon-expand:before { - content: "\e158"; -} - -.glyphicon-collapse-down:before { - content: "\e159"; -} - -.glyphicon-collapse-up:before { - content: "\e160"; -} - -.glyphicon-log-in:before { - content: "\e161"; -} - -.glyphicon-flash:before { - content: "\e162"; -} - -.glyphicon-log-out:before { - content: "\e163"; -} - -.glyphicon-new-window:before { - content: "\e164"; -} - -.glyphicon-record:before { - content: "\e165"; -} - -.glyphicon-save:before { - content: "\e166"; -} - -.glyphicon-open:before { - content: "\e167"; -} - -.glyphicon-saved:before { - content: "\e168"; -} - -.glyphicon-import:before { - content: "\e169"; -} - -.glyphicon-export:before { - content: "\e170"; -} - -.glyphicon-send:before { - content: "\e171"; -} - -.glyphicon-floppy-disk:before { - content: "\e172"; -} - -.glyphicon-floppy-saved:before { - content: "\e173"; -} - -.glyphicon-floppy-remove:before { - content: "\e174"; -} - -.glyphicon-floppy-save:before { - content: "\e175"; -} - -.glyphicon-floppy-open:before { - content: "\e176"; -} - -.glyphicon-credit-card:before { - content: "\e177"; -} - -.glyphicon-transfer:before { - content: "\e178"; -} - -.glyphicon-cutlery:before { - content: "\e179"; -} - -.glyphicon-header:before { - content: "\e180"; -} - -.glyphicon-compressed:before { - content: "\e181"; -} - -.glyphicon-earphone:before { - content: "\e182"; -} - -.glyphicon-phone-alt:before { - content: "\e183"; -} - -.glyphicon-tower:before { - content: "\e184"; -} - -.glyphicon-stats:before { - content: "\e185"; -} - -.glyphicon-sd-video:before { - content: "\e186"; -} - -.glyphicon-hd-video:before { - content: "\e187"; -} - -.glyphicon-subtitles:before { - content: "\e188"; -} - -.glyphicon-sound-stereo:before { - content: "\e189"; -} - -.glyphicon-sound-dolby:before { - content: "\e190"; -} - -.glyphicon-sound-5-1:before { - content: "\e191"; -} - -.glyphicon-sound-6-1:before { - content: "\e192"; -} - -.glyphicon-sound-7-1:before { - content: "\e193"; -} - -.glyphicon-copyright-mark:before { - content: "\e194"; -} - -.glyphicon-registration-mark:before { - content: "\e195"; -} - -.glyphicon-cloud-download:before { - content: "\e197"; -} - -.glyphicon-cloud-upload:before { - content: "\e198"; -} - -.glyphicon-tree-conifer:before { - content: "\e199"; -} - -.glyphicon-tree-deciduous:before { - content: "\e200"; -} - -.glyphicon-briefcase:before { - content: "\1f4bc"; -} - -.glyphicon-calendar:before { - content: "\1f4c5"; -} - -.glyphicon-pushpin:before { - content: "\1f4cc"; -} - -.glyphicon-paperclip:before { - content: "\1f4ce"; -} - -.glyphicon-camera:before { - content: "\1f4f7"; -} - -.glyphicon-lock:before { - content: "\1f512"; -} - -.glyphicon-bell:before { - content: "\1f514"; -} - -.glyphicon-bookmark:before { - content: "\1f516"; -} - -.glyphicon-fire:before { - content: "\1f525"; -} - -.glyphicon-wrench:before { - content: "\1f527"; -} - -.caret { - display: inline-block; - width: 0; - height: 0; - margin-left: 2px; - vertical-align: middle; - border-top: 4px solid #000000; - border-right: 4px solid transparent; - border-bottom: 0 dotted; - border-left: 4px solid transparent; - content: ""; -} - -.dropdown { - position: relative; -} - -.dropdown-toggle:focus { - outline: 0; -} - -.dropdown-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - display: none; - float: left; - min-width: 160px; - padding: 5px 0; - margin: 2px 0 0; - font-size: 14px; - list-style: none; - background-color: #ffffff; - border: 1px solid #cccccc; - border: 1px solid rgba(0, 0, 0, 0.15); - border-radius: 4px; - -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - background-clip: padding-box; -} - -.dropdown-menu.pull-right { - right: 0; - left: auto; -} - -.dropdown-menu .divider { - height: 1px; - margin: 9px 0; - overflow: hidden; - background-color: #e5e5e5; -} - -.dropdown-menu > li > a { - display: block; - padding: 3px 20px; - clear: both; - font-weight: normal; - line-height: 1.428571429; - color: #333333; - white-space: nowrap; -} - -.dropdown-menu > li > a:hover, -.dropdown-menu > li > a:focus { - color: #ffffff; - text-decoration: none; - background-color: #428bca; -} - -.dropdown-menu > .active > a, -.dropdown-menu > .active > a:hover, -.dropdown-menu > .active > a:focus { - color: #ffffff; - text-decoration: none; - background-color: #428bca; - outline: 0; -} - -.dropdown-menu > .disabled > a, -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - color: #999999; -} - -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - text-decoration: none; - cursor: not-allowed; - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -} - -.open > .dropdown-menu { - display: block; -} - -.open > a { - outline: 0; -} - -.dropdown-header { - display: block; - padding: 3px 20px; - font-size: 12px; - line-height: 1.428571429; - color: #999999; -} - -.dropdown-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 990; -} - -.pull-right > .dropdown-menu { - right: 0; - left: auto; -} - -.dropup .caret, -.navbar-fixed-bottom .dropdown .caret { - border-top: 0 dotted; - border-bottom: 4px solid #000000; - content: ""; -} - -.dropup .dropdown-menu, -.navbar-fixed-bottom .dropdown .dropdown-menu { - top: auto; - bottom: 100%; - margin-bottom: 1px; -} - -@media (min-width: 768px) { - .navbar-right .dropdown-menu { - right: 0; - left: auto; - } -} - -.btn-default .caret { - border-top-color: #333333; -} - -.btn-primary .caret, -.btn-success .caret, -.btn-warning .caret, -.btn-danger .caret, -.btn-info .caret { - border-top-color: #fff; -} - -.dropup .btn-default .caret { - border-bottom-color: #333333; -} - -.dropup .btn-primary .caret, -.dropup .btn-success .caret, -.dropup .btn-warning .caret, -.dropup .btn-danger .caret, -.dropup .btn-info .caret { - border-bottom-color: #fff; -} - -.btn-group, -.btn-group-vertical { - position: relative; - display: inline-block; - vertical-align: middle; -} - -.btn-group > .btn, -.btn-group-vertical > .btn { - position: relative; - float: left; -} - -.btn-group > .btn:hover, -.btn-group-vertical > .btn:hover, -.btn-group > .btn:focus, -.btn-group-vertical > .btn:focus, -.btn-group > .btn:active, -.btn-group-vertical > .btn:active, -.btn-group > .btn.active, -.btn-group-vertical > .btn.active { - z-index: 2; -} - -.btn-group > .btn:focus, -.btn-group-vertical > .btn:focus { - outline: none; -} - -.btn-group .btn + .btn, -.btn-group .btn + .btn-group, -.btn-group .btn-group + .btn, -.btn-group .btn-group + .btn-group { - margin-left: -1px; -} - -.btn-toolbar:before, -.btn-toolbar:after { - display: table; - content: " "; -} - -.btn-toolbar:after { - clear: both; -} - -.btn-toolbar:before, -.btn-toolbar:after { - display: table; - content: " "; -} - -.btn-toolbar:after { - clear: both; -} - -.btn-toolbar .btn-group { - float: left; -} - -.btn-toolbar > .btn + .btn, -.btn-toolbar > .btn-group + .btn, -.btn-toolbar > .btn + .btn-group, -.btn-toolbar > .btn-group + .btn-group { - margin-left: 5px; -} - -.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { - border-radius: 0; -} - -.btn-group > .btn:first-child { - margin-left: 0; -} - -.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { - border-top-right-radius: 0; - border-bottom-right-radius: 0; -} - -.btn-group > .btn:last-child:not(:first-child), -.btn-group > .dropdown-toggle:not(:first-child) { - border-bottom-left-radius: 0; - border-top-left-radius: 0; -} - -.btn-group > .btn-group { - float: left; -} - -.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { - border-radius: 0; -} - -.btn-group > .btn-group:first-child > .btn:last-child, -.btn-group > .btn-group:first-child > .dropdown-toggle { - border-top-right-radius: 0; - border-bottom-right-radius: 0; -} - -.btn-group > .btn-group:last-child > .btn:first-child { - border-bottom-left-radius: 0; - border-top-left-radius: 0; -} - -.btn-group .dropdown-toggle:active, -.btn-group.open .dropdown-toggle { - outline: 0; -} - -.btn-group-xs > .btn { - padding: 5px 10px; - padding: 1px 5px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} - -.btn-group-sm > .btn { - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} - -.btn-group-lg > .btn { - padding: 10px 16px; - font-size: 18px; - line-height: 1.33; - border-radius: 6px; -} - -.btn-group > .btn + .dropdown-toggle { - padding-right: 8px; - padding-left: 8px; -} - -.btn-group > .btn-lg + .dropdown-toggle { - padding-right: 12px; - padding-left: 12px; -} - -.btn-group.open .dropdown-toggle { - -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); -} - -.btn .caret { - margin-left: 0; -} - -.btn-lg .caret { - border-width: 5px 5px 0; - border-bottom-width: 0; -} - -.dropup .btn-lg .caret { - border-width: 0 5px 5px; -} - -.btn-group-vertical > .btn, -.btn-group-vertical > .btn-group { - display: block; - float: none; - width: 100%; - max-width: 100%; -} - -.btn-group-vertical > .btn-group:before, -.btn-group-vertical > .btn-group:after { - display: table; - content: " "; -} - -.btn-group-vertical > .btn-group:after { - clear: both; -} - -.btn-group-vertical > .btn-group:before, -.btn-group-vertical > .btn-group:after { - display: table; - content: " "; -} - -.btn-group-vertical > .btn-group:after { - clear: both; -} - -.btn-group-vertical > .btn-group > .btn { - float: none; -} - -.btn-group-vertical > .btn + .btn, -.btn-group-vertical > .btn + .btn-group, -.btn-group-vertical > .btn-group + .btn, -.btn-group-vertical > .btn-group + .btn-group { - margin-top: -1px; - margin-left: 0; -} - -.btn-group-vertical > .btn:not(:first-child):not(:last-child) { - border-radius: 0; -} - -.btn-group-vertical > .btn:first-child:not(:last-child) { - border-top-right-radius: 4px; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} - -.btn-group-vertical > .btn:last-child:not(:first-child) { - border-top-right-radius: 0; - border-bottom-left-radius: 4px; - border-top-left-radius: 0; -} - -.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { - border-radius: 0; -} - -.btn-group-vertical > .btn-group:first-child > .btn:last-child, -.btn-group-vertical > .btn-group:first-child > .dropdown-toggle { - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} - -.btn-group-vertical > .btn-group:last-child > .btn:first-child { - border-top-right-radius: 0; - border-top-left-radius: 0; -} - -.btn-group-justified { - display: table; - width: 100%; - border-collapse: separate; - table-layout: fixed; -} - -.btn-group-justified .btn { - display: table-cell; - float: none; - width: 1%; -} - -[data-toggle="buttons"] > .btn > input[type="radio"], -[data-toggle="buttons"] > .btn > input[type="checkbox"] { - display: none; -} - -.input-group { - position: relative; - display: table; - border-collapse: separate; -} - -.input-group.col { - float: none; - padding-right: 0; - padding-left: 0; -} - -.input-group .form-control { - width: 100%; - margin-bottom: 0; -} - -.input-group-lg > .form-control, -.input-group-lg > .input-group-addon, -.input-group-lg > .input-group-btn > .btn { - height: 45px; - padding: 10px 16px; - font-size: 18px; - line-height: 1.33; - border-radius: 6px; -} - -select.input-group-lg > .form-control, -select.input-group-lg > .input-group-addon, -select.input-group-lg > .input-group-btn > .btn { - height: 45px; - line-height: 45px; -} - -textarea.input-group-lg > .form-control, -textarea.input-group-lg > .input-group-addon, -textarea.input-group-lg > .input-group-btn > .btn { - height: auto; -} - -.input-group-sm > .form-control, -.input-group-sm > .input-group-addon, -.input-group-sm > .input-group-btn > .btn { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} - -select.input-group-sm > .form-control, -select.input-group-sm > .input-group-addon, -select.input-group-sm > .input-group-btn > .btn { - height: 30px; - line-height: 30px; -} - -textarea.input-group-sm > .form-control, -textarea.input-group-sm > .input-group-addon, -textarea.input-group-sm > .input-group-btn > .btn { - height: auto; -} - -.input-group-addon, -.input-group-btn, -.input-group .form-control { - display: table-cell; -} - -.input-group-addon:not(:first-child):not(:last-child), -.input-group-btn:not(:first-child):not(:last-child), -.input-group .form-control:not(:first-child):not(:last-child) { - border-radius: 0; -} - -.input-group-addon, -.input-group-btn { - width: 1%; - white-space: nowrap; - vertical-align: middle; -} - -.input-group-addon { - padding: 6px 12px; - font-size: 14px; - font-weight: normal; - line-height: 1; - text-align: center; - background-color: #eeeeee; - border: 1px solid #cccccc; - border-radius: 4px; -} - -.input-group-addon.input-sm { - padding: 5px 10px; - font-size: 12px; - border-radius: 3px; -} - -.input-group-addon.input-lg { - padding: 10px 16px; - font-size: 18px; - border-radius: 6px; -} - -.input-group-addon input[type="radio"], -.input-group-addon input[type="checkbox"] { - margin-top: 0; -} - -.input-group .form-control:first-child, -.input-group-addon:first-child, -.input-group-btn:first-child > .btn, -.input-group-btn:first-child > .dropdown-toggle, -.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle) { - border-top-right-radius: 0; - border-bottom-right-radius: 0; -} - -.input-group-addon:first-child { - border-right: 0; -} - -.input-group .form-control:last-child, -.input-group-addon:last-child, -.input-group-btn:last-child > .btn, -.input-group-btn:last-child > .dropdown-toggle, -.input-group-btn:first-child > .btn:not(:first-child) { - border-bottom-left-radius: 0; - border-top-left-radius: 0; -} - -.input-group-addon:last-child { - border-left: 0; -} - -.input-group-btn { - position: relative; - white-space: nowrap; -} - -.input-group-btn > .btn { - position: relative; -} - -.input-group-btn > .btn + .btn { - margin-left: -4px; -} - -.input-group-btn > .btn:hover, -.input-group-btn > .btn:active { - z-index: 2; -} - -.nav { - padding-left: 0; - margin-bottom: 0; - list-style: none; -} - -.nav:before, -.nav:after { - display: table; - content: " "; -} - -.nav:after { - clear: both; -} - -.nav:before, -.nav:after { - display: table; - content: " "; -} - -.nav:after { - clear: both; -} - -.nav > li { - position: relative; - display: block; -} - -.nav > li > a { - position: relative; - display: block; - padding: 10px 15px; -} - -.nav > li > a:hover, -.nav > li > a:focus { - text-decoration: none; - background-color: #eeeeee; -} - -.nav > li.disabled > a { - color: #999999; -} - -.nav > li.disabled > a:hover, -.nav > li.disabled > a:focus { - color: #999999; - text-decoration: none; - cursor: not-allowed; - background-color: transparent; -} - -.nav .open > a, -.nav .open > a:hover, -.nav .open > a:focus { - background-color: #eeeeee; - border-color: #428bca; -} - -.nav .nav-divider { - height: 1px; - margin: 9px 0; - overflow: hidden; - background-color: #e5e5e5; -} - -.nav > li > a > img { - max-width: none; -} - -.nav-tabs { - border-bottom: 1px solid #dddddd; -} - -.nav-tabs > li { - float: left; - margin-bottom: -1px; -} - -.nav-tabs > li > a { - margin-right: 2px; - line-height: 1.428571429; - border: 1px solid transparent; - border-radius: 4px 4px 0 0; -} - -.nav-tabs > li > a:hover { - border-color: #eeeeee #eeeeee #dddddd; -} - -.nav-tabs > li.active > a, -.nav-tabs > li.active > a:hover, -.nav-tabs > li.active > a:focus { - color: #555555; - cursor: default; - background-color: #ffffff; - border: 1px solid #dddddd; - border-bottom-color: transparent; -} - -.nav-tabs.nav-justified { - width: 100%; - border-bottom: 0; -} - -.nav-tabs.nav-justified > li { - float: none; -} - -.nav-tabs.nav-justified > li > a { - text-align: center; -} - -@media (min-width: 768px) { - .nav-tabs.nav-justified > li { - display: table-cell; - width: 1%; - } -} - -.nav-tabs.nav-justified > li > a { - margin-right: 0; - border-bottom: 1px solid #dddddd; -} - -.nav-tabs.nav-justified > .active > a { - border-bottom-color: #ffffff; -} - -.nav-pills > li { - float: left; -} - -.nav-pills > li > a { - border-radius: 5px; -} - -.nav-pills > li + li { - margin-left: 2px; -} - -.nav-pills > li.active > a, -.nav-pills > li.active > a:hover, -.nav-pills > li.active > a:focus { - color: #ffffff; - background-color: #428bca; -} - -.nav-stacked > li { - float: none; -} - -.nav-stacked > li + li { - margin-top: 2px; - margin-left: 0; -} - -.nav-justified { - width: 100%; -} - -.nav-justified > li { - float: none; -} - -.nav-justified > li > a { - text-align: center; -} - -@media (min-width: 768px) { - .nav-justified > li { - display: table-cell; - width: 1%; - } -} - -.nav-tabs-justified { - border-bottom: 0; -} - -.nav-tabs-justified > li > a { - margin-right: 0; - border-bottom: 1px solid #dddddd; -} - -.nav-tabs-justified > .active > a { - border-bottom-color: #ffffff; -} - -.tabbable:before, -.tabbable:after { - display: table; - content: " "; -} - -.tabbable:after { - clear: both; -} - -.tabbable:before, -.tabbable:after { - display: table; - content: " "; -} - -.tabbable:after { - clear: both; -} - -.tab-content > .tab-pane, -.pill-content > .pill-pane { - display: none; -} - -.tab-content > .active, -.pill-content > .active { - display: block; -} - -.nav .caret { - border-top-color: #428bca; - border-bottom-color: #428bca; -} - -.nav a:hover .caret { - border-top-color: #2a6496; - border-bottom-color: #2a6496; -} - -.nav-tabs .dropdown-menu { - margin-top: -1px; - border-top-right-radius: 0; - border-top-left-radius: 0; -} - -.navbar { - position: relative; - z-index: 1000; - min-height: 50px; - margin-bottom: 20px; - border: 1px solid transparent; -} - -.navbar:before, -.navbar:after { - display: table; - content: " "; -} - -.navbar:after { - clear: both; -} - -.navbar:before, -.navbar:after { - display: table; - content: " "; -} - -.navbar:after { - clear: both; -} - -@media (min-width: 768px) { - .navbar { - border-radius: 4px; - } -} - -.navbar-header:before, -.navbar-header:after { - display: table; - content: " "; -} - -.navbar-header:after { - clear: both; -} - -.navbar-header:before, -.navbar-header:after { - display: table; - content: " "; -} - -.navbar-header:after { - clear: both; -} - -@media (min-width: 768px) { - .navbar-header { - float: left; - } -} - -.navbar-collapse { - max-height: 340px; - padding-right: 15px; - padding-left: 15px; - overflow-x: visible; - border-top: 1px solid transparent; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); - -webkit-overflow-scrolling: touch; -} - -.navbar-collapse:before, -.navbar-collapse:after { - display: table; - content: " "; -} - -.navbar-collapse:after { - clear: both; -} - -.navbar-collapse:before, -.navbar-collapse:after { - display: table; - content: " "; -} - -.navbar-collapse:after { - clear: both; -} - -.navbar-collapse.in { - overflow-y: auto; -} - -@media (min-width: 768px) { - .navbar-collapse { - width: auto; - border-top: 0; - box-shadow: none; - } - .navbar-collapse.collapse { - display: block !important; - height: auto !important; - padding-bottom: 0; - overflow: visible !important; - } - .navbar-collapse.in { - overflow-y: visible; - } - .navbar-collapse .navbar-nav.navbar-left:first-child { - margin-left: -15px; - } - .navbar-collapse .navbar-nav.navbar-right:last-child { - margin-right: -15px; - } - .navbar-collapse .navbar-text:last-child { - margin-right: 0; - } -} - -.container > .navbar-header, -.container > .navbar-collapse { - margin-right: -15px; - margin-left: -15px; -} - -@media (min-width: 768px) { - .container > .navbar-header, - .container > .navbar-collapse { - margin-right: 0; - margin-left: 0; - } -} - -.navbar-static-top { - border-width: 0 0 1px; -} - -@media (min-width: 768px) { - .navbar-static-top { - border-radius: 0; - } -} - -.navbar-fixed-top, -.navbar-fixed-bottom { - position: fixed; - right: 0; - left: 0; - border-width: 0 0 1px; -} - -@media (min-width: 768px) { - .navbar-fixed-top, - .navbar-fixed-bottom { - border-radius: 0; - } -} - -.navbar-fixed-top { - top: 0; - z-index: 1030; -} - -.navbar-fixed-bottom { - bottom: 0; - margin-bottom: 0; -} - -.navbar-brand { - float: left; - padding: 15px 15px; - font-size: 18px; - line-height: 20px; -} - -.navbar-brand:hover, -.navbar-brand:focus { - text-decoration: none; -} - -@media (min-width: 768px) { - .navbar > .container .navbar-brand { - margin-left: -15px; - } -} - -.navbar-toggle { - position: relative; - float: right; - padding: 9px 10px; - margin-top: 8px; - margin-right: 15px; - margin-bottom: 8px; - background-color: transparent; - border: 1px solid transparent; - border-radius: 4px; -} - -.navbar-toggle .icon-bar { - display: block; - width: 22px; - height: 2px; - border-radius: 1px; -} - -.navbar-toggle .icon-bar + .icon-bar { - margin-top: 4px; -} - -@media (min-width: 768px) { - .navbar-toggle { - display: none; - } -} - -.navbar-nav { - margin: 7.5px -15px; -} - -.navbar-nav > li > a { - padding-top: 10px; - padding-bottom: 10px; - line-height: 20px; -} - -@media (max-width: 767px) { - .navbar-nav .open .dropdown-menu { - position: static; - float: none; - width: auto; - margin-top: 0; - background-color: transparent; - border: 0; - box-shadow: none; - } - .navbar-nav .open .dropdown-menu > li > a, - .navbar-nav .open .dropdown-menu .dropdown-header { - padding: 5px 15px 5px 25px; - } - .navbar-nav .open .dropdown-menu > li > a { - line-height: 20px; - } - .navbar-nav .open .dropdown-menu > li > a:hover, - .navbar-nav .open .dropdown-menu > li > a:focus { - background-image: none; - } -} - -@media (min-width: 768px) { - .navbar-nav { - float: left; - margin: 0; - } - .navbar-nav > li { - float: left; - } - .navbar-nav > li > a { - padding-top: 15px; - padding-bottom: 15px; - } -} - -@media (min-width: 768px) { - .navbar-left { - float: left !important; - } - .navbar-right { - float: right !important; - } -} - -.navbar-form { - padding: 10px 15px; - margin-top: 8px; - margin-right: -15px; - margin-bottom: 8px; - margin-left: -15px; - border-top: 1px solid transparent; - border-bottom: 1px solid transparent; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); -} - -@media (min-width: 768px) { - .navbar-form .form-group { - display: inline-block; - margin-bottom: 0; - vertical-align: middle; - } - .navbar-form .form-control { - display: inline-block; - } - .navbar-form .radio, - .navbar-form .checkbox { - display: inline-block; - padding-left: 0; - margin-top: 0; - margin-bottom: 0; - } - .navbar-form .radio input[type="radio"], - .navbar-form .checkbox input[type="checkbox"] { - float: none; - margin-left: 0; - } -} - -@media (max-width: 767px) { - .navbar-form .form-group { - margin-bottom: 5px; - } -} - -@media (min-width: 768px) { - .navbar-form { - width: auto; - padding-top: 0; - padding-bottom: 0; - margin-right: 0; - margin-left: 0; - border: 0; - -webkit-box-shadow: none; - box-shadow: none; - } -} - -.navbar-nav > li > .dropdown-menu { - margin-top: 0; - border-top-right-radius: 0; - border-top-left-radius: 0; -} - -.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} - -.navbar-nav.pull-right > li > .dropdown-menu, -.navbar-nav > li > .dropdown-menu.pull-right { - right: 0; - left: auto; -} - -.navbar-btn { - margin-top: 8px; - margin-bottom: 8px; -} - -.navbar-text { - float: left; - margin-top: 15px; - margin-bottom: 15px; -} - -@media (min-width: 768px) { - .navbar-text { - margin-right: 15px; - margin-left: 15px; - } -} - -.navbar-default { - background-color: #f8f8f8; - border-color: #e7e7e7; -} - -.navbar-default .navbar-brand { - color: #777777; -} - -.navbar-default .navbar-brand:hover, -.navbar-default .navbar-brand:focus { - color: #5e5e5e; - background-color: transparent; -} - -.navbar-default .navbar-text { - color: #777777; -} - -.navbar-default .navbar-nav > li > a { - color: #777777; -} - -.navbar-default .navbar-nav > li > a:hover, -.navbar-default .navbar-nav > li > a:focus { - color: #333333; - background-color: transparent; -} - -.navbar-default .navbar-nav > .active > a, -.navbar-default .navbar-nav > .active > a:hover, -.navbar-default .navbar-nav > .active > a:focus { - color: #555555; - background-color: #e7e7e7; -} - -.navbar-default .navbar-nav > .disabled > a, -.navbar-default .navbar-nav > .disabled > a:hover, -.navbar-default .navbar-nav > .disabled > a:focus { - color: #cccccc; - background-color: transparent; -} - -.navbar-default .navbar-toggle { - border-color: #dddddd; -} - -.navbar-default .navbar-toggle:hover, -.navbar-default .navbar-toggle:focus { - background-color: #dddddd; -} - -.navbar-default .navbar-toggle .icon-bar { - background-color: #cccccc; -} - -.navbar-default .navbar-collapse, -.navbar-default .navbar-form { - border-color: #e6e6e6; -} - -.navbar-default .navbar-nav > .dropdown > a:hover .caret, -.navbar-default .navbar-nav > .dropdown > a:focus .caret { - border-top-color: #333333; - border-bottom-color: #333333; -} - -.navbar-default .navbar-nav > .open > a, -.navbar-default .navbar-nav > .open > a:hover, -.navbar-default .navbar-nav > .open > a:focus { - color: #555555; - background-color: #e7e7e7; -} - -.navbar-default .navbar-nav > .open > a .caret, -.navbar-default .navbar-nav > .open > a:hover .caret, -.navbar-default .navbar-nav > .open > a:focus .caret { - border-top-color: #555555; - border-bottom-color: #555555; -} - -.navbar-default .navbar-nav > .dropdown > a .caret { - border-top-color: #777777; - border-bottom-color: #777777; -} - -@media (max-width: 767px) { - .navbar-default .navbar-nav .open .dropdown-menu > li > a { - color: #777777; - } - .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, - .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { - color: #333333; - background-color: transparent; - } - .navbar-default .navbar-nav .open .dropdown-menu > .active > a, - .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, - .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { - color: #555555; - background-color: #e7e7e7; - } - .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, - .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, - .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { - color: #cccccc; - background-color: transparent; - } -} - -.navbar-default .navbar-link { - color: #777777; -} - -.navbar-default .navbar-link:hover { - color: #333333; -} - -.navbar-inverse { - background-color: #222222; - border-color: #080808; -} - -.navbar-inverse .navbar-brand { - color: #999999; -} - -.navbar-inverse .navbar-brand:hover, -.navbar-inverse .navbar-brand:focus { - color: #ffffff; - background-color: transparent; -} - -.navbar-inverse .navbar-text { - color: #999999; -} - -.navbar-inverse .navbar-nav > li > a { - color: #999999; -} - -.navbar-inverse .navbar-nav > li > a:hover, -.navbar-inverse .navbar-nav > li > a:focus { - color: #ffffff; - background-color: transparent; -} - -.navbar-inverse .navbar-nav > .active > a, -.navbar-inverse .navbar-nav > .active > a:hover, -.navbar-inverse .navbar-nav > .active > a:focus { - color: #ffffff; - background-color: #080808; -} - -.navbar-inverse .navbar-nav > .disabled > a, -.navbar-inverse .navbar-nav > .disabled > a:hover, -.navbar-inverse .navbar-nav > .disabled > a:focus { - color: #444444; - background-color: transparent; -} - -.navbar-inverse .navbar-toggle { - border-color: #333333; -} - -.navbar-inverse .navbar-toggle:hover, -.navbar-inverse .navbar-toggle:focus { - background-color: #333333; -} - -.navbar-inverse .navbar-toggle .icon-bar { - background-color: #ffffff; -} - -.navbar-inverse .navbar-collapse, -.navbar-inverse .navbar-form { - border-color: #101010; -} - -.navbar-inverse .navbar-nav > .open > a, -.navbar-inverse .navbar-nav > .open > a:hover, -.navbar-inverse .navbar-nav > .open > a:focus { - color: #ffffff; - background-color: #080808; -} - -.navbar-inverse .navbar-nav > .dropdown > a:hover .caret { - border-top-color: #ffffff; - border-bottom-color: #ffffff; -} - -.navbar-inverse .navbar-nav > .dropdown > a .caret { - border-top-color: #999999; - border-bottom-color: #999999; -} - -.navbar-inverse .navbar-nav > .open > a .caret, -.navbar-inverse .navbar-nav > .open > a:hover .caret, -.navbar-inverse .navbar-nav > .open > a:focus .caret { - border-top-color: #ffffff; - border-bottom-color: #ffffff; -} - -@media (max-width: 767px) { - .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { - border-color: #080808; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { - color: #999999; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, - .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { - color: #ffffff; - background-color: transparent; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, - .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, - .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { - color: #ffffff; - background-color: #080808; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, - .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, - .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { - color: #444444; - background-color: transparent; - } -} - -.navbar-inverse .navbar-link { - color: #999999; -} - -.navbar-inverse .navbar-link:hover { - color: #ffffff; -} - -.breadcrumb { - padding: 8px 15px; - margin-bottom: 20px; - list-style: none; - background-color: #f5f5f5; - border-radius: 4px; -} - -.breadcrumb > li { - display: inline-block; -} - -.breadcrumb > li + li:before { - padding: 0 5px; - color: #cccccc; - content: "/\00a0"; -} - -.breadcrumb > .active { - color: #999999; -} - -.pagination { - display: inline-block; - padding-left: 0; - margin: 20px 0; - border-radius: 4px; -} - -.pagination > li { - display: inline; -} - -.pagination > li > a, -.pagination > li > span { - position: relative; - float: left; - padding: 6px 12px; - margin-left: -1px; - line-height: 1.428571429; - text-decoration: none; - background-color: #ffffff; - border: 1px solid #dddddd; -} - -.pagination > li:first-child > a, -.pagination > li:first-child > span { - margin-left: 0; - border-bottom-left-radius: 4px; - border-top-left-radius: 4px; -} - -.pagination > li:last-child > a, -.pagination > li:last-child > span { - border-top-right-radius: 4px; - border-bottom-right-radius: 4px; -} - -.pagination > li > a:hover, -.pagination > li > span:hover, -.pagination > li > a:focus, -.pagination > li > span:focus { - background-color: #eeeeee; -} - -.pagination > .active > a, -.pagination > .active > span, -.pagination > .active > a:hover, -.pagination > .active > span:hover, -.pagination > .active > a:focus, -.pagination > .active > span:focus { - z-index: 2; - color: #ffffff; - cursor: default; - background-color: #428bca; - border-color: #428bca; -} - -.pagination > .disabled > span, -.pagination > .disabled > a, -.pagination > .disabled > a:hover, -.pagination > .disabled > a:focus { - color: #999999; - cursor: not-allowed; - background-color: #ffffff; - border-color: #dddddd; -} - -.pagination-lg > li > a, -.pagination-lg > li > span { - padding: 10px 16px; - font-size: 18px; -} - -.pagination-lg > li:first-child > a, -.pagination-lg > li:first-child > span { - border-bottom-left-radius: 6px; - border-top-left-radius: 6px; -} - -.pagination-lg > li:last-child > a, -.pagination-lg > li:last-child > span { - border-top-right-radius: 6px; - border-bottom-right-radius: 6px; -} - -.pagination-sm > li > a, -.pagination-sm > li > span { - padding: 5px 10px; - font-size: 12px; -} - -.pagination-sm > li:first-child > a, -.pagination-sm > li:first-child > span { - border-bottom-left-radius: 3px; - border-top-left-radius: 3px; -} - -.pagination-sm > li:last-child > a, -.pagination-sm > li:last-child > span { - border-top-right-radius: 3px; - border-bottom-right-radius: 3px; -} - -.pager { - padding-left: 0; - margin: 20px 0; - text-align: center; - list-style: none; -} - -.pager:before, -.pager:after { - display: table; - content: " "; -} - -.pager:after { - clear: both; -} - -.pager:before, -.pager:after { - display: table; - content: " "; -} - -.pager:after { - clear: both; -} - -.pager li { - display: inline; -} - -.pager li > a, -.pager li > span { - display: inline-block; - padding: 5px 14px; - background-color: #ffffff; - border: 1px solid #dddddd; - border-radius: 15px; -} - -.pager li > a:hover, -.pager li > a:focus { - text-decoration: none; - background-color: #eeeeee; -} - -.pager .next > a, -.pager .next > span { - float: right; -} - -.pager .previous > a, -.pager .previous > span { - float: left; -} - -.pager .disabled > a, -.pager .disabled > a:hover, -.pager .disabled > a:focus, -.pager .disabled > span { - color: #999999; - cursor: not-allowed; - background-color: #ffffff; -} - -.label { - display: inline; - padding: .2em .6em .3em; - font-size: 75%; - font-weight: bold; - line-height: 1; - color: #ffffff; - text-align: center; - white-space: nowrap; - vertical-align: baseline; - border-radius: .25em; -} - -.label[href]:hover, -.label[href]:focus { - color: #ffffff; - text-decoration: none; - cursor: pointer; -} - -.label:empty { - display: none; -} - -.label-default { - background-color: #999999; -} - -.label-default[href]:hover, -.label-default[href]:focus { - background-color: #808080; -} - -.label-primary { - background-color: #428bca; -} - -.label-primary[href]:hover, -.label-primary[href]:focus { - background-color: #3071a9; -} - -.label-success { - background-color: #5cb85c; -} - -.label-success[href]:hover, -.label-success[href]:focus { - background-color: #449d44; -} - -.label-info { - background-color: #5bc0de; -} - -.label-info[href]:hover, -.label-info[href]:focus { - background-color: #31b0d5; -} - -.label-warning { - background-color: #f0ad4e; -} - -.label-warning[href]:hover, -.label-warning[href]:focus { - background-color: #ec971f; -} - -.label-danger { - background-color: #d9534f; -} - -.label-danger[href]:hover, -.label-danger[href]:focus { - background-color: #c9302c; -} - -.badge { - display: inline-block; - min-width: 10px; - padding: 3px 7px; - font-size: 12px; - font-weight: bold; - line-height: 1; - color: #ffffff; - text-align: center; - white-space: nowrap; - vertical-align: baseline; - background-color: #999999; - border-radius: 10px; -} - -.badge:empty { - display: none; -} - -a.badge:hover, -a.badge:focus { - color: #ffffff; - text-decoration: none; - cursor: pointer; -} - -.btn .badge { - position: relative; - top: -1px; -} - -a.list-group-item.active > .badge, -.nav-pills > .active > a > .badge { - color: #428bca; - background-color: #ffffff; -} - -.nav-pills > li > a > .badge { - margin-left: 3px; -} - -.jumbotron { - padding: 30px; - margin-bottom: 30px; - font-size: 21px; - font-weight: 200; - line-height: 2.1428571435; - color: inherit; - background-color: #eeeeee; -} - -.jumbotron h1 { - line-height: 1; - color: inherit; -} - -.jumbotron p { - line-height: 1.4; -} - -.container .jumbotron { - border-radius: 6px; -} - -@media screen and (min-width: 768px) { - .jumbotron { - padding-top: 48px; - padding-bottom: 48px; - } - .container .jumbotron { - padding-right: 60px; - padding-left: 60px; - } - .jumbotron h1 { - font-size: 63px; - } -} - -.thumbnail { - display: inline-block; - display: block; - height: auto; - max-width: 100%; - padding: 4px; - line-height: 1.428571429; - background-color: #ffffff; - border: 1px solid #dddddd; - border-radius: 4px; - -webkit-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; -} - -.thumbnail > img { - display: block; - height: auto; - max-width: 100%; -} - -a.thumbnail:hover, -a.thumbnail:focus { - border-color: #428bca; -} - -.thumbnail > img { - margin-right: auto; - margin-left: auto; -} - -.thumbnail .caption { - padding: 9px; - color: #333333; -} - -.alert { - padding: 15px; - margin-bottom: 20px; - border: 1px solid transparent; - border-radius: 4px; -} - -.alert h4 { - margin-top: 0; - color: inherit; -} - -.alert .alert-link { - font-weight: bold; -} - -.alert > p, -.alert > ul { - margin-bottom: 0; -} - -.alert > p + p { - margin-top: 5px; -} - -.alert-dismissable { - padding-right: 35px; -} - -.alert-dismissable .close { - position: relative; - top: -2px; - right: -21px; - color: inherit; -} - -.alert-success { - color: #468847; - background-color: #dff0d8; - border-color: #d6e9c6; -} - -.alert-success hr { - border-top-color: #c9e2b3; -} - -.alert-success .alert-link { - color: #356635; -} - -.alert-info { - color: #3a87ad; - background-color: #d9edf7; - border-color: #bce8f1; -} - -.alert-info hr { - border-top-color: #a6e1ec; -} - -.alert-info .alert-link { - color: #2d6987; -} - -.alert-warning { - color: #c09853; - background-color: #fcf8e3; - border-color: #fbeed5; -} - -.alert-warning hr { - border-top-color: #f8e5be; -} - -.alert-warning .alert-link { - color: #a47e3c; -} - -.alert-danger { - color: #b94a48; - background-color: #f2dede; - border-color: #eed3d7; -} - -.alert-danger hr { - border-top-color: #e6c1c7; -} - -.alert-danger .alert-link { - color: #953b39; -} - -@-webkit-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} - -@-moz-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} - -@-o-keyframes progress-bar-stripes { - from { - background-position: 0 0; - } - to { - background-position: 40px 0; - } -} - -@keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} - -.progress { - height: 20px; - margin-bottom: 20px; - overflow: hidden; - background-color: #f5f5f5; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -} - -.progress-bar { - float: left; - width: 0; - height: 100%; - font-size: 12px; - color: #ffffff; - text-align: center; - background-color: #428bca; - -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - -webkit-transition: width 0.6s ease; - transition: width 0.6s ease; -} - -.progress-striped .progress-bar { - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-size: 40px 40px; -} - -.progress.active .progress-bar { - -webkit-animation: progress-bar-stripes 2s linear infinite; - -moz-animation: progress-bar-stripes 2s linear infinite; - -ms-animation: progress-bar-stripes 2s linear infinite; - -o-animation: progress-bar-stripes 2s linear infinite; - animation: progress-bar-stripes 2s linear infinite; -} - -.progress-bar-success { - background-color: #5cb85c; -} - -.progress-striped .progress-bar-success { - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} - -.progress-bar-info { - background-color: #5bc0de; -} - -.progress-striped .progress-bar-info { - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} - -.progress-bar-warning { - background-color: #f0ad4e; -} - -.progress-striped .progress-bar-warning { - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} - -.progress-bar-danger { - background-color: #d9534f; -} - -.progress-striped .progress-bar-danger { - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} - -.media, -.media-body { - overflow: hidden; - zoom: 1; -} - -.media, -.media .media { - margin-top: 15px; -} - -.media:first-child { - margin-top: 0; -} - -.media-object { - display: block; -} - -.media-heading { - margin: 0 0 5px; -} - -.media > .pull-left { - margin-right: 10px; -} - -.media > .pull-right { - margin-left: 10px; -} - -.media-list { - padding-left: 0; - list-style: none; -} - -.list-group { - padding-left: 0; - margin-bottom: 20px; -} - -.list-group-item { - position: relative; - display: block; - padding: 10px 15px; - margin-bottom: -1px; - background-color: #ffffff; - border: 1px solid #dddddd; -} - -.list-group-item:first-child { - border-top-right-radius: 4px; - border-top-left-radius: 4px; -} - -.list-group-item:last-child { - margin-bottom: 0; - border-bottom-right-radius: 4px; - border-bottom-left-radius: 4px; -} - -.list-group-item > .badge { - float: right; -} - -.list-group-item > .badge + .badge { - margin-right: 5px; -} - -a.list-group-item { - color: #555555; -} - -a.list-group-item .list-group-item-heading { - color: #333333; -} - -a.list-group-item:hover, -a.list-group-item:focus { - text-decoration: none; - background-color: #f5f5f5; -} - -.list-group-item.active, -.list-group-item.active:hover, -.list-group-item.active:focus { - z-index: 2; - color: #ffffff; - background-color: #428bca; - border-color: #428bca; -} - -.list-group-item.active .list-group-item-heading, -.list-group-item.active:hover .list-group-item-heading, -.list-group-item.active:focus .list-group-item-heading { - color: inherit; -} - -.list-group-item.active .list-group-item-text, -.list-group-item.active:hover .list-group-item-text, -.list-group-item.active:focus .list-group-item-text { - color: #e1edf7; -} - -.list-group-item-heading { - margin-top: 0; - margin-bottom: 5px; -} - -.list-group-item-text { - margin-bottom: 0; - line-height: 1.3; -} - -.panel { - margin-bottom: 20px; - background-color: #ffffff; - border: 1px solid transparent; - border-radius: 4px; - -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); -} - -.panel-body { - padding: 15px; -} - -.panel-body:before, -.panel-body:after { - display: table; - content: " "; -} - -.panel-body:after { - clear: both; -} - -.panel-body:before, -.panel-body:after { - display: table; - content: " "; -} - -.panel-body:after { - clear: both; -} - -.panel > .list-group { - margin-bottom: 0; -} - -.panel > .list-group .list-group-item { - border-width: 1px 0; -} - -.panel > .list-group .list-group-item:first-child { - border-top-right-radius: 0; - border-top-left-radius: 0; -} - -.panel > .list-group .list-group-item:last-child { - border-bottom: 0; -} - -.panel-heading + .list-group .list-group-item:first-child { - border-top-width: 0; -} - -.panel > .table { - margin-bottom: 0; -} - -.panel > .panel-body + .table { - border-top: 1px solid #dddddd; -} - -.panel-heading { - padding: 10px 15px; - border-bottom: 1px solid transparent; - border-top-right-radius: 3px; - border-top-left-radius: 3px; -} - -.panel-title { - margin-top: 0; - margin-bottom: 0; - font-size: 16px; -} - -.panel-title > a { - color: inherit; -} - -.panel-footer { - padding: 10px 15px; - background-color: #f5f5f5; - border-top: 1px solid #dddddd; - border-bottom-right-radius: 3px; - border-bottom-left-radius: 3px; -} - -.panel-group .panel { - margin-bottom: 0; - overflow: hidden; - border-radius: 4px; -} - -.panel-group .panel + .panel { - margin-top: 5px; -} - -.panel-group .panel-heading { - border-bottom: 0; -} - -.panel-group .panel-heading + .panel-collapse .panel-body { - border-top: 1px solid #dddddd; -} - -.panel-group .panel-footer { - border-top: 0; -} - -.panel-group .panel-footer + .panel-collapse .panel-body { - border-bottom: 1px solid #dddddd; -} - -.panel-default { - border-color: #dddddd; -} - -.panel-default > .panel-heading { - color: #333333; - background-color: #f5f5f5; - border-color: #dddddd; -} - -.panel-default > .panel-heading + .panel-collapse .panel-body { - border-top-color: #dddddd; -} - -.panel-default > .panel-footer + .panel-collapse .panel-body { - border-bottom-color: #dddddd; -} - -.panel-primary { - border-color: #428bca; -} - -.panel-primary > .panel-heading { - color: #ffffff; - background-color: #428bca; - border-color: #428bca; -} - -.panel-primary > .panel-heading + .panel-collapse .panel-body { - border-top-color: #428bca; -} - -.panel-primary > .panel-footer + .panel-collapse .panel-body { - border-bottom-color: #428bca; -} - -.panel-success { - border-color: #d6e9c6; -} - -.panel-success > .panel-heading { - color: #468847; - background-color: #dff0d8; - border-color: #d6e9c6; -} - -.panel-success > .panel-heading + .panel-collapse .panel-body { - border-top-color: #d6e9c6; -} - -.panel-success > .panel-footer + .panel-collapse .panel-body { - border-bottom-color: #d6e9c6; -} - -.panel-warning { - border-color: #fbeed5; -} - -.panel-warning > .panel-heading { - color: #c09853; - background-color: #fcf8e3; - border-color: #fbeed5; -} - -.panel-warning > .panel-heading + .panel-collapse .panel-body { - border-top-color: #fbeed5; -} - -.panel-warning > .panel-footer + .panel-collapse .panel-body { - border-bottom-color: #fbeed5; -} - -.panel-danger { - border-color: #eed3d7; -} - -.panel-danger > .panel-heading { - color: #b94a48; - background-color: #f2dede; - border-color: #eed3d7; -} - -.panel-danger > .panel-heading + .panel-collapse .panel-body { - border-top-color: #eed3d7; -} - -.panel-danger > .panel-footer + .panel-collapse .panel-body { - border-bottom-color: #eed3d7; -} - -.panel-info { - border-color: #bce8f1; -} - -.panel-info > .panel-heading { - color: #3a87ad; - background-color: #d9edf7; - border-color: #bce8f1; -} - -.panel-info > .panel-heading + .panel-collapse .panel-body { - border-top-color: #bce8f1; -} - -.panel-info > .panel-footer + .panel-collapse .panel-body { - border-bottom-color: #bce8f1; -} - -.well { - min-height: 20px; - padding: 19px; - margin-bottom: 20px; - background-color: #f5f5f5; - border: 1px solid #e3e3e3; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); -} - -.well blockquote { - border-color: #ddd; - border-color: rgba(0, 0, 0, 0.15); -} - -.well-lg { - padding: 24px; - border-radius: 6px; -} - -.well-sm { - padding: 9px; - border-radius: 3px; -} - -.close { - float: right; - font-size: 21px; - font-weight: bold; - line-height: 1; - color: #000000; - text-shadow: 0 1px 0 #ffffff; - opacity: 0.2; - filter: alpha(opacity=20); -} - -.close:hover, -.close:focus { - color: #000000; - text-decoration: none; - cursor: pointer; - opacity: 0.5; - filter: alpha(opacity=50); -} - -button.close { - padding: 0; - cursor: pointer; - background: transparent; - border: 0; - -webkit-appearance: none; -} - -.modal-open { - overflow: hidden; -} - -body.modal-open, -.modal-open .navbar-fixed-top, -.modal-open .navbar-fixed-bottom { - margin-right: 15px; -} - -.modal { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1040; - display: none; - overflow: auto; - overflow-y: scroll; -} - -.modal.fade .modal-dialog { - -webkit-transform: translate(0, -25%); - -ms-transform: translate(0, -25%); - transform: translate(0, -25%); - -webkit-transition: -webkit-transform 0.3s ease-out; - -moz-transition: -moz-transform 0.3s ease-out; - -o-transition: -o-transform 0.3s ease-out; - transition: transform 0.3s ease-out; -} - -.modal.in .modal-dialog { - -webkit-transform: translate(0, 0); - -ms-transform: translate(0, 0); - transform: translate(0, 0); -} - -.modal-dialog { - z-index: 1050; - width: auto; - padding: 10px; - margin-right: auto; - margin-left: auto; -} - -.modal-content { - position: relative; - background-color: #ffffff; - border: 1px solid #999999; - border: 1px solid rgba(0, 0, 0, 0.2); - border-radius: 6px; - outline: none; - -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); - box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); - background-clip: padding-box; -} - -.modal-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1030; - background-color: #000000; -} - -.modal-backdrop.fade { - opacity: 0; - filter: alpha(opacity=0); -} - -.modal-backdrop.in { - opacity: 0.5; - filter: alpha(opacity=50); -} - -.modal-header { - min-height: 16.428571429px; - padding: 15px; - border-bottom: 1px solid #e5e5e5; -} - -.modal-header .close { - margin-top: -2px; -} - -.modal-title { - margin: 0; - line-height: 1.428571429; -} - -.modal-body { - position: relative; - padding: 20px; -} - -.modal-footer { - padding: 19px 20px 20px; - margin-top: 15px; - text-align: right; - border-top: 1px solid #e5e5e5; -} - -.modal-footer:before, -.modal-footer:after { - display: table; - content: " "; -} - -.modal-footer:after { - clear: both; -} - -.modal-footer:before, -.modal-footer:after { - display: table; - content: " "; -} - -.modal-footer:after { - clear: both; -} - -.modal-footer .btn + .btn { - margin-bottom: 0; - margin-left: 5px; -} - -.modal-footer .btn-group .btn + .btn { - margin-left: -1px; -} - -.modal-footer .btn-block + .btn-block { - margin-left: 0; -} - -@media screen and (min-width: 768px) { - .modal-dialog { - right: auto; - left: 50%; - width: 600px; - padding-top: 30px; - padding-bottom: 30px; - } - .modal-content { - -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); - box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); - } -} - -.tooltip { - position: absolute; - z-index: 1030; - display: block; - font-size: 12px; - line-height: 1.4; - opacity: 0; - filter: alpha(opacity=0); - visibility: visible; -} - -.tooltip.in { - opacity: 0.9; - filter: alpha(opacity=90); -} - -.tooltip.top { - padding: 5px 0; - margin-top: -3px; -} - -.tooltip.right { - padding: 0 5px; - margin-left: 3px; -} - -.tooltip.bottom { - padding: 5px 0; - margin-top: 3px; -} - -.tooltip.left { - padding: 0 5px; - margin-left: -3px; -} - -.tooltip-inner { - max-width: 200px; - padding: 3px 8px; - color: #ffffff; - text-align: center; - text-decoration: none; - background-color: #000000; - border-radius: 4px; -} - -.tooltip-arrow { - position: absolute; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} - -.tooltip.top .tooltip-arrow { - bottom: 0; - left: 50%; - margin-left: -5px; - border-top-color: #000000; - border-width: 5px 5px 0; -} - -.tooltip.top-left .tooltip-arrow { - bottom: 0; - left: 5px; - border-top-color: #000000; - border-width: 5px 5px 0; -} - -.tooltip.top-right .tooltip-arrow { - right: 5px; - bottom: 0; - border-top-color: #000000; - border-width: 5px 5px 0; -} - -.tooltip.right .tooltip-arrow { - top: 50%; - left: 0; - margin-top: -5px; - border-right-color: #000000; - border-width: 5px 5px 5px 0; -} - -.tooltip.left .tooltip-arrow { - top: 50%; - right: 0; - margin-top: -5px; - border-left-color: #000000; - border-width: 5px 0 5px 5px; -} - -.tooltip.bottom .tooltip-arrow { - top: 0; - left: 50%; - margin-left: -5px; - border-bottom-color: #000000; - border-width: 0 5px 5px; -} - -.tooltip.bottom-left .tooltip-arrow { - top: 0; - left: 5px; - border-bottom-color: #000000; - border-width: 0 5px 5px; -} - -.tooltip.bottom-right .tooltip-arrow { - top: 0; - right: 5px; - border-bottom-color: #000000; - border-width: 0 5px 5px; -} - -.popover { - position: absolute; - top: 0; - left: 0; - z-index: 1010; - display: none; - max-width: 276px; - padding: 1px; - text-align: left; - white-space: normal; - background-color: #ffffff; - border: 1px solid #cccccc; - border: 1px solid rgba(0, 0, 0, 0.2); - border-radius: 6px; - -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - background-clip: padding-box; -} - -.popover.top { - margin-top: -10px; -} - -.popover.right { - margin-left: 10px; -} - -.popover.bottom { - margin-top: 10px; -} - -.popover.left { - margin-left: -10px; -} - -.popover-title { - padding: 8px 14px; - margin: 0; - font-size: 14px; - font-weight: normal; - line-height: 18px; - background-color: #f7f7f7; - border-bottom: 1px solid #ebebeb; - border-radius: 5px 5px 0 0; -} - -.popover-content { - padding: 9px 14px; -} - -.popover .arrow, -.popover .arrow:after { - position: absolute; - display: block; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} - -.popover .arrow { - border-width: 11px; -} - -.popover .arrow:after { - border-width: 10px; - content: ""; -} - -.popover.top .arrow { - bottom: -11px; - left: 50%; - margin-left: -11px; - border-top-color: #999999; - border-top-color: rgba(0, 0, 0, 0.25); - border-bottom-width: 0; -} - -.popover.top .arrow:after { - bottom: 1px; - margin-left: -10px; - border-top-color: #ffffff; - border-bottom-width: 0; - content: " "; -} - -.popover.right .arrow { - top: 50%; - left: -11px; - margin-top: -11px; - border-right-color: #999999; - border-right-color: rgba(0, 0, 0, 0.25); - border-left-width: 0; -} - -.popover.right .arrow:after { - bottom: -10px; - left: 1px; - border-right-color: #ffffff; - border-left-width: 0; - content: " "; -} - -.popover.bottom .arrow { - top: -11px; - left: 50%; - margin-left: -11px; - border-bottom-color: #999999; - border-bottom-color: rgba(0, 0, 0, 0.25); - border-top-width: 0; -} - -.popover.bottom .arrow:after { - top: 1px; - margin-left: -10px; - border-bottom-color: #ffffff; - border-top-width: 0; - content: " "; -} - -.popover.left .arrow { - top: 50%; - right: -11px; - margin-top: -11px; - border-left-color: #999999; - border-left-color: rgba(0, 0, 0, 0.25); - border-right-width: 0; -} - -.popover.left .arrow:after { - right: 1px; - bottom: -10px; - border-left-color: #ffffff; - border-right-width: 0; - content: " "; -} - -.carousel { - position: relative; -} - -.carousel-inner { - position: relative; - width: 100%; - overflow: hidden; -} - -.carousel-inner > .item { - position: relative; - display: none; - -webkit-transition: 0.6s ease-in-out left; - transition: 0.6s ease-in-out left; -} - -.carousel-inner > .item > img, -.carousel-inner > .item > a > img { - display: block; - height: auto; - max-width: 100%; - line-height: 1; -} - -.carousel-inner > .active, -.carousel-inner > .next, -.carousel-inner > .prev { - display: block; -} - -.carousel-inner > .active { - left: 0; -} - -.carousel-inner > .next, -.carousel-inner > .prev { - position: absolute; - top: 0; - width: 100%; -} - -.carousel-inner > .next { - left: 100%; -} - -.carousel-inner > .prev { - left: -100%; -} - -.carousel-inner > .next.left, -.carousel-inner > .prev.right { - left: 0; -} - -.carousel-inner > .active.left { - left: -100%; -} - -.carousel-inner > .active.right { - left: 100%; -} - -.carousel-control { - position: absolute; - top: 0; - bottom: 0; - left: 0; - width: 15%; - font-size: 20px; - color: #ffffff; - text-align: center; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); - opacity: 0.5; - filter: alpha(opacity=50); -} - -.carousel-control.left { - background-image: -webkit-gradient(linear, 0 top, 100% top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0.0001))); - background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.5) 0), color-stop(rgba(0, 0, 0, 0.0001) 100%)); - background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.5) 0, rgba(0, 0, 0, 0.0001) 100%); - background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0, rgba(0, 0, 0, 0.0001) 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); -} - -.carousel-control.right { - right: 0; - left: auto; - background-image: -webkit-gradient(linear, 0 top, 100% top, from(rgba(0, 0, 0, 0.0001)), to(rgba(0, 0, 0, 0.5))); - background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.0001) 0), color-stop(rgba(0, 0, 0, 0.5) 100%)); - background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0, rgba(0, 0, 0, 0.5) 100%); - background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0, rgba(0, 0, 0, 0.5) 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); -} - -.carousel-control:hover, -.carousel-control:focus { - color: #ffffff; - text-decoration: none; - opacity: 0.9; - filter: alpha(opacity=90); -} - -.carousel-control .icon-prev, -.carousel-control .icon-next, -.carousel-control .glyphicon-chevron-left, -.carousel-control .glyphicon-chevron-right { - position: absolute; - top: 50%; - left: 50%; - z-index: 5; - display: inline-block; -} - -.carousel-control .icon-prev, -.carousel-control .icon-next { - width: 20px; - height: 20px; - margin-top: -10px; - margin-left: -10px; - font-family: serif; -} - -.carousel-control .icon-prev:before { - content: '\2039'; -} - -.carousel-control .icon-next:before { - content: '\203a'; -} - -.carousel-indicators { - position: absolute; - bottom: 10px; - left: 50%; - z-index: 15; - width: 60%; - padding-left: 0; - margin-left: -30%; - text-align: center; - list-style: none; -} - -.carousel-indicators li { - display: inline-block; - width: 10px; - height: 10px; - margin: 1px; - text-indent: -999px; - cursor: pointer; - border: 1px solid #ffffff; - border-radius: 10px; -} - -.carousel-indicators .active { - width: 12px; - height: 12px; - margin: 0; - background-color: #ffffff; -} - -.carousel-caption { - position: absolute; - right: 15%; - bottom: 20px; - left: 15%; - z-index: 10; - padding-top: 20px; - padding-bottom: 20px; - color: #ffffff; - text-align: center; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); -} - -.carousel-caption .btn { - text-shadow: none; -} - -@media screen and (min-width: 768px) { - .carousel-control .icon-prev, - .carousel-control .icon-next { - width: 30px; - height: 30px; - margin-top: -15px; - margin-left: -15px; - font-size: 30px; - } - .carousel-caption { - right: 20%; - left: 20%; - padding-bottom: 30px; - } - .carousel-indicators { - bottom: 20px; - } -} - -.clearfix:before, -.clearfix:after { - display: table; - content: " "; -} - -.clearfix:after { - clear: both; -} - -.pull-right { - float: right !important; -} - -.pull-left { - float: left !important; -} - -.hide { - display: none !important; -} - -.show { - display: block !important; -} - -.invisible { - visibility: hidden; -} - -.text-hide { - font: 0/0 a; - color: transparent; - text-shadow: none; - background-color: transparent; - border: 0; -} - -.affix { - position: fixed; -} - -@-ms-viewport { - width: device-width; -} - -@media screen and (max-width: 400px) { - @-ms-viewport { - width: 320px; - } -} - -.hidden { - display: none !important; - visibility: hidden !important; -} - -.visible-xs { - display: none !important; -} - -tr.visible-xs { - display: none !important; -} - -th.visible-xs, -td.visible-xs { - display: none !important; -} - -@media (max-width: 767px) { - .visible-xs { - display: block !important; - } - tr.visible-xs { - display: table-row !important; - } - th.visible-xs, - td.visible-xs { - display: table-cell !important; - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .visible-xs.visible-sm { - display: block !important; - } - tr.visible-xs.visible-sm { - display: table-row !important; - } - th.visible-xs.visible-sm, - td.visible-xs.visible-sm { - display: table-cell !important; - } -} - -@media (min-width: 992px) and (max-width: 1199px) { - .visible-xs.visible-md { - display: block !important; - } - tr.visible-xs.visible-md { - display: table-row !important; - } - th.visible-xs.visible-md, - td.visible-xs.visible-md { - display: table-cell !important; - } -} - -@media (min-width: 1200px) { - .visible-xs.visible-lg { - display: block !important; - } - tr.visible-xs.visible-lg { - display: table-row !important; - } - th.visible-xs.visible-lg, - td.visible-xs.visible-lg { - display: table-cell !important; - } -} - -.visible-sm { - display: none !important; -} - -tr.visible-sm { - display: none !important; -} - -th.visible-sm, -td.visible-sm { - display: none !important; -} - -@media (max-width: 767px) { - .visible-sm.visible-xs { - display: block !important; - } - tr.visible-sm.visible-xs { - display: table-row !important; - } - th.visible-sm.visible-xs, - td.visible-sm.visible-xs { - display: table-cell !important; - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .visible-sm { - display: block !important; - } - tr.visible-sm { - display: table-row !important; - } - th.visible-sm, - td.visible-sm { - display: table-cell !important; - } -} - -@media (min-width: 992px) and (max-width: 1199px) { - .visible-sm.visible-md { - display: block !important; - } - tr.visible-sm.visible-md { - display: table-row !important; - } - th.visible-sm.visible-md, - td.visible-sm.visible-md { - display: table-cell !important; - } -} - -@media (min-width: 1200px) { - .visible-sm.visible-lg { - display: block !important; - } - tr.visible-sm.visible-lg { - display: table-row !important; - } - th.visible-sm.visible-lg, - td.visible-sm.visible-lg { - display: table-cell !important; - } -} - -.visible-md { - display: none !important; -} - -tr.visible-md { - display: none !important; -} - -th.visible-md, -td.visible-md { - display: none !important; -} - -@media (max-width: 767px) { - .visible-md.visible-xs { - display: block !important; - } - tr.visible-md.visible-xs { - display: table-row !important; - } - th.visible-md.visible-xs, - td.visible-md.visible-xs { - display: table-cell !important; - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .visible-md.visible-sm { - display: block !important; - } - tr.visible-md.visible-sm { - display: table-row !important; - } - th.visible-md.visible-sm, - td.visible-md.visible-sm { - display: table-cell !important; - } -} - -@media (min-width: 992px) and (max-width: 1199px) { - .visible-md { - display: block !important; - } - tr.visible-md { - display: table-row !important; - } - th.visible-md, - td.visible-md { - display: table-cell !important; - } -} - -@media (min-width: 1200px) { - .visible-md.visible-lg { - display: block !important; - } - tr.visible-md.visible-lg { - display: table-row !important; - } - th.visible-md.visible-lg, - td.visible-md.visible-lg { - display: table-cell !important; - } -} - -.visible-lg { - display: none !important; -} - -tr.visible-lg { - display: none !important; -} - -th.visible-lg, -td.visible-lg { - display: none !important; -} - -@media (max-width: 767px) { - .visible-lg.visible-xs { - display: block !important; - } - tr.visible-lg.visible-xs { - display: table-row !important; - } - th.visible-lg.visible-xs, - td.visible-lg.visible-xs { - display: table-cell !important; - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .visible-lg.visible-sm { - display: block !important; - } - tr.visible-lg.visible-sm { - display: table-row !important; - } - th.visible-lg.visible-sm, - td.visible-lg.visible-sm { - display: table-cell !important; - } -} - -@media (min-width: 992px) and (max-width: 1199px) { - .visible-lg.visible-md { - display: block !important; - } - tr.visible-lg.visible-md { - display: table-row !important; - } - th.visible-lg.visible-md, - td.visible-lg.visible-md { - display: table-cell !important; - } -} - -@media (min-width: 1200px) { - .visible-lg { - display: block !important; - } - tr.visible-lg { - display: table-row !important; - } - th.visible-lg, - td.visible-lg { - display: table-cell !important; - } -} - -.hidden-xs { - display: block !important; -} - -tr.hidden-xs { - display: table-row !important; -} - -th.hidden-xs, -td.hidden-xs { - display: table-cell !important; -} - -@media (max-width: 767px) { - .hidden-xs { - display: none !important; - } - tr.hidden-xs { - display: none !important; - } - th.hidden-xs, - td.hidden-xs { - display: none !important; - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .hidden-xs.hidden-sm { - display: none !important; - } - tr.hidden-xs.hidden-sm { - display: none !important; - } - th.hidden-xs.hidden-sm, - td.hidden-xs.hidden-sm { - display: none !important; - } -} - -@media (min-width: 992px) and (max-width: 1199px) { - .hidden-xs.hidden-md { - display: none !important; - } - tr.hidden-xs.hidden-md { - display: none !important; - } - th.hidden-xs.hidden-md, - td.hidden-xs.hidden-md { - display: none !important; - } -} - -@media (min-width: 1200px) { - .hidden-xs.hidden-lg { - display: none !important; - } - tr.hidden-xs.hidden-lg { - display: none !important; - } - th.hidden-xs.hidden-lg, - td.hidden-xs.hidden-lg { - display: none !important; - } -} - -.hidden-sm { - display: block !important; -} - -tr.hidden-sm { - display: table-row !important; -} - -th.hidden-sm, -td.hidden-sm { - display: table-cell !important; -} - -@media (max-width: 767px) { - .hidden-sm.hidden-xs { - display: none !important; - } - tr.hidden-sm.hidden-xs { - display: none !important; - } - th.hidden-sm.hidden-xs, - td.hidden-sm.hidden-xs { - display: none !important; - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .hidden-sm { - display: none !important; - } - tr.hidden-sm { - display: none !important; - } - th.hidden-sm, - td.hidden-sm { - display: none !important; - } -} - -@media (min-width: 992px) and (max-width: 1199px) { - .hidden-sm.hidden-md { - display: none !important; - } - tr.hidden-sm.hidden-md { - display: none !important; - } - th.hidden-sm.hidden-md, - td.hidden-sm.hidden-md { - display: none !important; - } -} - -@media (min-width: 1200px) { - .hidden-sm.hidden-lg { - display: none !important; - } - tr.hidden-sm.hidden-lg { - display: none !important; - } - th.hidden-sm.hidden-lg, - td.hidden-sm.hidden-lg { - display: none !important; - } -} - -.hidden-md { - display: block !important; -} - -tr.hidden-md { - display: table-row !important; -} - -th.hidden-md, -td.hidden-md { - display: table-cell !important; -} - -@media (max-width: 767px) { - .hidden-md.hidden-xs { - display: none !important; - } - tr.hidden-md.hidden-xs { - display: none !important; - } - th.hidden-md.hidden-xs, - td.hidden-md.hidden-xs { - display: none !important; - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .hidden-md.hidden-sm { - display: none !important; - } - tr.hidden-md.hidden-sm { - display: none !important; - } - th.hidden-md.hidden-sm, - td.hidden-md.hidden-sm { - display: none !important; - } -} - -@media (min-width: 992px) and (max-width: 1199px) { - .hidden-md { - display: none !important; - } - tr.hidden-md { - display: none !important; - } - th.hidden-md, - td.hidden-md { - display: none !important; - } -} - -@media (min-width: 1200px) { - .hidden-md.hidden-lg { - display: none !important; - } - tr.hidden-md.hidden-lg { - display: none !important; - } - th.hidden-md.hidden-lg, - td.hidden-md.hidden-lg { - display: none !important; - } -} - -.hidden-lg { - display: block !important; -} - -tr.hidden-lg { - display: table-row !important; -} - -th.hidden-lg, -td.hidden-lg { - display: table-cell !important; -} - -@media (max-width: 767px) { - .hidden-lg.hidden-xs { - display: none !important; - } - tr.hidden-lg.hidden-xs { - display: none !important; - } - th.hidden-lg.hidden-xs, - td.hidden-lg.hidden-xs { - display: none !important; - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .hidden-lg.hidden-sm { - display: none !important; - } - tr.hidden-lg.hidden-sm { - display: none !important; - } - th.hidden-lg.hidden-sm, - td.hidden-lg.hidden-sm { - display: none !important; - } -} - -@media (min-width: 992px) and (max-width: 1199px) { - .hidden-lg.hidden-md { - display: none !important; - } - tr.hidden-lg.hidden-md { - display: none !important; - } - th.hidden-lg.hidden-md, - td.hidden-lg.hidden-md { - display: none !important; - } -} - -@media (min-width: 1200px) { - .hidden-lg { - display: none !important; - } - tr.hidden-lg { - display: none !important; - } - th.hidden-lg, - td.hidden-lg { - display: none !important; - } -} - -.visible-print { - display: none !important; -} - -tr.visible-print { - display: none !important; -} - -th.visible-print, -td.visible-print { - display: none !important; -} - -@media print { - .visible-print { - display: block !important; - } - tr.visible-print { - display: table-row !important; - } - th.visible-print, - td.visible-print { - display: table-cell !important; - } - .hidden-print { - display: none !important; - } - tr.hidden-print { - display: none !important; - } - th.hidden-print, - td.hidden-print { - display: none !important; - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Content/bootstrap.min.css b/dotnet/NotifyUsers/AppBackend/Content/bootstrap.min.css deleted file mode 100644 index df89a50..0000000 --- a/dotnet/NotifyUsers/AppBackend/Content/bootstrap.min.css +++ /dev/null @@ -1,20 +0,0 @@ -/* NUGET: BEGIN LICENSE TEXT - * - * Microsoft grants you the right to use these script files for the sole - * purpose of either: (i) interacting through your browser with the Microsoft - * website or online service, subject to the applicable licensing or use - * terms; or (ii) using the files as included with a Microsoft product subject - * to that product's license terms. Microsoft reserves all other rights to the - * files not expressly granted by Microsoft, whether by implication, estoppel - * or otherwise. The notices and licenses below are for informational purposes only. - * - * NUGET: END LICENSE TEXT */ -/*! - * Bootstrap v3.0.0 - * - * Copyright 2013 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world by @mdo and @fat. - *//*! normalize.css v2.1.0 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{margin:.67em 0;font-size:2em}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}hr{height:0;-moz-box-sizing:content-box;box-sizing:content-box}mark{color:#000;background:#ff0}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em}pre{white-space:pre-wrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid #c0c0c0}legend{padding:0;border:0}button,input,select,textarea{margin:0;font-family:inherit;font-size:100%}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{padding:0;box-sizing:border-box}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:2cm .5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.table td,.table th{background-color:#fff!important}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}*,*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:62.5%;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.428571429;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}button,input,select[multiple],textarea{background-image:none}a{color:#428bca;text-decoration:none}a:hover,a:focus{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}img{vertical-align:middle}.img-responsive{display:block;height:auto;max-width:100%}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;height:auto;max-width:100%;padding:4px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);border:0}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16.099999999999998px;font-weight:200;line-height:1.4}@media(min-width:768px){.lead{font-size:21px}}small{font-size:85%}cite{font-style:normal}.text-muted{color:#999}.text-primary{color:#428bca}.text-warning{color:#c09853}.text-danger{color:#b94a48}.text-success{color:#468847}.text-info{color:#3a87ad}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:500;line-height:1.1}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{margin-top:20px;margin-bottom:10px}h4,h5,h6{margin-top:10px;margin-bottom:10px}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}h1 small,.h1 small{font-size:24px}h2 small,.h2 small{font-size:18px}h3 small,.h3 small,h4 small,.h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-bottom:20px}dt,dd{line-height:1.428571429}dt{font-weight:bold}dd{margin-left:0}@media(min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{font-size:17.5px;font-weight:300;line-height:1.25}blockquote p:last-child{margin-bottom:0}blockquote small{display:block;line-height:1.428571429;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:1.428571429}code,pre{font-family:Monaco,Menlo,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;white-space:nowrap;background-color:#f9f2f4;border-radius:4px}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.428571429;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre.prettyprint{margin-bottom:20px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}.row{margin-right:-15px;margin-left:-15px}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11{float:left}.col-xs-1{width:8.333333333333332%}.col-xs-2{width:16.666666666666664%}.col-xs-3{width:25%}.col-xs-4{width:33.33333333333333%}.col-xs-5{width:41.66666666666667%}.col-xs-6{width:50%}.col-xs-7{width:58.333333333333336%}.col-xs-8{width:66.66666666666666%}.col-xs-9{width:75%}.col-xs-10{width:83.33333333333334%}.col-xs-11{width:91.66666666666666%}.col-xs-12{width:100%}@media(min-width:768px){.container{max-width:750px}.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11{float:left}.col-sm-1{width:8.333333333333332%}.col-sm-2{width:16.666666666666664%}.col-sm-3{width:25%}.col-sm-4{width:33.33333333333333%}.col-sm-5{width:41.66666666666667%}.col-sm-6{width:50%}.col-sm-7{width:58.333333333333336%}.col-sm-8{width:66.66666666666666%}.col-sm-9{width:75%}.col-sm-10{width:83.33333333333334%}.col-sm-11{width:91.66666666666666%}.col-sm-12{width:100%}.col-sm-push-1{left:8.333333333333332%}.col-sm-push-2{left:16.666666666666664%}.col-sm-push-3{left:25%}.col-sm-push-4{left:33.33333333333333%}.col-sm-push-5{left:41.66666666666667%}.col-sm-push-6{left:50%}.col-sm-push-7{left:58.333333333333336%}.col-sm-push-8{left:66.66666666666666%}.col-sm-push-9{left:75%}.col-sm-push-10{left:83.33333333333334%}.col-sm-push-11{left:91.66666666666666%}.col-sm-pull-1{right:8.333333333333332%}.col-sm-pull-2{right:16.666666666666664%}.col-sm-pull-3{right:25%}.col-sm-pull-4{right:33.33333333333333%}.col-sm-pull-5{right:41.66666666666667%}.col-sm-pull-6{right:50%}.col-sm-pull-7{right:58.333333333333336%}.col-sm-pull-8{right:66.66666666666666%}.col-sm-pull-9{right:75%}.col-sm-pull-10{right:83.33333333333334%}.col-sm-pull-11{right:91.66666666666666%}.col-sm-offset-1{margin-left:8.333333333333332%}.col-sm-offset-2{margin-left:16.666666666666664%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-4{margin-left:33.33333333333333%}.col-sm-offset-5{margin-left:41.66666666666667%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-7{margin-left:58.333333333333336%}.col-sm-offset-8{margin-left:66.66666666666666%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-10{margin-left:83.33333333333334%}.col-sm-offset-11{margin-left:91.66666666666666%}}@media(min-width:992px){.container{max-width:970px}.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11{float:left}.col-md-1{width:8.333333333333332%}.col-md-2{width:16.666666666666664%}.col-md-3{width:25%}.col-md-4{width:33.33333333333333%}.col-md-5{width:41.66666666666667%}.col-md-6{width:50%}.col-md-7{width:58.333333333333336%}.col-md-8{width:66.66666666666666%}.col-md-9{width:75%}.col-md-10{width:83.33333333333334%}.col-md-11{width:91.66666666666666%}.col-md-12{width:100%}.col-md-push-0{left:auto}.col-md-push-1{left:8.333333333333332%}.col-md-push-2{left:16.666666666666664%}.col-md-push-3{left:25%}.col-md-push-4{left:33.33333333333333%}.col-md-push-5{left:41.66666666666667%}.col-md-push-6{left:50%}.col-md-push-7{left:58.333333333333336%}.col-md-push-8{left:66.66666666666666%}.col-md-push-9{left:75%}.col-md-push-10{left:83.33333333333334%}.col-md-push-11{left:91.66666666666666%}.col-md-pull-0{right:auto}.col-md-pull-1{right:8.333333333333332%}.col-md-pull-2{right:16.666666666666664%}.col-md-pull-3{right:25%}.col-md-pull-4{right:33.33333333333333%}.col-md-pull-5{right:41.66666666666667%}.col-md-pull-6{right:50%}.col-md-pull-7{right:58.333333333333336%}.col-md-pull-8{right:66.66666666666666%}.col-md-pull-9{right:75%}.col-md-pull-10{right:83.33333333333334%}.col-md-pull-11{right:91.66666666666666%}.col-md-offset-0{margin-left:0}.col-md-offset-1{margin-left:8.333333333333332%}.col-md-offset-2{margin-left:16.666666666666664%}.col-md-offset-3{margin-left:25%}.col-md-offset-4{margin-left:33.33333333333333%}.col-md-offset-5{margin-left:41.66666666666667%}.col-md-offset-6{margin-left:50%}.col-md-offset-7{margin-left:58.333333333333336%}.col-md-offset-8{margin-left:66.66666666666666%}.col-md-offset-9{margin-left:75%}.col-md-offset-10{margin-left:83.33333333333334%}.col-md-offset-11{margin-left:91.66666666666666%}}@media(min-width:1200px){.container{max-width:1170px}.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11{float:left}.col-lg-1{width:8.333333333333332%}.col-lg-2{width:16.666666666666664%}.col-lg-3{width:25%}.col-lg-4{width:33.33333333333333%}.col-lg-5{width:41.66666666666667%}.col-lg-6{width:50%}.col-lg-7{width:58.333333333333336%}.col-lg-8{width:66.66666666666666%}.col-lg-9{width:75%}.col-lg-10{width:83.33333333333334%}.col-lg-11{width:91.66666666666666%}.col-lg-12{width:100%}.col-lg-push-0{left:auto}.col-lg-push-1{left:8.333333333333332%}.col-lg-push-2{left:16.666666666666664%}.col-lg-push-3{left:25%}.col-lg-push-4{left:33.33333333333333%}.col-lg-push-5{left:41.66666666666667%}.col-lg-push-6{left:50%}.col-lg-push-7{left:58.333333333333336%}.col-lg-push-8{left:66.66666666666666%}.col-lg-push-9{left:75%}.col-lg-push-10{left:83.33333333333334%}.col-lg-push-11{left:91.66666666666666%}.col-lg-pull-0{right:auto}.col-lg-pull-1{right:8.333333333333332%}.col-lg-pull-2{right:16.666666666666664%}.col-lg-pull-3{right:25%}.col-lg-pull-4{right:33.33333333333333%}.col-lg-pull-5{right:41.66666666666667%}.col-lg-pull-6{right:50%}.col-lg-pull-7{right:58.333333333333336%}.col-lg-pull-8{right:66.66666666666666%}.col-lg-pull-9{right:75%}.col-lg-pull-10{right:83.33333333333334%}.col-lg-pull-11{right:91.66666666666666%}.col-lg-offset-0{margin-left:0}.col-lg-offset-1{margin-left:8.333333333333332%}.col-lg-offset-2{margin-left:16.666666666666664%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-4{margin-left:33.33333333333333%}.col-lg-offset-5{margin-left:41.66666666666667%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-7{margin-left:58.333333333333336%}.col-lg-offset-8{margin-left:66.66666666666666%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-10{margin-left:83.33333333333334%}.col-lg-offset-11{margin-left:91.66666666666666%}}table{max-width:100%;background-color:transparent}th{text-align:left}.table{width:100%;margin-bottom:20px}.table thead>tr>th,.table tbody>tr>th,.table tfoot>tr>th,.table thead>tr>td,.table tbody>tr>td,.table tfoot>tr>td{padding:8px;line-height:1.428571429;vertical-align:top;border-top:1px solid #ddd}.table thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table caption+thead tr:first-child th,.table colgroup+thead tr:first-child th,.table thead:first-child tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed thead>tr>th,.table-condensed tbody>tr>th,.table-condensed tfoot>tr>th,.table-condensed thead>tr>td,.table-condensed tbody>tr>td,.table-condensed tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd)>td,.table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover>tbody>tr:hover>td,.table-hover>tbody>tr:hover>th{background-color:#f5f5f5}table col[class*="col-"]{display:table-column;float:none}table td[class*="col-"],table th[class*="col-"]{display:table-cell;float:none}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8;border-color:#d6e9c6}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td{background-color:#d0e9c6;border-color:#c9e2b3}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede;border-color:#eed3d7}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td{background-color:#ebcccc;border-color:#e6c1c7}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3;border-color:#fbeed5}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td{background-color:#faf2cc;border-color:#f8e5be}@media(max-width:768px){.table-responsive{width:100%;margin-bottom:15px;overflow-x:scroll;overflow-y:hidden;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0;background-color:#fff}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>thead>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>thead>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}select[multiple],select[size]{height:auto}select optgroup{font-family:inherit;font-size:inherit;font-style:inherit}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}input[type="number"]::-webkit-outer-spin-button,input[type="number"]::-webkit-inner-spin-button{height:auto}.form-control:-moz-placeholder{color:#999}.form-control::-moz-placeholder{color:#999}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.428571429;color:#555;vertical-align:middle;background-color:#fff;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee}textarea.form-control{height:auto}.form-group{margin-bottom:15px}.radio,.checkbox{display:block;min-height:20px;padding-left:20px;margin-top:10px;margin-bottom:10px;vertical-align:middle}.radio label,.checkbox label{display:inline;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{float:left;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:normal;vertical-align:middle;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],.radio[disabled],.radio-inline[disabled],.checkbox[disabled],.checkbox-inline[disabled],fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"],fieldset[disabled] .radio,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm{height:auto}.input-lg{height:45px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg{height:45px;line-height:45px}textarea.input-lg{height:auto}.has-warning .help-block,.has-warning .control-label{color:#c09853}.has-warning .form-control{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.has-warning .input-group-addon{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.has-error .help-block,.has-error .control-label{color:#b94a48}.has-error .form-control{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.has-error .input-group-addon{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.has-success .help-block,.has-success .control-label{color:#468847}.has-success .form-control{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.has-success .input-group-addon{color:#468847;background-color:#dff0d8;border-color:#468847}.form-control-static{padding-top:7px;margin-bottom:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media(min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block}.form-inline .radio,.form-inline .checkbox{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:none;margin-left:0}}.form-horizontal .control-label,.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}@media(min-width:768px){.form-horizontal .control-label{text-align:right}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:normal;line-height:1.428571429;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;border:1px solid transparent;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus{color:#333;text-decoration:none}.btn:active,.btn.active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{color:#333;background-color:#ebebeb;border-color:#adadad}.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{color:#fff;background-color:#3276b1;border-color:#285e8e}.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#428bca;border-color:#357ebd}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{color:#fff;background-color:#ed9c28;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{color:#fff;background-color:#d2322d;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{color:#fff;background-color:#47a447;border-color:#398439}.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{color:#fff;background-color:#39b3d7;border-color:#269abc}.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-link{font-weight:normal;color:#428bca;cursor:pointer;border-radius:0}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#2a6496;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#999;text-decoration:none}.btn-lg{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-xs{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs{padding:1px 5px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;transition:height .35s ease}@font-face{font-family:'Glyphicons Halflings';src:url('../fonts/glyphicons-halflings-regular.eot');src:url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url('../fonts/glyphicons-halflings-regular.woff') format('woff'),url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'),url('../fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular') format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';-webkit-font-smoothing:antialiased;font-style:normal;font-weight:normal;line-height:1}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-print:before{content:"\e045"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-briefcase:before{content:"\1f4bc"}.glyphicon-calendar:before{content:"\1f4c5"}.glyphicon-pushpin:before{content:"\1f4cc"}.glyphicon-paperclip:before{content:"\1f4ce"}.glyphicon-camera:before{content:"\1f4f7"}.glyphicon-lock:before{content:"\1f512"}.glyphicon-bell:before{content:"\1f514"}.glyphicon-bookmark:before{content:"\1f516"}.glyphicon-fire:before{content:"\1f525"}.glyphicon-wrench:before{content:"\1f527"}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid #000;border-right:4px solid transparent;border-bottom:0 dotted;border-left:4px solid transparent;content:""}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.428571429;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{color:#fff;text-decoration:none;background-color:#428bca}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#428bca;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.428571429;color:#999}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0 dotted;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media(min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}}.btn-default .caret{border-top-color:#333}.btn-primary .caret,.btn-success .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret{border-top-color:#fff}.dropup .btn-default .caret{border-bottom-color:#333}.dropup .btn-primary .caret,.dropup .btn-success .caret,.dropup .btn-warning .caret,.dropup .btn-danger .caret,.dropup .btn-info .caret{border-bottom-color:#fff}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group>.btn:focus,.btn-group-vertical>.btn:focus{outline:0}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar .btn-group{float:left}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group,.btn-toolbar>.btn-group+.btn-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group-xs>.btn{padding:5px 10px;padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-bottom-left-radius:4px;border-top-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child>.btn:last-child,.btn-group-vertical>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;border-collapse:separate;table-layout:fixed}.btn-group-justified .btn{display:table-cell;float:none;width:1%}[data-toggle="buttons"]>.btn>input[type="radio"],[data-toggle="buttons"]>.btn>input[type="checkbox"]{display:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group.col{float:none;padding-right:0;padding-left:0}.input-group .form-control{width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:45px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:45px;line-height:45px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:normal;line-height:1;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type="radio"],.input-group-addon input[type="checkbox"]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-4px}.input-group-btn>.btn:hover,.input-group-btn>.btn:active{z-index:2}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#999}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#999;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#428bca}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.428571429;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center}@media(min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}}.nav-tabs.nav-justified>li>a{margin-right:0;border-bottom:1px solid #ddd}.nav-tabs.nav-justified>.active>a{border-bottom-color:#fff}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:5px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#428bca}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{text-align:center}@media(min-width:768px){.nav-justified>li{display:table-cell;width:1%}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-bottom:1px solid #ddd}.nav-tabs-justified>.active>a{border-bottom-color:#fff}.tabbable:before,.tabbable:after{display:table;content:" "}.tabbable:after{clear:both}.tabbable:before,.tabbable:after{display:table;content:" "}.tabbable:after{clear:both}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.nav .caret{border-top-color:#428bca;border-bottom-color:#428bca}.nav a:hover .caret{border-top-color:#2a6496;border-bottom-color:#2a6496}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;z-index:1000;min-height:50px;margin-bottom:20px;border:1px solid transparent}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}@media(min-width:768px){.navbar{border-radius:4px}}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}@media(min-width:768px){.navbar-header{float:left}}.navbar-collapse{max-height:340px;padding-right:15px;padding-left:15px;overflow-x:visible;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse.in{overflow-y:auto}@media(min-width:768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-collapse .navbar-nav.navbar-left:first-child{margin-left:-15px}.navbar-collapse .navbar-nav.navbar-right:last-child{margin-right:-15px}.navbar-collapse .navbar-text:last-child{margin-right:0}}.container>.navbar-header,.container>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media(min-width:768px){.container>.navbar-header,.container>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{border-width:0 0 1px}@media(min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;border-width:0 0 1px}@media(min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;z-index:1030}.navbar-fixed-bottom{bottom:0;margin-bottom:0}.navbar-brand{float:left;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}@media(min-width:768px){.navbar>.container .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;border:1px solid transparent;border-radius:4px}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media(min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media(max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media(min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}@media(min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}@media(min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.navbar-form .radio input[type="radio"],.navbar-form .checkbox input[type="checkbox"]{float:none;margin-left:0}}@media(max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media(min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-nav.pull-right>li>.dropdown-menu,.navbar-nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-text{float:left;margin-top:15px;margin-bottom:15px}@media(min-width:768px){.navbar-text{margin-right:15px;margin-left:15px}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#ccc}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e6e6e6}.navbar-default .navbar-nav>.dropdown>a:hover .caret,.navbar-default .navbar-nav>.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.open>a .caret,.navbar-default .navbar-nav>.open>a:hover .caret,.navbar-default .navbar-nav>.open>a:focus .caret{border-top-color:#555;border-bottom-color:#555}.navbar-default .navbar-nav>.dropdown>a .caret{border-top-color:#777;border-bottom-color:#777}@media(max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#999}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .navbar-nav>li>a{color:#999}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.dropdown>a:hover .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-nav>.dropdown>a .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .navbar-nav>.open>a .caret,.navbar-inverse .navbar-nav>.open>a:hover .caret,.navbar-inverse .navbar-nav>.open>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}@media(max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#999}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover{color:#fff}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#999}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.428571429;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{background-color:#eee}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;cursor:default;background-color:#428bca;border-color:#428bca}.pagination>.disabled>span,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#999;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.label[href]:hover,.label[href]:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.label-default{background-color:#999}.label-default[href]:hover,.label-default[href]:focus{background-color:#808080}.label-primary{background-color:#428bca}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#999;border-radius:10px}.badge:empty{display:none}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.btn .badge{position:relative;top:-1px}a.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#428bca;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px;margin-bottom:30px;font-size:21px;font-weight:200;line-height:2.1428571435;color:inherit;background-color:#eee}.jumbotron h1{line-height:1;color:inherit}.jumbotron p{line-height:1.4}.container .jumbotron{border-radius:6px}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1{font-size:63px}}.thumbnail{display:inline-block;display:block;height:auto;max-width:100%;padding:4px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.thumbnail>img{display:block;height:auto;max-width:100%}a.thumbnail:hover,a.thumbnail:focus{border-color:#428bca}.thumbnail>img{margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:bold}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable{padding-right:35px}.alert-dismissable .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#356635}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#2d6987}.alert-warning{color:#c09853;background-color:#fcf8e3;border-color:#fbeed5}.alert-warning hr{border-top-color:#f8e5be}.alert-warning .alert-link{color:#a47e3c}.alert-danger{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-danger hr{border-top-color:#e6c1c7}.alert-danger .alert-link{color:#953b39}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;background-color:#428bca;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-size:40px 40px}.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.media,.media-body{overflow:hidden;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{text-decoration:none;background-color:#f5f5f5}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#e1edf7}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.panel-body{padding:15px}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel>.list-group{margin-bottom:0}.panel>.list-group .list-group-item{border-width:1px 0}.panel>.list-group .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.panel>.list-group .list-group-item:last-child{border-bottom:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.panel>.table{margin-bottom:0}.panel>.panel-body+.table{border-top:1px solid #ddd}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px}.panel-title{margin-top:0;margin-bottom:0;font-size:16px}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-group .panel{margin-bottom:0;overflow:hidden;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse .panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse .panel-body{border-top-color:#ddd}.panel-default>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#428bca}.panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.panel-primary>.panel-heading+.panel-collapse .panel-body{border-top-color:#428bca}.panel-primary>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#428bca}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse .panel-body{border-top-color:#d6e9c6}.panel-success>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#d6e9c6}.panel-warning{border-color:#fbeed5}.panel-warning>.panel-heading{color:#c09853;background-color:#fcf8e3;border-color:#fbeed5}.panel-warning>.panel-heading+.panel-collapse .panel-body{border-top-color:#fbeed5}.panel-warning>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#fbeed5}.panel-danger{border-color:#eed3d7}.panel-danger>.panel-heading{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.panel-danger>.panel-heading+.panel-collapse .panel-body{border-top-color:#eed3d7}.panel-danger>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#eed3d7}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse .panel-body{border-top-color:#bce8f1}.panel-info>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#bce8f1}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:bold;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}body.modal-open,.modal-open .navbar-fixed-top,.modal-open .navbar-fixed-bottom{margin-right:15px}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;display:none;overflow:auto;overflow-y:scroll}.modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);transform:translate(0,0)}.modal-dialog{z-index:1050;width:auto;padding:10px;margin-right:auto;margin-left:auto}.modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);background-clip:padding-box}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1030;background-color:#000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{min-height:16.428571429px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.428571429}.modal-body{position:relative;padding:20px}.modal-footer{padding:19px 20px 20px;margin-top:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}@media screen and (min-width:768px){.modal-dialog{right:auto;left:50%;width:600px;padding-top:30px;padding-bottom:30px}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,0.5);box-shadow:0 5px 15px rgba(0,0,0,0.5)}}.tooltip{position:absolute;z-index:1030;display:block;font-size:12px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.top-right .tooltip-arrow{right:5px;bottom:0;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-bottom-color:#000;border-width:0 5px 5px}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0;content:" "}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0;content:" "}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0;content:" "}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0;content:" "}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;height:auto;max-width:100%;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6);opacity:.5;filter:alpha(opacity=50)}.carousel-control.left{background-image:-webkit-gradient(linear,0 top,100% top,from(rgba(0,0,0,0.5)),to(rgba(0,0,0,0.0001)));background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,0.5) 0),color-stop(rgba(0,0,0,0.0001) 100%));background-image:-moz-linear-gradient(left,rgba(0,0,0,0.5) 0,rgba(0,0,0,0.0001) 100%);background-image:linear-gradient(to right,rgba(0,0,0,0.5) 0,rgba(0,0,0,0.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000',endColorstr='#00000000',GradientType=1)}.carousel-control.right{right:0;left:auto;background-image:-webkit-gradient(linear,0 top,100% top,from(rgba(0,0,0,0.0001)),to(rgba(0,0,0,0.5)));background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,0.0001) 0),color-stop(rgba(0,0,0,0.5) 100%));background-image:-moz-linear-gradient(left,rgba(0,0,0,0.0001) 0,rgba(0,0,0,0.5) 100%);background-image:linear-gradient(to right,rgba(0,0,0,0.0001) 0,rgba(0,0,0,0.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000',endColorstr='#80000000',GradientType=1)}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;left:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;margin-left:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;margin-left:-15px;font-size:30px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after{display:table;content:" "}.clearfix:after{clear:both}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.affix{position:fixed}@-ms-viewport{width:device-width}@media screen and (max-width:400px){@-ms-viewport{width:320px}}.hidden{display:none!important;visibility:hidden!important}.visible-xs{display:none!important}tr.visible-xs{display:none!important}th.visible-xs,td.visible-xs{display:none!important}@media(max-width:767px){.visible-xs{display:block!important}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-xs.visible-sm{display:block!important}tr.visible-xs.visible-sm{display:table-row!important}th.visible-xs.visible-sm,td.visible-xs.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-xs.visible-md{display:block!important}tr.visible-xs.visible-md{display:table-row!important}th.visible-xs.visible-md,td.visible-xs.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-xs.visible-lg{display:block!important}tr.visible-xs.visible-lg{display:table-row!important}th.visible-xs.visible-lg,td.visible-xs.visible-lg{display:table-cell!important}}.visible-sm{display:none!important}tr.visible-sm{display:none!important}th.visible-sm,td.visible-sm{display:none!important}@media(max-width:767px){.visible-sm.visible-xs{display:block!important}tr.visible-sm.visible-xs{display:table-row!important}th.visible-sm.visible-xs,td.visible-sm.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-sm{display:block!important}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-sm.visible-md{display:block!important}tr.visible-sm.visible-md{display:table-row!important}th.visible-sm.visible-md,td.visible-sm.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-sm.visible-lg{display:block!important}tr.visible-sm.visible-lg{display:table-row!important}th.visible-sm.visible-lg,td.visible-sm.visible-lg{display:table-cell!important}}.visible-md{display:none!important}tr.visible-md{display:none!important}th.visible-md,td.visible-md{display:none!important}@media(max-width:767px){.visible-md.visible-xs{display:block!important}tr.visible-md.visible-xs{display:table-row!important}th.visible-md.visible-xs,td.visible-md.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-md.visible-sm{display:block!important}tr.visible-md.visible-sm{display:table-row!important}th.visible-md.visible-sm,td.visible-md.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-md{display:block!important}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-md.visible-lg{display:block!important}tr.visible-md.visible-lg{display:table-row!important}th.visible-md.visible-lg,td.visible-md.visible-lg{display:table-cell!important}}.visible-lg{display:none!important}tr.visible-lg{display:none!important}th.visible-lg,td.visible-lg{display:none!important}@media(max-width:767px){.visible-lg.visible-xs{display:block!important}tr.visible-lg.visible-xs{display:table-row!important}th.visible-lg.visible-xs,td.visible-lg.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-lg.visible-sm{display:block!important}tr.visible-lg.visible-sm{display:table-row!important}th.visible-lg.visible-sm,td.visible-lg.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-lg.visible-md{display:block!important}tr.visible-lg.visible-md{display:table-row!important}th.visible-lg.visible-md,td.visible-lg.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-lg{display:block!important}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}.hidden-xs{display:block!important}tr.hidden-xs{display:table-row!important}th.hidden-xs,td.hidden-xs{display:table-cell!important}@media(max-width:767px){.hidden-xs{display:none!important}tr.hidden-xs{display:none!important}th.hidden-xs,td.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-xs.hidden-sm{display:none!important}tr.hidden-xs.hidden-sm{display:none!important}th.hidden-xs.hidden-sm,td.hidden-xs.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-xs.hidden-md{display:none!important}tr.hidden-xs.hidden-md{display:none!important}th.hidden-xs.hidden-md,td.hidden-xs.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-xs.hidden-lg{display:none!important}tr.hidden-xs.hidden-lg{display:none!important}th.hidden-xs.hidden-lg,td.hidden-xs.hidden-lg{display:none!important}}.hidden-sm{display:block!important}tr.hidden-sm{display:table-row!important}th.hidden-sm,td.hidden-sm{display:table-cell!important}@media(max-width:767px){.hidden-sm.hidden-xs{display:none!important}tr.hidden-sm.hidden-xs{display:none!important}th.hidden-sm.hidden-xs,td.hidden-sm.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}tr.hidden-sm{display:none!important}th.hidden-sm,td.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-sm.hidden-md{display:none!important}tr.hidden-sm.hidden-md{display:none!important}th.hidden-sm.hidden-md,td.hidden-sm.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-sm.hidden-lg{display:none!important}tr.hidden-sm.hidden-lg{display:none!important}th.hidden-sm.hidden-lg,td.hidden-sm.hidden-lg{display:none!important}}.hidden-md{display:block!important}tr.hidden-md{display:table-row!important}th.hidden-md,td.hidden-md{display:table-cell!important}@media(max-width:767px){.hidden-md.hidden-xs{display:none!important}tr.hidden-md.hidden-xs{display:none!important}th.hidden-md.hidden-xs,td.hidden-md.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-md.hidden-sm{display:none!important}tr.hidden-md.hidden-sm{display:none!important}th.hidden-md.hidden-sm,td.hidden-md.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}tr.hidden-md{display:none!important}th.hidden-md,td.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-md.hidden-lg{display:none!important}tr.hidden-md.hidden-lg{display:none!important}th.hidden-md.hidden-lg,td.hidden-md.hidden-lg{display:none!important}}.hidden-lg{display:block!important}tr.hidden-lg{display:table-row!important}th.hidden-lg,td.hidden-lg{display:table-cell!important}@media(max-width:767px){.hidden-lg.hidden-xs{display:none!important}tr.hidden-lg.hidden-xs{display:none!important}th.hidden-lg.hidden-xs,td.hidden-lg.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-lg.hidden-sm{display:none!important}tr.hidden-lg.hidden-sm{display:none!important}th.hidden-lg.hidden-sm,td.hidden-lg.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-lg.hidden-md{display:none!important}tr.hidden-lg.hidden-md{display:none!important}th.hidden-lg.hidden-md,td.hidden-lg.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-lg{display:none!important}tr.hidden-lg{display:none!important}th.hidden-lg,td.hidden-lg{display:none!important}}.visible-print{display:none!important}tr.visible-print{display:none!important}th.visible-print,td.visible-print{display:none!important}@media print{.visible-print{display:block!important}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}.hidden-print{display:none!important}tr.hidden-print{display:none!important}th.hidden-print,td.hidden-print{display:none!important}} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Controllers/AccountController.cs b/dotnet/NotifyUsers/AppBackend/Controllers/AccountController.cs deleted file mode 100644 index a1059b3..0000000 --- a/dotnet/NotifyUsers/AppBackend/Controllers/AccountController.cs +++ /dev/null @@ -1,494 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Security.Claims; -using System.Security.Cryptography; -using System.Threading.Tasks; -using System.Web; -using System.Web.Http; -using System.Web.Http.ModelBinding; -using Microsoft.AspNet.Identity; -using Microsoft.AspNet.Identity.EntityFramework; -using Microsoft.AspNet.Identity.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Cookies; -using Microsoft.Owin.Security.OAuth; -using AppBackend.Models; -using AppBackend.Providers; -using AppBackend.Results; - -namespace AppBackend.Controllers -{ - [Authorize] - [RoutePrefix("api/Account")] - public class AccountController : ApiController - { - private const string LocalLoginProvider = "Local"; - private ApplicationUserManager _userManager; - - public AccountController() - { - } - - public AccountController(ApplicationUserManager userManager, - ISecureDataFormat accessTokenFormat) - { - UserManager = userManager; - AccessTokenFormat = accessTokenFormat; - } - - public ApplicationUserManager UserManager - { - get - { - return _userManager ?? Request.GetOwinContext().GetUserManager(); - } - private set - { - _userManager = value; - } - } - - public ISecureDataFormat AccessTokenFormat { get; private set; } - - // GET api/Account/UserInfo - [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)] - [Route("UserInfo")] - public UserInfoViewModel GetUserInfo() - { - ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity); - - return new UserInfoViewModel - { - Email = User.Identity.GetUserName(), - HasRegistered = externalLogin == null, - LoginProvider = externalLogin != null ? externalLogin.LoginProvider : null - }; - } - - // POST api/Account/Logout - [Route("Logout")] - public IHttpActionResult Logout() - { - Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType); - return Ok(); - } - - // GET api/Account/ManageInfo?returnUrl=%2F&generateState=true - [Route("ManageInfo")] - public async Task GetManageInfo(string returnUrl, bool generateState = false) - { - IdentityUser user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); - - if (user == null) - { - return null; - } - - List logins = new List(); - - foreach (IdentityUserLogin linkedAccount in user.Logins) - { - logins.Add(new UserLoginInfoViewModel - { - LoginProvider = linkedAccount.LoginProvider, - ProviderKey = linkedAccount.ProviderKey - }); - } - - if (user.PasswordHash != null) - { - logins.Add(new UserLoginInfoViewModel - { - LoginProvider = LocalLoginProvider, - ProviderKey = user.UserName, - }); - } - - return new ManageInfoViewModel - { - LocalLoginProvider = LocalLoginProvider, - Email = user.UserName, - Logins = logins, - ExternalLoginProviders = GetExternalLogins(returnUrl, generateState) - }; - } - - // POST api/Account/ChangePassword - [Route("ChangePassword")] - public async Task ChangePassword(ChangePasswordBindingModel model) - { - if (!ModelState.IsValid) - { - return BadRequest(ModelState); - } - - IdentityResult result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword, - model.NewPassword); - - if (!result.Succeeded) - { - return GetErrorResult(result); - } - - return Ok(); - } - - // POST api/Account/SetPassword - [Route("SetPassword")] - public async Task SetPassword(SetPasswordBindingModel model) - { - if (!ModelState.IsValid) - { - return BadRequest(ModelState); - } - - IdentityResult result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword); - - if (!result.Succeeded) - { - return GetErrorResult(result); - } - - return Ok(); - } - - // POST api/Account/AddExternalLogin - [Route("AddExternalLogin")] - public async Task AddExternalLogin(AddExternalLoginBindingModel model) - { - if (!ModelState.IsValid) - { - return BadRequest(ModelState); - } - - Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie); - - AuthenticationTicket ticket = AccessTokenFormat.Unprotect(model.ExternalAccessToken); - - if (ticket == null || ticket.Identity == null || (ticket.Properties != null - && ticket.Properties.ExpiresUtc.HasValue - && ticket.Properties.ExpiresUtc.Value < DateTimeOffset.UtcNow)) - { - return BadRequest("External login failure."); - } - - ExternalLoginData externalData = ExternalLoginData.FromIdentity(ticket.Identity); - - if (externalData == null) - { - return BadRequest("The external login is already associated with an account."); - } - - IdentityResult result = await UserManager.AddLoginAsync(User.Identity.GetUserId(), - new UserLoginInfo(externalData.LoginProvider, externalData.ProviderKey)); - - if (!result.Succeeded) - { - return GetErrorResult(result); - } - - return Ok(); - } - - // POST api/Account/RemoveLogin - [Route("RemoveLogin")] - public async Task RemoveLogin(RemoveLoginBindingModel model) - { - if (!ModelState.IsValid) - { - return BadRequest(ModelState); - } - - IdentityResult result; - - if (model.LoginProvider == LocalLoginProvider) - { - result = await UserManager.RemovePasswordAsync(User.Identity.GetUserId()); - } - else - { - result = await UserManager.RemoveLoginAsync(User.Identity.GetUserId(), - new UserLoginInfo(model.LoginProvider, model.ProviderKey)); - } - - if (!result.Succeeded) - { - return GetErrorResult(result); - } - - return Ok(); - } - - // GET api/Account/ExternalLogin - [OverrideAuthentication] - [HostAuthentication(DefaultAuthenticationTypes.ExternalCookie)] - [AllowAnonymous] - [Route("ExternalLogin", Name = "ExternalLogin")] - public async Task GetExternalLogin(string provider, string error = null) - { - if (error != null) - { - return Redirect(Url.Content("~/") + "#error=" + Uri.EscapeDataString(error)); - } - - if (!User.Identity.IsAuthenticated) - { - return new ChallengeResult(provider, this); - } - - ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity); - - if (externalLogin == null) - { - return InternalServerError(); - } - - if (externalLogin.LoginProvider != provider) - { - Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie); - return new ChallengeResult(provider, this); - } - - ApplicationUser user = await UserManager.FindAsync(new UserLoginInfo(externalLogin.LoginProvider, - externalLogin.ProviderKey)); - - bool hasRegistered = user != null; - - if (hasRegistered) - { - Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie); - - ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager, - OAuthDefaults.AuthenticationType); - ClaimsIdentity cookieIdentity = await user.GenerateUserIdentityAsync(UserManager, - CookieAuthenticationDefaults.AuthenticationType); - - AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName); - Authentication.SignIn(properties, oAuthIdentity, cookieIdentity); - } - else - { - IEnumerable claims = externalLogin.GetClaims(); - ClaimsIdentity identity = new ClaimsIdentity(claims, OAuthDefaults.AuthenticationType); - Authentication.SignIn(identity); - } - - return Ok(); - } - - // GET api/Account/ExternalLogins?returnUrl=%2F&generateState=true - [AllowAnonymous] - [Route("ExternalLogins")] - public IEnumerable GetExternalLogins(string returnUrl, bool generateState = false) - { - IEnumerable descriptions = Authentication.GetExternalAuthenticationTypes(); - List logins = new List(); - - string state; - - if (generateState) - { - const int strengthInBits = 256; - state = RandomOAuthStateGenerator.Generate(strengthInBits); - } - else - { - state = null; - } - - foreach (AuthenticationDescription description in descriptions) - { - ExternalLoginViewModel login = new ExternalLoginViewModel - { - Name = description.Caption, - Url = Url.Route("ExternalLogin", new - { - provider = description.AuthenticationType, - response_type = "token", - client_id = Startup.PublicClientId, - redirect_uri = new Uri(Request.RequestUri, returnUrl).AbsoluteUri, - state = state - }), - State = state - }; - logins.Add(login); - } - - return logins; - } - - // POST api/Account/Register - [AllowAnonymous] - [Route("Register")] - public async Task Register(RegisterBindingModel model) - { - if (!ModelState.IsValid) - { - return BadRequest(ModelState); - } - - var user = new ApplicationUser() { UserName = model.Email, Email = model.Email }; - - IdentityResult result = await UserManager.CreateAsync(user, model.Password); - - if (!result.Succeeded) - { - return GetErrorResult(result); - } - - return Ok(); - } - - // POST api/Account/RegisterExternal - [OverrideAuthentication] - [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)] - [Route("RegisterExternal")] - public async Task RegisterExternal(RegisterExternalBindingModel model) - { - if (!ModelState.IsValid) - { - return BadRequest(ModelState); - } - - var info = await Authentication.GetExternalLoginInfoAsync(); - if (info == null) - { - return InternalServerError(); - } - - var user = new ApplicationUser() { UserName = model.Email, Email = model.Email }; - - IdentityResult result = await UserManager.CreateAsync(user); - if (!result.Succeeded) - { - return GetErrorResult(result); - } - - result = await UserManager.AddLoginAsync(user.Id, info.Login); - if (!result.Succeeded) - { - return GetErrorResult(result); - } - return Ok(); - } - - protected override void Dispose(bool disposing) - { - if (disposing && _userManager != null) - { - _userManager.Dispose(); - _userManager = null; - } - - base.Dispose(disposing); - } - - #region Helpers - - private IAuthenticationManager Authentication - { - get { return Request.GetOwinContext().Authentication; } - } - - private IHttpActionResult GetErrorResult(IdentityResult result) - { - if (result == null) - { - return InternalServerError(); - } - - if (!result.Succeeded) - { - if (result.Errors != null) - { - foreach (string error in result.Errors) - { - ModelState.AddModelError("", error); - } - } - - if (ModelState.IsValid) - { - // No ModelState errors are available to send, so just return an empty BadRequest. - return BadRequest(); - } - - return BadRequest(ModelState); - } - - return null; - } - - private class ExternalLoginData - { - public string LoginProvider { get; set; } - public string ProviderKey { get; set; } - public string UserName { get; set; } - - public IList GetClaims() - { - IList claims = new List(); - claims.Add(new Claim(ClaimTypes.NameIdentifier, ProviderKey, null, LoginProvider)); - - if (UserName != null) - { - claims.Add(new Claim(ClaimTypes.Name, UserName, null, LoginProvider)); - } - - return claims; - } - - public static ExternalLoginData FromIdentity(ClaimsIdentity identity) - { - if (identity == null) - { - return null; - } - - Claim providerKeyClaim = identity.FindFirst(ClaimTypes.NameIdentifier); - - if (providerKeyClaim == null || String.IsNullOrEmpty(providerKeyClaim.Issuer) - || String.IsNullOrEmpty(providerKeyClaim.Value)) - { - return null; - } - - if (providerKeyClaim.Issuer == ClaimsIdentity.DefaultIssuer) - { - return null; - } - - return new ExternalLoginData - { - LoginProvider = providerKeyClaim.Issuer, - ProviderKey = providerKeyClaim.Value, - UserName = identity.FindFirstValue(ClaimTypes.Name) - }; - } - } - - private static class RandomOAuthStateGenerator - { - private static RandomNumberGenerator _random = new RNGCryptoServiceProvider(); - - public static string Generate(int strengthInBits) - { - const int bitsPerByte = 8; - - if (strengthInBits % bitsPerByte != 0) - { - throw new ArgumentException("strengthInBits must be evenly divisible by 8.", "strengthInBits"); - } - - int strengthInBytes = strengthInBits / bitsPerByte; - - byte[] data = new byte[strengthInBytes]; - _random.GetBytes(data); - return HttpServerUtility.UrlTokenEncode(data); - } - } - - #endregion - } -} diff --git a/dotnet/NotifyUsers/AppBackend/Controllers/HomeController.cs b/dotnet/NotifyUsers/AppBackend/Controllers/HomeController.cs deleted file mode 100644 index ee7ee7e..0000000 --- a/dotnet/NotifyUsers/AppBackend/Controllers/HomeController.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; -using System.Web.Mvc; - -namespace AppBackend.Controllers -{ - public class HomeController : Controller - { - public ActionResult Index() - { - ViewBag.Title = "Home Page"; - - return View(); - } - } -} diff --git a/dotnet/NotifyUsers/AppBackend/Controllers/NotificationsController.cs b/dotnet/NotifyUsers/AppBackend/Controllers/NotificationsController.cs deleted file mode 100644 index 55a0ed7..0000000 --- a/dotnet/NotifyUsers/AppBackend/Controllers/NotificationsController.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Web.Http; - -using AppBackend.Models; -using System.Threading.Tasks; -using System.Web; - - -namespace AppBackend.Controllers -{ - public class NotificationsController : ApiController - { - public async Task Post(string pns, [FromBody]string message, string to_tag) - { - var user = HttpContext.Current.User.Identity.Name; - string[] userTag = new string[2]; - userTag[0] = "username:" + to_tag; - userTag[1] = "from:" + user; - - Microsoft.Azure.NotificationHubs.NotificationOutcome outcome = null; - HttpStatusCode ret = HttpStatusCode.InternalServerError; - - switch (pns.ToLower()) - { - case "wns": - // Windows 8.1 / Windows Phone 8.1 - var toast = @"" + - "From " + user + ": " + message + ""; - outcome = await Notifications.Instance.Hub.SendWindowsNativeNotificationAsync(toast, userTag); - - // Windows 10 specific Action Center support - toast = @"" + - "From " + user + ": " + message + ""; - outcome = await Notifications.Instance.Hub.SendWindowsNativeNotificationAsync(toast, userTag); - - // Additionally sending Windows Phone Notification MPNS - //toast = "" + - // "" + - // "From " + user + ": " + message + - // ""; - //outcome = await Notifications.Instance.Hub.SendMpnsNativeNotificationAsync(toast, userTag); - - break; - case "apns": - // iOS - var alert = "{\"aps\":{\"alert\":\"" + "From " + user + ": " + message + "\"}}"; - outcome = await Notifications.Instance.Hub.SendAppleNativeNotificationAsync(alert, userTag); - break; - case "gcm": - // Android - var notif = "{ \"data\" : {\"message\":\"" + "From " + user + ": " + message + "\"}}"; - outcome = await Notifications.Instance.Hub.SendGcmNativeNotificationAsync(notif, userTag); - break; - } - - if (outcome != null) - { - if (!((outcome.State == Microsoft.Azure.NotificationHubs.NotificationOutcomeState.Abandoned) || - (outcome.State == Microsoft.Azure.NotificationHubs.NotificationOutcomeState.Unknown))) - { - ret = HttpStatusCode.OK; - } - } - - return Request.CreateResponse(ret); - } - } -} diff --git a/dotnet/NotifyUsers/AppBackend/Controllers/RegisterController.cs b/dotnet/NotifyUsers/AppBackend/Controllers/RegisterController.cs deleted file mode 100644 index 0e6b8f9..0000000 --- a/dotnet/NotifyUsers/AppBackend/Controllers/RegisterController.cs +++ /dev/null @@ -1,122 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Web.Http; - -using Microsoft.Azure.NotificationHubs; -using AppBackend.Models; -using System.Threading.Tasks; -using Microsoft.Azure.NotificationHubs.Messaging; -using System.Web; - -namespace AppBackend.Controllers -{ - public class RegisterController : ApiController - { - private NotificationHubClient hub; - - public RegisterController() - { - hub = Notifications.Instance.Hub; - } - - public class DeviceRegistration - { - public string Platform { get; set; } - public string Handle { get; set; } - public string[] Tags { get; set; } - } - - // POST api/register - // This creates a registration id - public async Task Post(string handle = null) - { - string newRegistrationId = null; - - // make sure there are no existing registrations for this push handle (used for iOS and Android) - if (handle != null) - { - var registrations = await hub.GetRegistrationsByChannelAsync(handle, 100); - - foreach (RegistrationDescription registration in registrations) - { - if (newRegistrationId == null) - { - newRegistrationId = registration.RegistrationId; - } - else - { - await hub.DeleteRegistrationAsync(registration); - } - } - } - - if (newRegistrationId == null) - newRegistrationId = await hub.CreateRegistrationIdAsync(); - - return newRegistrationId; - } - - // PUT api/register/5 - // This creates or updates a registration (with provided channelURI) at the specified id - public async Task Put(string id, DeviceRegistration deviceUpdate) - { - RegistrationDescription registration = null; - switch (deviceUpdate.Platform) - { - case "mpns": - registration = new MpnsRegistrationDescription(deviceUpdate.Handle); - break; - case "wns": - registration = new WindowsRegistrationDescription(deviceUpdate.Handle); - break; - case "apns": - registration = new AppleRegistrationDescription(deviceUpdate.Handle); - break; - case "gcm": - registration = new GcmRegistrationDescription(deviceUpdate.Handle); - break; - default: - throw new HttpResponseException(HttpStatusCode.BadRequest); - } - - registration.RegistrationId = id; - var username = HttpContext.Current.User.Identity.Name; - - // add check if user is allowed to add these tags - registration.Tags = new HashSet(deviceUpdate.Tags); - registration.Tags.Add("username:" + username); - - try - { - await hub.CreateOrUpdateRegistrationAsync(registration); - } - catch (MessagingException e) - { - ReturnGoneIfHubResponseIsGone(e); - } - - return Request.CreateResponse(HttpStatusCode.OK); - } - - // DELETE api/register/5 - public async Task Delete(string id) - { - await hub.DeleteRegistrationAsync(id); - return Request.CreateResponse(HttpStatusCode.OK); - } - - private static void ReturnGoneIfHubResponseIsGone(MessagingException e) - { - var webex = e.InnerException as WebException; - if (webex.Status == WebExceptionStatus.ProtocolError) - { - var response = (HttpWebResponse)webex.Response; - if (response.StatusCode == HttpStatusCode.Gone) - throw new HttpRequestException(HttpStatusCode.Gone.ToString()); - } - } - } -} diff --git a/dotnet/NotifyUsers/AppBackend/Controllers/ValuesController.cs b/dotnet/NotifyUsers/AppBackend/Controllers/ValuesController.cs deleted file mode 100644 index bf37f5b..0000000 --- a/dotnet/NotifyUsers/AppBackend/Controllers/ValuesController.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Web.Http; - -namespace AppBackend.Controllers -{ - [Authorize] - public class ValuesController : ApiController - { - // GET api/values - public IEnumerable Get() - { - return new string[] { "value1", "value2" }; - } - - // GET api/values/5 - public string Get(int id) - { - return "value"; - } - - // POST api/values - public void Post([FromBody]string value) - { - } - - // PUT api/values/5 - public void Put(int id, [FromBody]string value) - { - } - - // DELETE api/values/5 - public void Delete(int id) - { - } - } -} diff --git a/dotnet/NotifyUsers/AppBackend/Global.asax b/dotnet/NotifyUsers/AppBackend/Global.asax deleted file mode 100644 index 96b9789..0000000 --- a/dotnet/NotifyUsers/AppBackend/Global.asax +++ /dev/null @@ -1 +0,0 @@ -<%@ Application Codebehind="Global.asax.cs" Inherits="AppBackend.WebApiApplication" Language="C#" %> diff --git a/dotnet/NotifyUsers/AppBackend/Global.asax.cs b/dotnet/NotifyUsers/AppBackend/Global.asax.cs deleted file mode 100644 index 637d32c..0000000 --- a/dotnet/NotifyUsers/AppBackend/Global.asax.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; -using System.Web.Http; -using System.Web.Mvc; -using System.Web.Optimization; -using System.Web.Routing; - -namespace AppBackend -{ - public class WebApiApplication : System.Web.HttpApplication - { - protected void Application_Start() - { - AreaRegistration.RegisterAllAreas(); - GlobalConfiguration.Configure(WebApiConfig.Register); - FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); - RouteConfig.RegisterRoutes(RouteTable.Routes); - BundleConfig.RegisterBundles(BundleTable.Bundles); - } - } -} diff --git a/dotnet/NotifyUsers/AppBackend/Models/AccountBindingModels.cs b/dotnet/NotifyUsers/AppBackend/Models/AccountBindingModels.cs deleted file mode 100644 index 88a58aa..0000000 --- a/dotnet/NotifyUsers/AppBackend/Models/AccountBindingModels.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; -using Newtonsoft.Json; - -namespace AppBackend.Models -{ - // Models used as parameters to AccountController actions. - - public class AddExternalLoginBindingModel - { - [Required] - [Display(Name = "External access token")] - public string ExternalAccessToken { get; set; } - } - - public class ChangePasswordBindingModel - { - [Required] - [DataType(DataType.Password)] - [Display(Name = "Current password")] - public string OldPassword { get; set; } - - [Required] - [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] - [DataType(DataType.Password)] - [Display(Name = "New password")] - public string NewPassword { get; set; } - - [DataType(DataType.Password)] - [Display(Name = "Confirm new password")] - [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] - public string ConfirmPassword { get; set; } - } - - public class RegisterBindingModel - { - [Required] - [Display(Name = "Email")] - public string Email { get; set; } - - [Required] - [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] - [DataType(DataType.Password)] - [Display(Name = "Password")] - public string Password { get; set; } - - [DataType(DataType.Password)] - [Display(Name = "Confirm password")] - [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] - public string ConfirmPassword { get; set; } - } - - public class RegisterExternalBindingModel - { - [Required] - [Display(Name = "Email")] - public string Email { get; set; } - } - - public class RemoveLoginBindingModel - { - [Required] - [Display(Name = "Login provider")] - public string LoginProvider { get; set; } - - [Required] - [Display(Name = "Provider key")] - public string ProviderKey { get; set; } - } - - public class SetPasswordBindingModel - { - [Required] - [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] - [DataType(DataType.Password)] - [Display(Name = "New password")] - public string NewPassword { get; set; } - - [DataType(DataType.Password)] - [Display(Name = "Confirm new password")] - [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] - public string ConfirmPassword { get; set; } - } -} diff --git a/dotnet/NotifyUsers/AppBackend/Models/AccountViewModels.cs b/dotnet/NotifyUsers/AppBackend/Models/AccountViewModels.cs deleted file mode 100644 index b81962e..0000000 --- a/dotnet/NotifyUsers/AppBackend/Models/AccountViewModels.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace AppBackend.Models -{ - // Models returned by AccountController actions. - - public class ExternalLoginViewModel - { - public string Name { get; set; } - - public string Url { get; set; } - - public string State { get; set; } - } - - public class ManageInfoViewModel - { - public string LocalLoginProvider { get; set; } - - public string Email { get; set; } - - public IEnumerable Logins { get; set; } - - public IEnumerable ExternalLoginProviders { get; set; } - } - - public class UserInfoViewModel - { - public string Email { get; set; } - - public bool HasRegistered { get; set; } - - public string LoginProvider { get; set; } - } - - public class UserLoginInfoViewModel - { - public string LoginProvider { get; set; } - - public string ProviderKey { get; set; } - } -} diff --git a/dotnet/NotifyUsers/AppBackend/Models/IdentityModels.cs b/dotnet/NotifyUsers/AppBackend/Models/IdentityModels.cs deleted file mode 100644 index 3a6f0bc..0000000 --- a/dotnet/NotifyUsers/AppBackend/Models/IdentityModels.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Security.Claims; -using System.Threading.Tasks; -using Microsoft.AspNet.Identity; -using Microsoft.AspNet.Identity.EntityFramework; -using Microsoft.AspNet.Identity.Owin; - -namespace AppBackend.Models -{ - // You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more. - public class ApplicationUser : IdentityUser - { - public async Task GenerateUserIdentityAsync(UserManager manager, string authenticationType) - { - // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType - var userIdentity = await manager.CreateIdentityAsync(this, authenticationType); - // Add custom user claims here - return userIdentity; - } - } - - public class ApplicationDbContext : IdentityDbContext - { - public ApplicationDbContext() - : base("DefaultConnection", throwIfV1Schema: false) - { - } - - public static ApplicationDbContext Create() - { - return new ApplicationDbContext(); - } - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Models/Notifications.cs b/dotnet/NotifyUsers/AppBackend/Models/Notifications.cs deleted file mode 100644 index d5341d8..0000000 --- a/dotnet/NotifyUsers/AppBackend/Models/Notifications.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Microsoft.Azure.NotificationHubs; - -namespace AppBackend.Models -{ - public class Notifications - { - public static Notifications Instance = new Notifications(); - - public NotificationHubClient Hub { get; set; } - - private Notifications() - { -// Hub = NotificationHubClient.CreateClientFromConnectionString(" - - - - Your ASP.NET application - - - - - - - - - diff --git a/dotnet/NotifyUsers/AppBackend/Properties/AssemblyInfo.cs b/dotnet/NotifyUsers/AppBackend/Properties/AssemblyInfo.cs deleted file mode 100644 index efe9796..0000000 --- a/dotnet/NotifyUsers/AppBackend/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("AppBackend")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("AppBackend")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("554d106d-e0dd-4150-9ac5-e16ab93cbea3")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/dotnet/NotifyUsers/AppBackend/Providers/ApplicationOAuthProvider.cs b/dotnet/NotifyUsers/AppBackend/Providers/ApplicationOAuthProvider.cs deleted file mode 100644 index c67c072..0000000 --- a/dotnet/NotifyUsers/AppBackend/Providers/ApplicationOAuthProvider.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Claims; -using System.Threading.Tasks; -using Microsoft.AspNet.Identity; -using Microsoft.AspNet.Identity.EntityFramework; -using Microsoft.AspNet.Identity.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Cookies; -using Microsoft.Owin.Security.OAuth; -using AppBackend.Models; - -namespace AppBackend.Providers -{ - public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider - { - private readonly string _publicClientId; - - public ApplicationOAuthProvider(string publicClientId) - { - if (publicClientId == null) - { - throw new ArgumentNullException("publicClientId"); - } - - _publicClientId = publicClientId; - } - - public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) - { - var userManager = context.OwinContext.GetUserManager(); - - ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password); - - if (user == null) - { - context.SetError("invalid_grant", "The user name or password is incorrect."); - return; - } - - ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, - OAuthDefaults.AuthenticationType); - ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager, - CookieAuthenticationDefaults.AuthenticationType); - - AuthenticationProperties properties = CreateProperties(user.UserName); - AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties); - context.Validated(ticket); - context.Request.Context.Authentication.SignIn(cookiesIdentity); - } - - public override Task TokenEndpoint(OAuthTokenEndpointContext context) - { - foreach (KeyValuePair property in context.Properties.Dictionary) - { - context.AdditionalResponseParameters.Add(property.Key, property.Value); - } - - return Task.FromResult(null); - } - - public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) - { - // Resource owner password credentials does not provide a client ID. - if (context.ClientId == null) - { - context.Validated(); - } - - return Task.FromResult(null); - } - - public override Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context) - { - if (context.ClientId == _publicClientId) - { - Uri expectedRootUri = new Uri(context.Request.Uri, "/"); - - if (expectedRootUri.AbsoluteUri == context.RedirectUri) - { - context.Validated(); - } - } - - return Task.FromResult(null); - } - - public static AuthenticationProperties CreateProperties(string userName) - { - IDictionary data = new Dictionary - { - { "userName", userName } - }; - return new AuthenticationProperties(data); - } - } -} \ No newline at end of file diff --git a/dotnet/NotifyUsers/AppBackend/Results/ChallengeResult.cs b/dotnet/NotifyUsers/AppBackend/Results/ChallengeResult.cs deleted file mode 100644 index c705519..0000000 --- a/dotnet/NotifyUsers/AppBackend/Results/ChallengeResult.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; -using System.Web.Http; - -namespace AppBackend.Results -{ - public class ChallengeResult : IHttpActionResult - { - public ChallengeResult(string loginProvider, ApiController controller) - { - LoginProvider = loginProvider; - Request = controller.Request; - } - - public string LoginProvider { get; set; } - public HttpRequestMessage Request { get; set; } - - public Task ExecuteAsync(CancellationToken cancellationToken) - { - Request.GetOwinContext().Authentication.Challenge(LoginProvider); - - HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.Unauthorized); - response.RequestMessage = Request; - return Task.FromResult(response); - } - } -} diff --git a/dotnet/NotifyUsers/AppBackend/Scripts/_references.js b/dotnet/NotifyUsers/AppBackend/Scripts/_references.js deleted file mode 100644 index cbe7a47..0000000 Binary files a/dotnet/NotifyUsers/AppBackend/Scripts/_references.js and /dev/null differ diff --git a/dotnet/NotifyUsers/AppBackend/Scripts/bootstrap.js b/dotnet/NotifyUsers/AppBackend/Scripts/bootstrap.js deleted file mode 100644 index 5aa9982..0000000 --- a/dotnet/NotifyUsers/AppBackend/Scripts/bootstrap.js +++ /dev/null @@ -1,2014 +0,0 @@ -/* NUGET: BEGIN LICENSE TEXT - * - * Microsoft grants you the right to use these script files for the sole - * purpose of either: (i) interacting through your browser with the Microsoft - * website or online service, subject to the applicable licensing or use - * terms; or (ii) using the files as included with a Microsoft product subject - * to that product's license terms. Microsoft reserves all other rights to the - * files not expressly granted by Microsoft, whether by implication, estoppel - * or otherwise. Insofar as a script file is dual licensed under GPL, - * Microsoft neither took the code under GPL nor distributes it thereunder but - * under the terms set out in this paragraph. All notices and licenses - * below are for informational purposes only. - * - * NUGET: END LICENSE TEXT */ - -/** -* bootstrap.js v3.0.0 by @fat and @mdo -* Copyright 2013 Twitter Inc. -* http://www.apache.org/licenses/LICENSE-2.0 -*/ -if (!jQuery) { throw new Error("Bootstrap requires jQuery") } - -/* ======================================================================== - * Bootstrap: transition.js v3.0.0 - * http://twbs.github.com/bootstrap/javascript.html#transitions - * ======================================================================== - * Copyright 2013 Twitter, 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/licenses/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. - * ======================================================================== */ - - -+function ($) { "use strict"; - - // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) - // ============================================================ - - function transitionEnd() { - var el = document.createElement('bootstrap') - - var transEndEventNames = { - 'WebkitTransition' : 'webkitTransitionEnd' - , 'MozTransition' : 'transitionend' - , 'OTransition' : 'oTransitionEnd otransitionend' - , 'transition' : 'transitionend' - } - - for (var name in transEndEventNames) { - if (el.style[name] !== undefined) { - return { end: transEndEventNames[name] } - } - } - } - - // http://blog.alexmaccaw.com/css-transitions - $.fn.emulateTransitionEnd = function (duration) { - var called = false, $el = this - $(this).one($.support.transition.end, function () { called = true }) - var callback = function () { if (!called) $($el).trigger($.support.transition.end) } - setTimeout(callback, duration) - return this - } - - $(function () { - $.support.transition = transitionEnd() - }) - -}(window.jQuery); - -/* ======================================================================== - * Bootstrap: alert.js v3.0.0 - * http://twbs.github.com/bootstrap/javascript.html#alerts - * ======================================================================== - * Copyright 2013 Twitter, 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/licenses/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. - * ======================================================================== */ - - -+function ($) { "use strict"; - - // ALERT CLASS DEFINITION - // ====================== - - var dismiss = '[data-dismiss="alert"]' - var Alert = function (el) { - $(el).on('click', dismiss, this.close) - } - - Alert.prototype.close = function (e) { - var $this = $(this) - var selector = $this.attr('data-target') - - if (!selector) { - selector = $this.attr('href') - selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 - } - - var $parent = $(selector) - - if (e) e.preventDefault() - - if (!$parent.length) { - $parent = $this.hasClass('alert') ? $this : $this.parent() - } - - $parent.trigger(e = $.Event('close.bs.alert')) - - if (e.isDefaultPrevented()) return - - $parent.removeClass('in') - - function removeElement() { - $parent.trigger('closed.bs.alert').remove() - } - - $.support.transition && $parent.hasClass('fade') ? - $parent - .one($.support.transition.end, removeElement) - .emulateTransitionEnd(150) : - removeElement() - } - - - // ALERT PLUGIN DEFINITION - // ======================= - - var old = $.fn.alert - - $.fn.alert = function (option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.alert') - - if (!data) $this.data('bs.alert', (data = new Alert(this))) - if (typeof option == 'string') data[option].call($this) - }) - } - - $.fn.alert.Constructor = Alert - - - // ALERT NO CONFLICT - // ================= - - $.fn.alert.noConflict = function () { - $.fn.alert = old - return this - } - - - // ALERT DATA-API - // ============== - - $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) - -}(window.jQuery); - -/* ======================================================================== - * Bootstrap: button.js v3.0.0 - * http://twbs.github.com/bootstrap/javascript.html#buttons - * ======================================================================== - * Copyright 2013 Twitter, 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/licenses/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. - * ======================================================================== */ - - -+function ($) { "use strict"; - - // BUTTON PUBLIC CLASS DEFINITION - // ============================== - - var Button = function (element, options) { - this.$element = $(element) - this.options = $.extend({}, Button.DEFAULTS, options) - } - - Button.DEFAULTS = { - loadingText: 'loading...' - } - - Button.prototype.setState = function (state) { - var d = 'disabled' - var $el = this.$element - var val = $el.is('input') ? 'val' : 'html' - var data = $el.data() - - state = state + 'Text' - - if (!data.resetText) $el.data('resetText', $el[val]()) - - $el[val](data[state] || this.options[state]) - - // push to event loop to allow forms to submit - setTimeout(function () { - state == 'loadingText' ? - $el.addClass(d).attr(d, d) : - $el.removeClass(d).removeAttr(d); - }, 0) - } - - Button.prototype.toggle = function () { - var $parent = this.$element.closest('[data-toggle="buttons"]') - - if ($parent.length) { - var $input = this.$element.find('input') - .prop('checked', !this.$element.hasClass('active')) - .trigger('change') - if ($input.prop('type') === 'radio') $parent.find('.active').removeClass('active') - } - - this.$element.toggleClass('active') - } - - - // BUTTON PLUGIN DEFINITION - // ======================== - - var old = $.fn.button - - $.fn.button = function (option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.button') - var options = typeof option == 'object' && option - - if (!data) $this.data('bs.button', (data = new Button(this, options))) - - if (option == 'toggle') data.toggle() - else if (option) data.setState(option) - }) - } - - $.fn.button.Constructor = Button - - - // BUTTON NO CONFLICT - // ================== - - $.fn.button.noConflict = function () { - $.fn.button = old - return this - } - - - // BUTTON DATA-API - // =============== - - $(document).on('click.bs.button.data-api', '[data-toggle^=button]', function (e) { - var $btn = $(e.target) - if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') - $btn.button('toggle') - e.preventDefault() - }) - -}(window.jQuery); - -/* ======================================================================== - * Bootstrap: carousel.js v3.0.0 - * http://twbs.github.com/bootstrap/javascript.html#carousel - * ======================================================================== - * Copyright 2012 Twitter, 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/licenses/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. - * ======================================================================== */ - - -+function ($) { "use strict"; - - // CAROUSEL CLASS DEFINITION - // ========================= - - var Carousel = function (element, options) { - this.$element = $(element) - this.$indicators = this.$element.find('.carousel-indicators') - this.options = options - this.paused = - this.sliding = - this.interval = - this.$active = - this.$items = null - - this.options.pause == 'hover' && this.$element - .on('mouseenter', $.proxy(this.pause, this)) - .on('mouseleave', $.proxy(this.cycle, this)) - } - - Carousel.DEFAULTS = { - interval: 5000 - , pause: 'hover' - , wrap: true - } - - Carousel.prototype.cycle = function (e) { - e || (this.paused = false) - - this.interval && clearInterval(this.interval) - - this.options.interval - && !this.paused - && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) - - return this - } - - Carousel.prototype.getActiveIndex = function () { - this.$active = this.$element.find('.item.active') - this.$items = this.$active.parent().children() - - return this.$items.index(this.$active) - } - - Carousel.prototype.to = function (pos) { - var that = this - var activeIndex = this.getActiveIndex() - - if (pos > (this.$items.length - 1) || pos < 0) return - - if (this.sliding) return this.$element.one('slid', function () { that.to(pos) }) - if (activeIndex == pos) return this.pause().cycle() - - return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos])) - } - - Carousel.prototype.pause = function (e) { - e || (this.paused = true) - - if (this.$element.find('.next, .prev').length && $.support.transition.end) { - this.$element.trigger($.support.transition.end) - this.cycle(true) - } - - this.interval = clearInterval(this.interval) - - return this - } - - Carousel.prototype.next = function () { - if (this.sliding) return - return this.slide('next') - } - - Carousel.prototype.prev = function () { - if (this.sliding) return - return this.slide('prev') - } - - Carousel.prototype.slide = function (type, next) { - var $active = this.$element.find('.item.active') - var $next = next || $active[type]() - var isCycling = this.interval - var direction = type == 'next' ? 'left' : 'right' - var fallback = type == 'next' ? 'first' : 'last' - var that = this - - if (!$next.length) { - if (!this.options.wrap) return - $next = this.$element.find('.item')[fallback]() - } - - this.sliding = true - - isCycling && this.pause() - - var e = $.Event('slide.bs.carousel', { relatedTarget: $next[0], direction: direction }) - - if ($next.hasClass('active')) return - - if (this.$indicators.length) { - this.$indicators.find('.active').removeClass('active') - this.$element.one('slid', function () { - var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()]) - $nextIndicator && $nextIndicator.addClass('active') - }) - } - - if ($.support.transition && this.$element.hasClass('slide')) { - this.$element.trigger(e) - if (e.isDefaultPrevented()) return - $next.addClass(type) - $next[0].offsetWidth // force reflow - $active.addClass(direction) - $next.addClass(direction) - $active - .one($.support.transition.end, function () { - $next.removeClass([type, direction].join(' ')).addClass('active') - $active.removeClass(['active', direction].join(' ')) - that.sliding = false - setTimeout(function () { that.$element.trigger('slid') }, 0) - }) - .emulateTransitionEnd(600) - } else { - this.$element.trigger(e) - if (e.isDefaultPrevented()) return - $active.removeClass('active') - $next.addClass('active') - this.sliding = false - this.$element.trigger('slid') - } - - isCycling && this.cycle() - - return this - } - - - // CAROUSEL PLUGIN DEFINITION - // ========================== - - var old = $.fn.carousel - - $.fn.carousel = function (option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.carousel') - var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) - var action = typeof option == 'string' ? option : options.slide - - if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) - if (typeof option == 'number') data.to(option) - else if (action) data[action]() - else if (options.interval) data.pause().cycle() - }) - } - - $.fn.carousel.Constructor = Carousel - - - // CAROUSEL NO CONFLICT - // ==================== - - $.fn.carousel.noConflict = function () { - $.fn.carousel = old - return this - } - - - // CAROUSEL DATA-API - // ================= - - $(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) { - var $this = $(this), href - var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 - var options = $.extend({}, $target.data(), $this.data()) - var slideIndex = $this.attr('data-slide-to') - if (slideIndex) options.interval = false - - $target.carousel(options) - - if (slideIndex = $this.attr('data-slide-to')) { - $target.data('bs.carousel').to(slideIndex) - } - - e.preventDefault() - }) - - $(window).on('load', function () { - $('[data-ride="carousel"]').each(function () { - var $carousel = $(this) - $carousel.carousel($carousel.data()) - }) - }) - -}(window.jQuery); - -/* ======================================================================== - * Bootstrap: collapse.js v3.0.0 - * http://twbs.github.com/bootstrap/javascript.html#collapse - * ======================================================================== - * Copyright 2012 Twitter, 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/licenses/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. - * ======================================================================== */ - - -+function ($) { "use strict"; - - // COLLAPSE PUBLIC CLASS DEFINITION - // ================================ - - var Collapse = function (element, options) { - this.$element = $(element) - this.options = $.extend({}, Collapse.DEFAULTS, options) - this.transitioning = null - - if (this.options.parent) this.$parent = $(this.options.parent) - if (this.options.toggle) this.toggle() - } - - Collapse.DEFAULTS = { - toggle: true - } - - Collapse.prototype.dimension = function () { - var hasWidth = this.$element.hasClass('width') - return hasWidth ? 'width' : 'height' - } - - Collapse.prototype.show = function () { - if (this.transitioning || this.$element.hasClass('in')) return - - var startEvent = $.Event('show.bs.collapse') - this.$element.trigger(startEvent) - if (startEvent.isDefaultPrevented()) return - - var actives = this.$parent && this.$parent.find('> .panel > .in') - - if (actives && actives.length) { - var hasData = actives.data('bs.collapse') - if (hasData && hasData.transitioning) return - actives.collapse('hide') - hasData || actives.data('bs.collapse', null) - } - - var dimension = this.dimension() - - this.$element - .removeClass('collapse') - .addClass('collapsing') - [dimension](0) - - this.transitioning = 1 - - var complete = function () { - this.$element - .removeClass('collapsing') - .addClass('in') - [dimension]('auto') - this.transitioning = 0 - this.$element.trigger('shown.bs.collapse') - } - - if (!$.support.transition) return complete.call(this) - - var scrollSize = $.camelCase(['scroll', dimension].join('-')) - - this.$element - .one($.support.transition.end, $.proxy(complete, this)) - .emulateTransitionEnd(350) - [dimension](this.$element[0][scrollSize]) - } - - Collapse.prototype.hide = function () { - if (this.transitioning || !this.$element.hasClass('in')) return - - var startEvent = $.Event('hide.bs.collapse') - this.$element.trigger(startEvent) - if (startEvent.isDefaultPrevented()) return - - var dimension = this.dimension() - - this.$element - [dimension](this.$element[dimension]()) - [0].offsetHeight - - this.$element - .addClass('collapsing') - .removeClass('collapse') - .removeClass('in') - - this.transitioning = 1 - - var complete = function () { - this.transitioning = 0 - this.$element - .trigger('hidden.bs.collapse') - .removeClass('collapsing') - .addClass('collapse') - } - - if (!$.support.transition) return complete.call(this) - - this.$element - [dimension](0) - .one($.support.transition.end, $.proxy(complete, this)) - .emulateTransitionEnd(350) - } - - Collapse.prototype.toggle = function () { - this[this.$element.hasClass('in') ? 'hide' : 'show']() - } - - - // COLLAPSE PLUGIN DEFINITION - // ========================== - - var old = $.fn.collapse - - $.fn.collapse = function (option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.collapse') - var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) - - if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - $.fn.collapse.Constructor = Collapse - - - // COLLAPSE NO CONFLICT - // ==================== - - $.fn.collapse.noConflict = function () { - $.fn.collapse = old - return this - } - - - // COLLAPSE DATA-API - // ================= - - $(document).on('click.bs.collapse.data-api', '[data-toggle=collapse]', function (e) { - var $this = $(this), href - var target = $this.attr('data-target') - || e.preventDefault() - || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 - var $target = $(target) - var data = $target.data('bs.collapse') - var option = data ? 'toggle' : $this.data() - var parent = $this.attr('data-parent') - var $parent = parent && $(parent) - - if (!data || !data.transitioning) { - if ($parent) $parent.find('[data-toggle=collapse][data-parent="' + parent + '"]').not($this).addClass('collapsed') - $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed') - } - - $target.collapse(option) - }) - -}(window.jQuery); - -/* ======================================================================== - * Bootstrap: dropdown.js v3.0.0 - * http://twbs.github.com/bootstrap/javascript.html#dropdowns - * ======================================================================== - * Copyright 2012 Twitter, 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/licenses/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. - * ======================================================================== */ - - -+function ($) { "use strict"; - - // DROPDOWN CLASS DEFINITION - // ========================= - - var backdrop = '.dropdown-backdrop' - var toggle = '[data-toggle=dropdown]' - var Dropdown = function (element) { - var $el = $(element).on('click.bs.dropdown', this.toggle) - } - - Dropdown.prototype.toggle = function (e) { - var $this = $(this) - - if ($this.is('.disabled, :disabled')) return - - var $parent = getParent($this) - var isActive = $parent.hasClass('open') - - clearMenus() - - if (!isActive) { - if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { - // if mobile we we use a backdrop because click events don't delegate - $('