text:
//
// KISSmetricsSDK
//
// Copyright 2014 KISSmetrics
//
// 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.

package com.kissmetrics.sdk;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.kissmetrics.sdk.KISSmetricsAPI.RecordCondition;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

/**
 * Handles read/write of settings, identity, recorded events and properties.
 * Recorded events and properties are URL encoded before being saved to a send queue.
 */
public class ArchiverImpl implements Archiver {
  private static final String CLIENT_TYPE = "mobile_app";
  private static final String IDENTITY_PREF = "KISSmetricsIdentity";
  private static final String SETTINGS_FILE = "KISSmetricsSettings";
  private static final String INSTALL_UUID_KEY = "installUuid";
  private static final String HAS_GENERIC_IDENTITY_KEY = "hasGenericIdentity";
  private static final String VERIFICATION_EXP_DATE_KEY = "verification_exp_date";
  private static final String DO_TRACK_KEY = "doTrack";
  private static final String DO_SEND_KEY = "doSend";
  private static final String BASE_URL_KEY = "baseUrl";
  private static final String APP_VERSION_KEY = "appVersionKey";
  private static final String ACTIONS_FILE = "KISSmetricsActions";
  private static final String SAVED_ID_EVENTS_FILE = "KISSmetricsSavedEvents";
  private static final String SAVED_INSTALL_EVENTS_FILE = "KISSmetricsSavedInstallEvents";
  private static final String SAVED_PROPERTIES_FILE = "KISSmetricsSavedProperties";
  private static final long VERIFICATION_EXP_DATE_DEFAULT = 0L;
  private static final boolean HAS_GENERIC_IDENTITY_DEFAULT = false;
  private static final boolean DO_TRACK_DEFAULT = true;
  private static final boolean DO_SEND_DEFAULT = false;
  private static final String BASE_URL_DEFAULT = "https://trc.kissmetrics.io";

  private static ArchiverImpl sharedArchiver = null;

  private String key;
  private Context context;
  private QueryEncoder queryEncoder;
  private HashMap<String, Object> settings;
  private String lastIdentity;
  private List<String> sendQueue;
  private List<String> savedIdEvents;
  private List<String> savedInstallEvents;
  private HashMap<String, String> savedProperties;

  /**
   * Initializes the private singleton.
   *
   * @param key                KISSmetrics product key
   * @param applicationContext Android application context
   */
  private ArchiverImpl(String key, Context applicationContext) {
    this.key = key;
    this.context = applicationContext;
    this.queryEncoder = new QueryEncoder(this.key, CLIENT_TYPE, Connection.USER_AGENT);

    synchronized (this) {
      unarchiveSettings();
      unarchiveIdentity();
      unarchiveSendQueue();
      unarchiveSavedInstallEvents();
      unarchiveSavedIdEvents();
      unarchiveSavedProperties();
    }
  }

  /**
   * Initializes and/or returns the ArchiverImpl singleton instance. This method must be called
   * before making any other calls.
   *
   * @param productKey         KISSmetrics product key
   * @param applicationContext Android application context
   * @return Archiver singleton instance
   */
  public static synchronized ArchiverImpl sharedArchiver(String productKey,
                                                         Context applicationContext)
  {
    if (sharedArchiver == null) {
      sharedArchiver = new ArchiverImpl(productKey, applicationContext);
    }
    return sharedArchiver;
  }

  /**
   * @return ArchiverImpl singleton instance
   */
  public static synchronized ArchiverImpl sharedArchiver()
  {
    if (sharedArchiver == null) {
      Log.w(KISSmetricsAPI.TAG,
              "KISSMetricsAPI: WARNING - Returning null object in sharedAPI as " +
                      "sharedArchiver(<API_KEY>, <Context>): has not been called.");
    }
    return sharedArchiver;
  }

  /************************************************
   * Private methods
   ************************************************/

  /**
   * Unarchives settings from Internal Storage or establishes defaults.
   * Sets value of mSettings with unarchived settings.
   *

   * Suppresses warnings for ObjectInputStream readObject cast to HashMap<String, Object>.
   */
  @SuppressWarnings("unchecked")
  private void unarchiveSettings() {
    // Not synch'd as should always be called inside of a sync block !!
    try {
      FileInputStream fis = this.context.openFileInput(SETTINGS_FILE);
      ObjectInputStream ois = new ObjectInputStream(fis);
      this.settings = (HashMap<String, Object>) ois.readObject();
      ois.close();
    } catch (Exception e) {
      // The KISSmetrics SDK should not cause a customer's app to crash.
      // If a FileNotFoundException or IOException arises we define default settings
      // and carry on.
      Log.w(KISSmetricsAPI.TAG, "Unable to unarchive saved settings", e);
    }

    // The file doesn't exist yet or there was an error in reading the file.
    // Create the settings file with default values.
    if (this.settings == null) {
      archiveDefaultSettings();
    }
  }

  /**
   * Defines mSettings with default values and archives to Internal Storage.
   */
  private void archiveDefaultSettings() {
    this.settings = new HashMap<String, Object>();

    // Apply default settings
    this.settings.put(DO_TRACK_KEY, DO_TRACK_DEFAULT);
    this.settings.put(DO_SEND_KEY, DO_SEND_DEFAULT);
    this.settings.put(BASE_URL_KEY, BASE_URL_DEFAULT);
    this.settings.put(VERIFICATION_EXP_DATE_KEY, VERIFICATION_EXP_DATE_DEFAULT);
    this.settings.put(HAS_GENERIC_IDENTITY_KEY, HAS_GENERIC_IDENTITY_DEFAULT);

    this.archiveSettings();
  }

  /**
   * Archives mSettings to Internal Storage
   */
  private void archiveSettings() {
    try {
      FileOutputStream fos = this.context.openFileOutput(SETTINGS_FILE,
              Context.MODE_PRIVATE);
      ObjectOutputStream oos = new ObjectOutputStream(fos);
      oos.writeObject(this.settings);
      oos.flush();
      oos.close();
    } catch (Exception e) {
      // The KISSmetrics SDK should not cause a customer's app to crash.
      // If a FileNotFoundException or IOException arises we ignore it.
      Log.w(KISSmetricsAPI.TAG, "Unable to archive settings", e);
    }
  }

  /**
   * Unarchive's identity from Shared Preferences.
   * Sets value of mLastIdentity with unarchived identity.
   */
  private void unarchiveIdentity() {
    // Not synch'd as should always be called inside of a sync block !!
    SharedPreferences pref = this.context.getSharedPreferences(IDENTITY_PREF,
            Context.MODE_PRIVATE);

    // We should not have to protect against a null identity here.
    // If preferences are cleared by the user while an application is running we will continue
    // to use mLastIdentity.
    // Upon the next true launch of an application a null unarchived identity will trigger the
    // creation of a new anon identity.
    this.lastIdentity = pref.getString("identity", "");
  }

  /**
   * Unarchives saved install events from Internal Storage or establishes a new List object.
   * Sets value of mSavedInstallEvents with unarchived saved events.
   *

   * Suppresses warnings for ObjectInputStream readObject cast to List<String>.
   */
  @SuppressWarnings("unchecked")
  private void unarchiveSavedInstallEvents() {
    // Not synch'd as should always be called inside of a sync block !!
    try {
      FileInputStream fis = this.context.openFileInput(SAVED_INSTALL_EVENTS_FILE);
      ObjectInputStream ois = new ObjectInputStream(fis);
      this.savedInstallEvents = (List<String>) ois.readObject();
      ois.close();
    } catch (Exception e) {
      // The KISSmetrics SDK should not cause a customer's app to crash.
      // If a FileNotFoundException or IOException arises we define mSavedInstallEvents
      // as a new ArrayList and carry on.
      Log.w(KISSmetricsAPI.TAG, "Unable to unarchive saved install events", e);
    }

    if (this.savedInstallEvents == null) {
      // The file doesn't exist yet or there was an error in reading the file.
      // Create the savedInstallEvents file with a new Array List.
      this.savedInstallEvents = new ArrayList<String>();
      this.archiveSavedInstallEvents();
    }
  }

  /**
   * Archives mSavedInstallEvents from Internal Storage.
   */
  private void archiveSavedInstallEvents() {
    // Not synch'd as should always be called inside of a sync block !!
    try {
      FileOutputStream fos = this.context.openFileOutput(SAVED_INSTALL_EVENTS_FILE,
              Context.MODE_PRIVATE);
      ObjectOutputStream oos = new ObjectOutputStream(fos);
      oos.writeObject(this.savedInstallEvents);
      oos.flush();
      oos.close();
    } catch (Exception e) {
      // The KISSmetrics SDK should not cause a customer's app to crash.
      // If a FileNotFoundException or IOException arises we ignore it.
      Log.w(KISSmetricsAPI.TAG, "Unable to archive saved install events", e);
    }
  }

  /**
   * Unarchives saved events from Internal Storage or establishes a new List object.
   * Sets value of mSavedIdEvents with unarchived saved events.
   *

   * Suppresses warnings for ObjectInputStream readObject cast to List<String>.
   */
  @SuppressWarnings("unchecked")
  private void unarchiveSavedIdEvents() {
    // Not synch'd as should always be called inside of a sync block !!
    try {
      FileInputStream fis = this.context.openFileInput(SAVED_ID_EVENTS_FILE);
      ObjectInputStream ois = new ObjectInputStream(fis);
      this.savedIdEvents = (List<String>) ois.readObject();
      ois.close();
    } catch (Exception e) {
      // The KISSmetrics SDK should not cause a customer's app to crash.
      // If a FileNotFoundException or IOException arises we define mSavedIdEvents as a new
      // ArrayList and carry on.
      Log.w(KISSmetricsAPI.TAG, "Unable to unarchive saved identity events", e);
    }

    if (this.savedIdEvents == null) {
      // The file doesn't exist yet or there was an error in reading the file.
      // Create the savedIdEvents file with a new Array List.
      this.savedIdEvents = new ArrayList<String>();
      this.archiveSavedIdEvents();
    }
  }

  /**
   * Archives mSavedIdEvents from Internal Storage.
   */
  private void archiveSavedIdEvents() {
    // Not synch'd as should always be called inside of a sync block !!
    try {
      FileOutputStream fos = this.context.openFileOutput(SAVED_ID_EVENTS_FILE,
              Context.MODE_PRIVATE);
      ObjectOutputStream oos = new ObjectOutputStream(fos);
      oos.writeObject(this.savedIdEvents);
      oos.flush();
      oos.close();
    } catch (Exception e) {
      // The KISSmetrics SDK should not cause a customer's app to crash.
      // If a FileNotFoundException or IOException arises we ignore it.
      Log.w(KISSmetricsAPI.TAG, "Unable to archive saved identity events", e);
    }
  }

  /**
   * Unarchives saved properties from Internal Storage or establishes new a HashMap object.
   * Sets value of mSavedProperties with unarchived saved properties.
   *

   * Suppresses warnings for ObjectInputStream readObject cast to HashMap<String, String>.
   */
  @SuppressWarnings("unchecked")
  private void unarchiveSavedProperties() {
    // Not synch'd as should always be called inside of a sync block !!
    try {
      FileInputStream fis = this.context.openFileInput(SAVED_PROPERTIES_FILE);
      ObjectInputStream ois = new ObjectInputStream(fis);
      this.savedProperties = (HashMap<String, String>) ois.readObject();
      ois.close();
    } catch (Exception e) {
      // The KISSmetrics SDK should not cause a customer's app to crash.
      // If a FileNotFoundException or IOException arises we define mSavedProperites as a new
      // HashMap and carry on.
      Log.w(KISSmetricsAPI.TAG, "Unable to unarchive saved properties", e);
    }

    if (this.savedProperties == null) {
      // The file doesn't exist yet or there was an error in reading the file.
      // Create the savedProperties file with a new HashMap.
      this.savedProperties = new HashMap<String, String>();
      this.archiveSavedProperties();
    }
  }

  /**
   * Archives mSavedProperties to Internal Storage.
   */
  private void archiveSavedProperties() {
    // Not synch'd as should always be called inside of a sync block !!
    try {
      FileOutputStream fos = this.context.openFileOutput(SAVED_PROPERTIES_FILE,
              Context.MODE_PRIVATE);
      ObjectOutputStream oos = new ObjectOutputStream(fos);
      oos.writeObject(this.savedProperties);
      oos.flush();
      oos.close();
    } catch (Exception e) {
      // The KISSmetrics SDK should not cause a customer's app to crash.
      // If a FileNotFoundException or IOException arises we ignore it.
      Log.w(KISSmetricsAPI.TAG, "Unable to archive saved properties", e);
    }
  }

  /**
   * Unarchives sendQueue from Internal Storage or establishes a new List<String, String> object.
   * Sets value of mSendQueue with unarchived sendQueue.
   *

   * Suppresses warnings for ObjectInputStream readObject cast to List<String, String>.
   */
  @SuppressWarnings("unchecked")
  private void unarchiveSendQueue() {
    // Not synch'd as should always be called inside of a synch block !!
    try {
      FileInputStream fis = this.context.openFileInput(ACTIONS_FILE);
      ObjectInputStream ois = new ObjectInputStream(fis);
      this.sendQueue = (List<String>) ois.readObject();
      ois.close();
    } catch (Exception e) {
      // The KISSmetrics SDK should not cause a customer's app to crash.
      // If a FileNotFoundException or IOException arises we define mSavedProperites as a new
      // List<String> and carry on.
      Log.w(KISSmetricsAPI.TAG, "Unable to unarchive data", e);
    }

    if (this.sendQueue == null) {
      this.sendQueue = new ArrayList<String>();
      this.archiveSendQueue();
    }
  }

  /**
   * Archives mSendQueue to Internal Storage.
   */
  private void archiveSendQueue() {
    // Not synch'd as should always be called inside of a sync block !!
    try {
      FileOutputStream fos = this.context.openFileOutput(ACTIONS_FILE, Context.MODE_PRIVATE);
      ObjectOutputStream oos = new ObjectOutputStream(fos);
      oos.writeObject(this.sendQueue);
      oos.flush();
      oos.close();
    } catch (Exception e) {
      // The KISSmetrics SDK should not cause a customer's app to crash.
      // If a FileNotFoundException or IOException arises we ignore it.
      Log.w(KISSmetricsAPI.TAG, "Unable to archive data", e);
    }
  }

  /**
   * Helper method to get seconds from the system clock.
   *
   * @return Current time in seconds
   */
  private long currentTimeSeconds() {
    return System.currentTimeMillis() / 1000L;
  }

  /************************************************
   * Public methods
   ************************************************/

  /**
   * Archives install UUID to Settings < Internal Storage.
   *
   * @param installUuid Unique identifier of the application install which may only be
   *                    archived once.
   */
  public void archiveInstallUuid(final String installUuid) {
    // Protect from null or empty string, or overriding install UUID value
    if (installUuid == null ||
            installUuid.length() == 0 ||
            this.settings.get(INSTALL_UUID_KEY) != null) {

      Log.w(KISSmetricsAPI.TAG, "installUuid not valid to save");
      return;
    }

    synchronized (this) {
      this.settings.put(INSTALL_UUID_KEY, installUuid);
      this.archiveSettings();
    }
  }

  /**
   * Archives doTrack boolean to Settings < Internal Storage.
   *
   * @param doTrack Setting to control recording of aliases, events and properties.
   */
  public void archiveDoTrack(boolean doTrack) {
    synchronized (this) {
      this.settings.put(DO_TRACK_KEY, doTrack);
      this.archiveSettings();
    }
  }

  /**
   * Archives doSend boolean to Settings < Internal Storage.
   *
   * @param doSend Setting to control the uploading of aliases, events and properties.
   */
  public void archiveDoSend(boolean doSend) {
    synchronized (this) {
      this.settings.put(DO_SEND_KEY, doSend);
      this.archiveSettings();
    }
  }

  /**
   * Archives baseUrl String to Settings < Internal Storage.
   *
   * @param baseUrl Setting for API base URL path
   */
  public void archiveBaseUrl(String baseUrl) {
    // Protect from null or empty string
    if (baseUrl == null || baseUrl.length() == 0) {
      Log.w(KISSmetricsAPI.TAG, "baseUrl not valid to save");
      return;
    }

    synchronized (this) {
      this.settings.put(BASE_URL_KEY, baseUrl);
      this.archiveSettings();
    }
  }

  /**
   * Archives doTrack verification expiration date to Settings < Internal Storage.
   *
   * @param expDate Milliseconds from unix epoch when verification expires.
   */
  public void archiveVerificationExpDate(long expDate) {
    synchronized (this) {
      this.settings.put(VERIFICATION_EXP_DATE_KEY, expDate);
      this.archiveSettings();
    }
  }

  /**
   * Archives hasGenericIdentity boolean to Settings < Internal Storage.
   *
   * @param hasGenericIdentity setting to indicate that a proper identity has been given.
   */
  public void archiveHasGenericIdentity(final boolean hasGenericIdentity) {
    synchronized (this) {
      this.settings.put(HAS_GENERIC_IDENTITY_KEY, hasGenericIdentity);
    }
  }

  /**
   * Archives appVersion to Settings < Internal Storage.
   *
   * @param appVersion String app version name.
   */
  public void archiveAppVersion(String appVersion) {
    synchronized (this) {
      this.settings.put(APP_VERSION_KEY, appVersion);
      this.archiveSettings();
    }
  }

  /**
   * Archives first identity to Shared Preferences.
   * Used when establishing a new identity that is not aliased to any other identity.
   * Nothing is passed to KISSmetrics as a result of archiving a first identity.
   *
   * @param identity A new, anonymous identity
   */
  public void archiveFirstIdentity(String identity) {
    if (identity == null || identity.length() == 0) {
      return;
    }

    synchronized (this) {
      this.lastIdentity = identity;
      this.archiveHasGenericIdentity(true);
      SharedPreferences pref = this.context.getSharedPreferences(IDENTITY_PREF,
              Context.MODE_PRIVATE);
      SharedPreferences.Editor prefEditor = pref.edit();
      prefEditor.putString("identity", this.lastIdentity);
      prefEditor.commit();
    }
  }

  public void archiveEvent(String name, Map<String, String> properties, RecordCondition condition) {
    if (name == null || name.length() == 0) {
      Log.w(KISSmetricsAPI.TAG,
              "Attempted to record an event with null or empty event name. Ignoring");
      return;
    }

    switch (condition) {
      case RECORD_ALWAYS:
        // Nothing else to check, continue with archiving.
        break;

      case RECORD_ONCE_PER_IDENTITY:
        synchronized (this) {
          if (this.savedIdEvents != null && this.savedIdEvents.contains(name)) {
            // Recorded event already exists
            return;
          } else {
            this.savedIdEvents.add(name);
            archiveSavedIdEvents();
          }
        }
        break;

      case RECORD_ONCE_PER_INSTALL:
        synchronized (this) {
          if (this.savedInstallEvents != null && this.savedInstallEvents.contains(name)) {
            // Recorded event already exists
            return;
          } else {
            this.savedInstallEvents.add(name);
            archiveSavedInstallEvents();
          }
        }
        break;

      default:
        // Continue with archiving the event.
        break;
    }

    // Intentionally called outside of synchronized, method is already synchronized.
    archiveEvent(name, properties);
  }

  /**
   * Adds an event (with or without properties) to the sendQueue.
   * Archives the updated sendQueue to Internal Storage.
   *
   * @param name       Name of the event to record
   * @param properties A HashMap of 1 or more properties, or null
   */
  private void archiveEvent(String name, Map<String, String> properties) {
    synchronized (this) {
      String theUrl = this.queryEncoder.createEventQuery(name, properties,
              this.lastIdentity,
              currentTimeSeconds());
      this.sendQueue.add(theUrl);
      archiveSendQueue();
    }
  }

  /**
   * Adds 1 or more properties to the sendQueue.
   * Archives the updated sendQueue to Internal Storage.
   *
   * @param properties HashMap of 1 or more properties.
   */
  public void archiveProperties(Map<String, String> properties) {
    if (properties == null || properties.isEmpty()) {
      Log.w(KISSmetricsAPI.TAG,
              "Attempted to set properties with no properties in it. Ignoring");
      return;
    }

    synchronized (this) {
      String theUrl = this.queryEncoder.createPropertiesQuery(properties, this.lastIdentity,
              currentTimeSeconds());
      this.sendQueue.add(theUrl);
      archiveSendQueue();
    }
  }

  /**
   * Adds 1 property to the sendQueue if the value is different than
   * the current value for the provided name(key).
   * Archives the updated sendQueue to Internal Storage.
   * Adds this property to mSavedProperties and archives to savedProperties.
   *
   * @param name  Property name(key)
   * @param value Property value for name(key)
   */
  public void archiveDistinctProperty(String name, String value) {
    synchronized (this) {
      String propertyValue = this.savedProperties.get(name);
      if (propertyValue != null && propertyValue.equals(value)) {
        //Log.w(KISSmetricsAPI.TAG, "Distinct property already set with same value");
        return;
      } else {
        this.savedProperties.put(name, value);
        archiveSavedProperties();
      }
    }

    // Pass it to the archive method
    // Intentionally called outside of synchronized block!
    HashMap<String, String> propertyHashMap = new HashMap<String, String>();
    propertyHashMap.put(name, value);
    archiveProperties(propertyHashMap);
  }

  /**
   * Sets value of mLastIdentity.
   * Archives mLastIdentity to Shared Preferences.
   * Adds an alias query to the sendQueue.
   * Archives the updated sendQueue to Internal Storage.
   *
   * @param identity A new user identity
   */
  public void archiveIdentity(String identity) {
    if (identity == null || identity.length() == 0 || identity.equals(this.lastIdentity)) {
      Log.w(KISSmetricsAPI.TAG, "Attempted to use null, empty or existing identity. Ignoring");
      return;
    }

    String theUrl = this.queryEncoder.createAliasQuery(identity, this.lastIdentity);

    synchronized (this) {
      // Now we must update the identity on disk. No need to wait until the alias has been
      // accepted on the server, as calls are FIFO and encoded with current identity.
      this.lastIdentity = identity;

      SharedPreferences pref = this.context.getSharedPreferences(IDENTITY_PREF,
              Context.MODE_PRIVATE);
      SharedPreferences.Editor prefEditor = pref.edit();
      prefEditor.putString("identity", this.lastIdentity);
      prefEditor.commit();

      // Only add the alias query if the current identity is a generic identity
      if (this.hasGenericIdentity()) {
        this.archiveHasGenericIdentity(false);
        this.sendQueue.add(theUrl);
        archiveSendQueue();
      } else {
        // This is expected to be an entirely different user.
        // Clear saved Events and Properties just as we would when clearing an Identity
        this.clearSavedIdEvents();
        this.clearSavedProperties();
      }
    }
  }

  /**
   * Adds an alias query to the sendQueue.
   * Archives the updated sendQueue to Internal Storage.
   *
   * @param alias    An alias to an identity
   * @param identity A known user identity
   */
  public void archiveAlias(String alias, String identity) {
    if (alias == null || alias.length() == 0 || identity == null || identity.length() == 0) {
      Log.w(KISSmetricsAPI.TAG,
              "Attempted to use null or empty identities in " +
                      "alias (" + alias + " and " + identity + "). Ignoring.");
      return;
    }

    String theUrl = this.queryEncoder.createAliasQuery(alias, identity);

    synchronized (this) {
      this.sendQueue.add(theUrl);
      archiveSendQueue();
    }
  }

  /**
   * Replaces mSendQueue with a new(empty) List.
   * Archives the updated sendQueue to Internal Storage.
   */
  public void clearSendQueue() {
    synchronized (this) {
      this.sendQueue = new ArrayList<String>();
      archiveSendQueue();
    }
  }

  /**
   * Replaces mSavedIdEvents with a new(empty) List.
   * Archives the updated savedIdEvents to Internal Storage.
   */
  public void clearSavedIdEvents() {
    synchronized (this) {
      this.savedIdEvents = new ArrayList<String>();
      archiveSavedProperties();
    }
  }

  /**
   * Replaces mSavedProperties with a new(empty) HashMap.
   * Archives the updated savedProperties to Internal Storage.
   */
  public void clearSavedProperties() {
    synchronized (this) {
      this.savedProperties = new HashMap<String, String>();
      archiveSavedProperties();
    }
  }

  /**
   * Returns the query string from the sendQueue at the specified index.
   *
   * @param index Query string index in the sendQueue.
   * @return Query string of the requested index.
   */
  public String getQueryString(int index) {
    synchronized (this) {
      if (sendQueue.isEmpty()) {
        return null;
      }
      return sendQueue.get(index);
    }
  }

  /**
   * Removes a query string from the sendQueue at the specified index.
   * Intended to be used to remove successful API queries or malformed queries to prevent
   * repeated attempts to query the KISSmetrics API with URL strings that will never succeed.
   *
   * @param index Query string index in the sendQueue
   */
  public void removeQueryString(int index) {
    synchronized (this) {
      // As an added precaution we check the length of the sendQueue before removing.
      if (sendQueue.size() > 0) {
        sendQueue.remove(index);
        // Persist the shorter queue
        archiveSendQueue();
      }
    }
  }

  /**
   * @return The number of query strings in the sendQueue.
   */
  public int getQueueCount() {
    synchronized (this) {
      if (sendQueue == null) {
        return 0;
      }
      return sendQueue.size();
    }
  }

  public String getInstallUuid() {
    return (String) settings.get(INSTALL_UUID_KEY);
  }

  public long getVerificationExpDate() {
    if (settings.containsKey(VERIFICATION_EXP_DATE_KEY)) {
      return (Long) settings.get(VERIFICATION_EXP_DATE_KEY);
    }

    return VERIFICATION_EXP_DATE_DEFAULT;
  }

  public boolean hasGenericIdentity() {
    if (this.settings.containsKey(HAS_GENERIC_IDENTITY_KEY)) {
      return (Boolean) this.settings.get(HAS_GENERIC_IDENTITY_KEY);
    }

    return HAS_GENERIC_IDENTITY_DEFAULT;
  }

  /**
   * @return The last archived appVersion setting.
   */
  public String getAppVersion() {
    if (this.settings.containsKey(APP_VERSION_KEY)) {
      return (String) this.settings.get(APP_VERSION_KEY);
    }

    return null;
  }

  public boolean getDoSend() {
    if (this.settings.containsKey(DO_SEND_KEY)) {
      return (Boolean) this.settings.get(DO_SEND_KEY);
    }

    return DO_SEND_DEFAULT;
  }

  public boolean getDoTrack() {
    if (this.settings.containsKey(DO_TRACK_KEY)) {
      return (Boolean) this.settings.get(DO_TRACK_KEY);
    }

    return DO_TRACK_DEFAULT;
  }

  public String getBaseUrl() {
    if (this.settings.containsKey(BASE_URL_KEY)) {
      return (String) this.settings.get(BASE_URL_KEY);
    }

    return BASE_URL_DEFAULT;
  }

  public String getIdentity() {
    return lastIdentity;
  }
}


text:
<?xml version="1.0" encoding="ISO-8859-1"?>
<recette>
<nom>Oeufs à la coque</nom>
<portion>4</portion>
<preparation value="1" unit="min"/>
<cuisson value="3" unit="min"/>
<ingredients>
<i><nom id="ing1">oeufs</nom><nbre>4</nbre></i>
</ingredients>
<guide>
Plongez délicatement les <renvoi ref="ing1">oeufs</renvoi> dans de l_eau portée à "bullition. Faîtes reprendre l_ébullition, puis baissez le feu et laissez cuire à petits bouillons pendant <cuisson value="3"unit="min"/> minutes. Egouttez les <renvoi ref="ing1">oeufs</renvoi>, posez-les dans des coquetiers et coupez hortizontalement la partie supérieure pour les déguster.
2</guide>
</recette>

redpajama_set_name: RedPajamaGithub


text:
published: true
title: Мысли по поводу JavaScript
layout: post
tags: [Programming, JavaScript, JS]
permalink: mysli-po-povodu-js
---
# Итак, я закончил курс по JS на [Codecademy](http://codecademy.com)

Что я могу сказать? После довольно продолжительного общения с C# JS выглядит как нечто несуразное. Строгой типизации нет, функции объявляются почти как переменные - через `var`, объявление классов - вообще отдельная песня. Визуально дифференцировать публичное свойство от приватного несколько затруднительно.

Однако, TBH, язык довольно простой и код читать несложно. Да, я понимаю, что не видел сколько-нибудь крупный проект написанный на чем-либо кроме джавы (_на досуге ковырял исходники одной игрушки_), но соу фар код на JS мне читать было легче всего.

## Что мне в JS понравилось

Во-первых - наличие встроенных методов, таких как `hasOwnProperty` и `typeof`. Их применимость (особенно второго) для меня очевидна, и приятно, что таковые есть. Во-вторых - язык все еще си-подобный, имеется множество сходств в плане синтаксиса и работы различных стандартных конструкций.

## Кроме того

За время прохождения этого курса мне actually стала нравится расстановка скобок по Кернигану и Ричи. Раньше такая расстановка скобок мне была просто противна, а сейчас я вижу, что такой код все еще вполне неплохо читается, занимая при этом меньше строк, чем в варианте написания по Оллмэну.

Следующий на очереди - JQuery.

А пока вот вам картинка с котенком, которого мы обнаружили однажды в подъезде.
![Это котенок](http://s10.postimg.org/tbql6xnyh/IMG_9271.jpg)


text:
class EventNavigator : public Event
{
public:
    EventNavigator(Card *_source)
    {
        source = _source;
        done = false;
    }
    bool Advance(State &s)
    {
        if(done) return true;

        PlayerState &p = s.players[s.player];

        if(p.deck.Length() < 5) s.Shuffle(s.player);
        int cardsToReveal = Math::Min((int)p.deck.Length(), 5);
        if(cardsToReveal == 0)
        {
            if(logging) s.LogIndent(1, "has no cards to reveal");
            return true;
        }

        for(int cardIndex = 0; cardIndex < cardsToReveal; cardIndex++)
        {
            Card *c = p.deck[p.deck.Length() - 1 - cardIndex];
            if(logging) s.LogIndent(1, "reveals " + c->PrettyName());
        }

        s.decision.MakeDiscreteChoice(source, 2);
        if(decisionText) s.decision.text = "Discard revealed cards?|Yes|No";

        return false;
    }
    bool CanProcessDecisions() const
    {
        return true;
    }
    void ProcessDecision(State &s, const DecisionResponse &response)
    {
        PlayerState &p = s.players[s.player];
        int cardsToReveal = Math::Min((int)p.deck.Length(), 5);
        if(response.choice == 0)
        {
            for(int cardIndex = 0; cardIndex < cardsToReveal; cardIndex++)
            {
                Card *c = p.deck.Last();
                p.deck.PopEnd();
                s.stack.PushEnd(new EventDiscardCard(s.player, c, DiscardFromSideZone));
            }
        }
        else
        {
            if(logging) s.LogIndent(1, "puts the cards back on top of their deck");
            s.ReorderDeck(source, s.player, cardsToReveal);
        }
        done = true;
    }

    Card *source;
    bool done;
};

class EventLookout : public Event
{
public:
    EventLookout(Card *_source)
    {
        source = _source;
        done = false;
        cardToTrash = NULL;
        revealedCards[0] = NULL;
        revealedCards[1] = NULL;
        revealedCards[2] = NULL;
    }
    bool CanProcessDecisions() const
    {
        return true;
    }
    UINT Stage() const
    {
        int count = 0;
        if(revealedCards[0] != NULL) count++;
        if(revealedCards[1] != NULL) count++;
        if(revealedCards[2] != NULL) count++;
        if(count == 0) return 0;
        if(count == 3) return 1;
        if(count == 2) return 2;
        return -1;
    }
    bool Advance(State &s)
    {
        if(done) return true;

        PlayerState &p = s.players[s.player];

        int stage = Stage();
        if(stage == 0)
        {
            if(p.deck.Length() < 3) s.Shuffle(s.player);
            if(p.deck.Length() < 3)
            {
                if(logging) s.Log("does not have enough cards to reveal");
                return true;
            }

            for(int cardIndex = 0; cardIndex < 3; cardIndex++)
            {
                revealedCards[cardIndex] = p.deck.Last();
                p.deck.PopEnd();
                if(logging) s.LogIndent(1, "reveals " + revealedCards[cardIndex]->PrettyName());
            }

            s.decision.SelectCards(source, 1, 1);
            if(decisionText) s.decision.text = "Choose a card to trash:";
            for(int i = 0; i < 3; i++) s.decision.AddUniqueCard(revealedCards[i]);
        }

        return false;
    }
    void ProcessDecision(State &s, const DecisionResponse &response)
    {
        int stage = Stage();
        if(stage == 1)
        {
            cardToTrash = response.cards[0];

            s.decision.SelectCards(source, 1, 1);
            if(decisionText) s.decision.text = "Choose a card to discard:";
            bool cardFound = false;
            for(int i = 0; i < 3; i++)
            {
                if(!cardFound && revealedCards[i] == response.cards[0])
                {
                    cardFound = true;
                    revealedCards[i] = NULL;
                }
                if(revealedCards[i] != NULL) s.decision.AddUniqueCard(revealedCards[i]);
            }
        }
        else if(stage == 2)
        {
            s.stack.PushEnd(new EventDiscardCard(s.player, response.cards[0], DiscardFromSideZone));
            s.stack.PushEnd(new EventTrashCardFromSideZone(s.player, cardToTrash));
            bool cardFound = false;
            for(int i = 0; i < 3; i++)
            {
                if(!cardFound && revealedCards[i] == response.cards[0])
                {
                    cardFound = true;
                    revealedCards[i] = NULL;
                }
            }
            for(int i = 0; i < 3; i++)
            {
                if(revealedCards[i] != NULL)
                {
                    if(logging) s.LogIndent(1, "puts " + revealedCards[i]->PrettyName() + " on top of their deck");
                    s.players[s.player].deck.PushEnd(revealedCards[i]);
                }
            }
            done = true;
        }
    }

    Card *source;
    Card *revealedCards[3];
    Card *cardToTrash;
    bool done;
};

class EventSeaHagAttack : public Event
{
public:
    EventSeaHagAttack(Card *_source, UINT _player)
    {
        source = _source;
        player = _player;
    }
    bool IsAttack() const
    {
        return true;
    }
    int AttackedPlayer() const
    {
        return player;
    }
    AttackAnnotations* Annotations()
    {
        return &annotations;
    }
    bool Advance(State &s)
    {
        PlayerState &p = s.players[player];
        if(p.deck.Length() == 0) s.Shuffle(player);

        s.stack.PushEnd(new EventGainCard(player, s.data->baseCards.curse, false, false, GainToDeckTop));

        if(p.deck.Length() == 0)
        {
            if(logging) s.LogIndent(1, player, "has no cards to reveal");
        }
        else
        {
            if(logging) s.LogIndent(1, player, "reveals " + p.deck.Last()->PrettyName());
            s.stack.PushEnd(new EventDiscardCard(player, p.deck.Last(), DiscardFromSideZone));
            p.deck.PopEnd();
        }
        return true;
    }
    Card *source;
    UINT player;
    AttackAnnotations annotations;
};

class EventCutpurseAttack : public Event
{
public:
    EventCutpurseAttack(Card *_source, UINT _player)
    {
        source = _source;
        player = _player;
    }
    bool IsAttack() const
    {
        return true;
    }
    int AttackedPlayer() const
    {
        return player;
    }
    AttackAnnotations* Annotations()
    {
        return &annotations;
    }
    bool Advance(State &s)
    {
        PlayerState &p = s.players[player];

        if(p.hand.Contains(s.data->baseCards.copper))
        {
            s.stack.PushEnd(new EventDiscardCard(player, s.data->baseCards.copper, DiscardFromHand));
        }
        else
        {
            if(logging) for(Card *c : p.hand) s.LogIndent(1, player, "reveals " + c->PrettyName());
        }
        return true;
    }
    Card *source;
    UINT player;
    AttackAnnotations annotations;
};

class EventAmbassador : public Event
{
public:
    EventAmbassador(Card *_source)
    {
        source = _source;
        revealedCard = NULL;
        done = false;
    }
    bool CanProcessDecisions() const
    {
        return true;
    }
    bool Advance(State &s)
    {
        if(done) return true;

        if(revealedCard == NULL)
        {
            PlayerState &p = s.players[s.player];

            if(p.hand.Length() == 0)
            {
                if(logging) s.LogIndent(1, "has no cards to reveal");
                return true;
            }

            s.decision.SelectCards(source, 1, 1);
            if(decisionText) s.decision.text = "Choose a card to reveal:";
            s.decision.AddUniqueCards(p.hand);
        }

        return false;
    }
    void ProcessDecision(State &s, const DecisionResponse &response)
    {
        PlayerState &p = s.players[s.player];
        if(revealedCard == NULL)
        {
            revealedCard = response.cards[0];
            if(logging) s.LogIndent(1, "reveals " + revealedCard->PrettyName());

            int handCount = 0;
            for(Card *c : p.hand) if(c == revealedCard) handCount++;
            handCount = Math::Min(handCount, 2);

            if(handCount == 1)
            {
                s.decision.MakeDiscreteChoice(source, 2);
                if(decisionText) s.decision.text = "Return how many cards to the supply?|0|1";
            }
            else if(handCount == 2)
            {
                s.decision.MakeDiscreteChoice(source, 3);
                if(decisionText) s.decision.text = "Return how many cards to the supply?|0|1|2";
            }
        }
        else
        {
            if(logging) s.LogIndent(1, "returns " + String(response.choice) + " " + revealedCard->PrettyName() + " to the supply");
            for(UINT returnIndex = 0; returnIndex < response.choice; returnIndex++)
            {
                p.hand.RemoveSwap(p.hand.FindFirstIndex(revealedCard));
                s.supply[s.data->SupplyIndex(revealedCard)].count++;
            }

            for(const PlayerInfo &p : s.data->players)
            {
                if(p.index != s.player)
                {
                    s.stack.PushEnd(new EventGainCard(p.index, revealedCard, false, true, GainToDiscard));
                }
            }

            done = true;
        }
    }

    Card *source;
    Card *revealedCard;
    bool done;
};

class EventExplorer : public Event
{
public:
    EventExplorer(Card *_source)
    {
        source = _source;
        done = false;
    }
    bool Advance(State &s)
    {
        if(done) return true;

        PlayerState &p = s.players[s.player];

        if(p.hand.Contains(s.data->baseCards.province))
        {
            s.decision.MakeDiscreteChoice(source, 2);
            if(decisionText) s.decision.text = "Reveal a Province?|Yes|No";
            return false;
        }
        else
        {
            s.stack.PushEnd(new EventGainCard(s.player, s.data->baseCards.silver, false, false, GainToHand));
            return true;
        }
    }
    bool CanProcessDecisions() const
    {
        return true;
    }
    void ProcessDecision(State &s, const DecisionResponse &response)
    {
        PlayerState &p = s.players[s.player];
        if(response.choice == 0)
        {
            if(logging) s.LogIndent(1, "reveals a " + s.data->baseCards.province->PrettyName());
            s.stack.PushEnd(new EventGainCard(s.player, s.data->baseCards.gold, false, false, GainToHand));
        }
        else
        {
            s.stack.PushEnd(new EventGainCard(s.player, s.data->baseCards.silver, false, false, GainToHand));
        }
        done = true;
    }

    Card *source;
    bool done;
};


text:
var app = module.parent.exports.app;
var passport = module.parent.exports.passport;
var Employees = require('../models/employees.js');
var Admins = require('../models/admins.js');

//securizar rutas
var adminAuth = function(req, res, next){
    //authorize role
    if(typeof req.user != "undefined"){
        next();
    }else{
        //Not authorized redirect
        res.redirect('/');
    }
}

app.use(function(req, res, next) {
    res.locals.user = req.user;
    next();
});

app.get('/admin', function(req, res){
    if (req.user) {
        res.redirect('/panel/employees');
    };
    var msg = req.flash('message');
    res.render('admin', { title: 'Login', flashmsg: msg});
});

app.post('/admin',function(req, res, next){
    req.flash('message', 'Error to login!');
    next();
},
    passport.authenticate('AdminLogin',
    { successRedirect: '/panel/employees',
      failureRedirect: '/admin',
      failureFlash: true
    }));

app.get('/logout', function(req, res){
    req.logout();
    res.redirect('/');
});

app.get('/panel/employees', adminAuth, function(req, res){
    var msg = req.flash('message'); // Read the flash message
    Employees.find({}, function(err, docs){
        res.render('employees', { title: 'Employees', employee: docs, flashmsg: msg}); //Pass the flash message to the view
    });
});

//parte de pedido por ajax
app.get('/employees/search/:name', function(req, res){
    Employees.find({ name: new RegExp(".*"+req.params.name+".*", 'gi') })
        //.populate('sueldo')
        //.limit(10)
        .select('-password')
        //.skip(4)
        .exec( function(err, docs){
           res.json(docs);
    });

});

app.get('/panel/employees/new', adminAuth, function(req, res){
    req.flash('message', 'You added a new employee!'); // Save the flash message in this page
    res.render('new', { title: 'New Employee'});
});

app.post('/panel/employees/new', adminAuth, function(req, res){
    console.log(req.body);
    if (req.body.password === req.body.confirm) {
        var e = new Employees({ name: req.body.name, lastName: req.body.lastName, email: req.body.email });
        e.save(function(err, doc){
            if(!err){
                res.redirect('/panel/employees');
            } else {
                res.end(err);
            }
        });
    }else{
        res.render('new', {title: 'New EMployee', error: true });
    }
});

app.get('/panel/employees/delete/:id', adminAuth, function(req, res){
    req.flash('message', 'You deleted an employee!'); //Save the flash message in this page
    Employees.remove({ _id: req.params.id }, function(err, doc){
        if(!err){
            res.redirect('/panel/employees');
        } else {
            res.end(err);
        }
    });
});

app.get('/panel/employees/edit/:id', adminAuth, function(req, res){
    req.flash('message', 'you modified an employee!'); // Save the flash message in this page
    Employees.findOne({ _id: req.params.id }, function(err, doc){
        if(!err){
            res.render('edit', { title: 'Edit employee', employee: doc});
        } else {
            res.end(err);
        }
    });
});

app.post('/panel/employees/edit/:id', adminAuth, function(req, res){
    Employees.findOne({ _id: req.params.id }, function(err, doc){
        if(!err){
            doc.name = req.body.name;
            doc.lastName = req.body.lastName;
            doc.email = req.body.email;
            doc.save(function(err, doc){
                if(!err){
                    res.redirect('/panel/employees');
                } else {
                    res.end(err);
                }
            });
        } else {
            res.end(err);
        }
    });
});


text:
/*!
 * jquery-inviewport
 * 1.0.0
 * license: MIT
*/

!function(t,e){if("function"==typeof define&&define.amd)define(["exports"],e);else if("undefined"!=typeof exports)e(exports);else{var o={exports:{}};e(o.exports),t.jqueryInViewport=o.exports}}(this,function(t){"use strict";$.fn.inViewport=function(){var t=$(window),e={top:t.scrollTop(),left:t.scrollLeft()};e.right=e.left+t.width(),e.bottom=e.top+t.height();var o=this.offset();return o.right=o.left+this.outerWidth(),o.bottom=o.top+this.outerHeight(),!(e.right<o.left||e.left>o.right||e.bottom<o.top||e.top>o.bottom)}});


text:
FROM alpine:3.5

RUN apk --no-cache add \
    ca-certificates

ADD bin/linux/gostatsd /bin/gostatsd

ENTRYPOINT ["gostatsd"]


text:
TO DO list for LeanCheck
========================

List of things to do for LeanCheck.

Nothing planned at the moment.


text:
using AngWebForm.Framework.Context.Database;
using AngWebForm.Framework.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace AngWebForm.Framework.Context
{
    public class ResumeDbContext : IDbContext
    {
        #region Constructors and Properties
        private const string KEY_Resumes = "KEY_Resumes";
        private const string KEY_Users = "KEY_Users";
        private const string KEY_Jobs = "KEY_Jobs";
        private const string KEY_Training = "KEY_Training";
        private const string KEY_Schools = "KEY_Schools";

        public ResumeDbContext()
        {
            Schools = HttpRuntime.Cache[KEY_Schools] as IQueryable<School>;
            if (Schools == null)
                Schools = ResetCache<School>(KEY_Schools, Data.Schools.AsQueryable());

            Training = HttpRuntime.Cache[KEY_Training] as IQueryable<Education>;
            if (Training == null)
                Training = ResetCache<Education>(KEY_Training, Data.Training.AsQueryable());

            Jobs = HttpRuntime.Cache[KEY_Jobs] as IQueryable<WorkExperience>;
            if (Jobs == null)
                Jobs = ResetCache<WorkExperience>(KEY_Jobs, Data.Jobs.AsQueryable());

            Users = HttpRuntime.Cache[KEY_Users] as IQueryable<User>;
            if (Users == null)
                Users = ResetCache<User>(KEY_Users, Data.Users.AsQueryable());

            Resumes = HttpRuntime.Cache[KEY_Resumes] as IQueryable<Resume>;
            if (Resumes == null)
                Resumes = ResetCache<Resume>(KEY_Resumes, Data.Resumes.AsQueryable());
        }

        private IQueryable<T> ResetCache<T>(string key, IQueryable<T> data)
        {
            HttpRuntime.Cache.Add(key, data, null, System.Web.Caching.Cache.NoAbsoluteExpiration, new TimeSpan(0, 0, 15), System.Web.Caching.CacheItemPriority.Default, null);
            return data;
        }
        #endregion

        #region IDbContext
        public IQueryable<School> Schools { get; set; }
        public IQueryable<Education> Training { get; set; }
        public IQueryable<WorkExperience> Jobs { get; set; }
        public IQueryable<User> Users { get; set; }
        public IQueryable<Resume> Resumes { get; set; }

        void IDbContext.SaveChanges()
        {
            throw new NotImplementedException();
        }
        #endregion

        #region IDisposable
        public void Dispose()
        {
        }
        #endregion
    }
}


text:
package syndicate

import (
	"testing"
)

func TestFilter(t *testing.T) {

}


text:
define([], function () {

    var _spacing = 0;

    var _getSpacing = function _getSpacing() {
        return _spacing;
    };

    var _setSpacing = function _setSpacing(value) {
        _spacing = value;
    };

    return {
        getSpacing: _getSpacing,
        setSpacing: _setSpacing
    };

});


text:
'''
  Author Alumet 2015
  https://github.com/Alumet/Codingame
'''

surface_n = int(input())  # the number of points used to draw the surface of Mars.
for i in range(surface_n):
    # land_x: X coordinate of a surface point. (0 to 6999)
    # land_y: Y coordinate of a surface point. By linking all the points together in a sequential fashion, you form the surface of Mars.
    land_x, land_y = [int(j) for j in input().split()]

# game loop
while 1:
    # h_speed: the horizontal speed (in m/s), can be negative.
    # v_speed: the vertical speed (in m/s), can be negative.
    # fuel: the quantity of remaining fuel in liters.
    # rotate: the rotation angle in degrees (-90 to 90).
    # power: the thrust power (0 to 4).
    x, y, h_speed, v_speed, fuel, rotate, power = [int(i) for i in input().split()]

    # rotate power. rotate is the desired rotation angle. power is the desired thrust power.
    if y>2500:
        print(rotate,power)
    else:
        if v_speed<-20 and power<4:
            power+=1
            print(rotate,power)
        elif v_speed>-20 and power>0:
            power-=1
            print(rotate,power)
        else:
            print(rotate,power)


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<title>LampController</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="date" content="2018-04-23">
<link rel="stylesheet" type="text/css" href="../../stylesheet.css" title="Style">
<link rel="stylesheet" type="text/css" href="../../jquery/jquery-ui.css" title="Style">

JavaScript is disabled on your browser.

Skip navigation links

Overview

Package

Class

Tree

Deprecated

Index

Help

Prev Class

Next Class

Frames

No Frames

All Classes

SEARCH:
<input type="text" id="search" value=" " disabled="disabled">
<input type="reset" id="reset" value=" " disabled="disabled">

JavaScript is disabled on your browser.

Summary:

Nested |

Field |

Constr |

Method

Detail:

Field |

Constr |

Method

Package lejos.robotics

Interface LampController

<map id="G" name="G">
<area shape="rect" id="node1_0" href="./LampController.html" title="lejos.robotics.LampController" alt="" coords="16,11,220,137"/>
<area shape="rect" id="node1" href="./LampController.html" title="<TABLE>" alt="" coords="5,5,231,143"/>
</map>

public interface LampController

Interface for a light sensors that also includes a lamp (usually LED) to provide illumination.

Method Summary

All Methods Instance Methods Abstract Methods

Modifier and Type
Method and Description

int
getFloodlight()

Returns the color of the floodlight, including Color.NONE.

boolean
isFloodlightOn()

Checks if the floodlight is currently on.

void
setFloodlight(boolean floodlight)

Turns the default LED light on or off.

boolean
setFloodlight(int color)

Used to turn on or off the floodlight by color.

Method Detail

setFloodlight

void setFloodlight(boolean floodlight)

Turns the default LED light on or off. If the sensors has more than one lamp color, this will
 control the red LED.

Parameters:

floodlight - true to turn on lamp, false for off (ambient light only).

isFloodlightOn

boolean isFloodlightOn()

Checks if the floodlight is currently on.

Returns:

true if on, false if off.

getFloodlight

int getFloodlight()

Returns the color of the floodlight, including Color.NONE.

Returns:

An enumeration of the current color.

setFloodlight

boolean setFloodlight(int color)

Used to turn on or off the floodlight by color. If the sensors has multiple light colors, you can control
 which color is turned on or off. If the color does not exist, it does nothing and returns false. You can turn
 the floodlight off by using Color.NONE.

Parameters:

color - Use Color enumeration constant to control lamp colors.

Returns:

True if lamp changed, false if lamp color doesn't exist for this sensors.

Skip navigation links

Overview

Package

Class

Tree

Deprecated

Index

Help

Prev Class

Next Class

Frames

No Frames

All Classes

JavaScript is disabled on your browser.

Summary:

Nested |

Field |

Constr |

Method

Detail:

Field |

Constr |

Method


text:
package com.intellij.java.codeInsight.daemon.lambda;

import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase5;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Test;

class UncheckedWarningInferenceTest extends LightJavaCodeInsightFixtureTestCase5 {

  @NotNull
  @Override
  protected String getRelativePath() {
    return super.getRelativePath() + "/codeInsight/daemonCodeAnalyzer/lambda/unchecked/";
  }

  @Test
  void testDontTreatAsUncheckedIfRawWasAssignedInRawParameter() { doTest(); }

  private void doTest() {
    getFixture().testHighlighting(getTestName(false) + ".java");
  }
}


text:
package com.abewy.android.apps.klyph.view;

import com.abewy.android.apps.klyph.R;
import android.content.Context;
import android.content.res.Resources;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.MeasureSpec;

public class DismissibleListItemView extends SlidingPanelLayout
{
	private final int				mDismissScrollDeltaThreshold;
	private int						mDismissWidthThreshold;
	private boolean 					mDismissed							= false;
	private boolean 					mDismissible;
	private TransalatableTextView	mLeftBackgroundView;
	private ListItemActionListener	mListItemActionListener;
	private int						mRead								= 0;
	private TransalatableTextView	mRightBackgroundView;
	private int						mScrollDelta;
	private Runnable				mScrollToInitialPositionRunnable	= new Runnable() {
																			public final void run()
																			{
																				DismissibleListItemView.this.smoothScrollTo(0);
																			}
																		};
	private Runnable				mScrollToLeftRunnable				= new Runnable() {
																			public final void run()
																			{
																				DismissibleListItemView.this
																						.smoothScrollTo(DismissibleListItemView.this.mWidth);
																				DismissibleListItemView.this.dismiss();
																			}
																		};
	private Runnable				mScrollToRightRunnable				= new Runnable() {
																			public final void run()
																			{
																				DismissibleListItemView.this
																						.smoothScrollTo(-DismissibleListItemView.this.mWidth);
																				DismissibleListItemView.this.dismiss();
																			}
																		};
	private int						mWidth;

	public DismissibleListItemView(Context paramContext)
	{
		this(paramContext, null);
	}

	public DismissibleListItemView(Context paramContext, AttributeSet paramAttributeSet)
	{
		this(paramContext, paramAttributeSet, 0);
	}

	public DismissibleListItemView(Context paramContext, AttributeSet paramAttributeSet, int paramInt)
	{
		super(paramContext, paramAttributeSet, paramInt);
		setVertical(false);
		setScrollEnabled(true);
		this.mDismissScrollDeltaThreshold = paramContext.getResources().getDimensionPixelSize(R.dimen.notification_dismiss_scroll_delta_threshold);
	}

	private void onSwipeComplete(int paramInt)
	{
		if ((paramInt < -this.mDismissWidthThreshold)
			|| ((paramInt < 0) && (this.mScrollDelta < 0) && (-this.mScrollDelta > this.mDismissScrollDeltaThreshold)))
		{
			post(this.mScrollToRightRunnable);
			return;
		}
		if ((paramInt > this.mDismissWidthThreshold)
			|| ((paramInt > 0) && (this.mScrollDelta > 0) && (this.mScrollDelta > this.mDismissScrollDeltaThreshold)))
		{
			post(this.mScrollToLeftRunnable);
			return;
		}
		post(this.mScrollToInitialPositionRunnable);
	}

	private static void updateBackgroundView(TransalatableTextView transalatabletextview, int i, boolean  flag)
	{
		if (flag)
		{
			i = -i;
		}
		if (transalatabletextview != null)
		{
			if (i > 0)
			{
				transalatabletextview.setVisibility(0);
				int j = transalatabletextview.getMeasuredWidth();
				float f;
				if (i >= j)
				{
					f = 0F;
				}
				else
				{
					float f1 = i;
					float f2 = j;
					f = f1 - f2;
				}
				if (!flag)
				{
					f = -f;
				}
				transalatabletextview.setTranslate(f, 0F);
			}
			else
			{
				transalatabletextview.setVisibility(8);
			}
		}
	}

	public final void dismiss()
	{
		if (!this.mDismissed)
		{
			this.mDismissed = true;
			if (this.mListItemActionListener != null)
				this.mListItemActionListener.onDismiss();
		}
	}

	public final void init(TransalatableTextView paramTransalatableTextView1, TransalatableTextView paramTransalatableTextView2, boolean  paramboolean)
	{
		this.mDismissible = paramboolean;
		this.mDismissed = false;
		this.mLeftBackgroundView = paramTransalatableTextView1;
		this.mRightBackgroundView = paramTransalatableTextView2;
		if (this.mLeftBackgroundView != null)
			this.mLeftBackgroundView.clearAnimation();
		if (this.mRightBackgroundView != null)
			this.mRightBackgroundView.clearAnimation();
		reset(0);
	}

	protected void onLayout(boolean  paramboolean, int paramInt1, int paramInt2, int paramInt3, int paramInt4)
	{
		this.mPanel.layout(0, 0, paramInt3 - paramInt1, paramInt4 - paramInt2);
	}

	protected void onMeasure(int paramInt1, int paramInt2)
	{
		this.mWidth = View.MeasureSpec.getSize(paramInt1);
		this.mDismissWidthThreshold = ((int) (0.5F * this.mWidth));
		int i = View.MeasureSpec.getSize(paramInt2);
		int j = View.MeasureSpec.getMode(paramInt2);
		this.mPanel.measure(View.MeasureSpec.makeMeasureSpec(this.mWidth, 1073741824), View.MeasureSpec.makeMeasureSpec(i, j));
		super.onMeasure(paramInt1, View.MeasureSpec.makeMeasureSpec(this.mPanel.getMeasuredHeight(), 1073741824));
		setScrollLimits(-this.mWidth, this.mWidth);
	}

	protected void onScrollChanged(int paramInt1, int paramInt2, int paramInt3, int paramInt4)
	{
		super.onScrollChanged(paramInt1, paramInt2, paramInt3, paramInt4);
		this.mScrollDelta = (paramInt1 - paramInt3);
		if (Math.abs(paramInt1) == this.mWidth)
			dismiss();
		updateBackgroundView(this.mLeftBackgroundView, paramInt1, true);
		updateBackgroundView(this.mRightBackgroundView, paramInt1, false);
	}

	public boolean  onTouchEvent(MotionEvent paramMotionEvent)
	{
		boolean  flag = super.onTouchEvent(paramMotionEvent);
		if ((!this.mDismissible) || (this.mRead == 1))
			return false;

		switch (paramMotionEvent.getAction())
		{
			case 2:
			default:
			case 1:
			case 3:
		}

		/*int i = getScroll();
		if ((i == 0) && (this.mListItemActionListener != null))
		{
			// this.mPanel.setBackgroundResource(R.color.generic_selected_item);
			this.mPanel.postDelayed(new Runnable() {
				public final void run()
				{
					DismissibleListItemView.this.setRead(1);
				}
			}, 300L);
			this.mListItemActionListener.onClick();
		}
		else
		{
			onSwipeComplete(i);
		}*/

		//onSwipeComplete(getScroll());
		return flag;
	}

	public void setDismissListener(ListItemActionListener paramListItemActionListener)
	{
		this.mListItemActionListener = paramListItemActionListener;
	}

	public void setRead(int i)
	{
		mRead = i;
		View view = mPanel;
		int flag;
		if (mRead == 0)
		{
			// flag = R.drawable.notification_item_background_unread;
		}
		else
		{
			// flag = R.drawable.notification_item_background_read;
		}
		// view.setBackgroundResource(flag);

		boolean  f = false;
		if (mRead != 1 && mDismissible)
		{
			f = true;
		}
		else
		{
			f = false;
		}
		setScrollEnabled(f);
	}

	public static abstract interface ListItemActionListener
	{
		public abstract void onClick();

		public abstract void onDismiss();
	}
}


text:
import * as Skins from "../data/skins";
import * as S3 from "../s3";
import {
  INSTAGRAM_ACCESS_TOKEN,
  INSTAGRAM_ACCOUNT_ID,
  TWEET_BOT_CHANNEL_ID,
} from "../config";
import { Client } from "discord.js";
import sharp from "sharp";
import SkinModel from "../data/SkinModel";
import UserContext from "../data/UserContext";
import fetch from "node-fetch";

export async function insta(
  discordClient: Client,
  md5: string | null
): Promise<void> {
  if (md5 == null) {
    md5 = await Skins.getSkinToPostToInstagram();
  }
  if (md5 == null) {
    console.error("No skins to post to instagram");
    return;
  }
  const url = await post(md5);

  console.log("Going to post to discord");
  const tweetBotChannel = await discordClient.channels.fetch(
    TWEET_BOT_CHANNEL_ID
  );
  // @ts-ignore
  await tweetBotChannel.send(url);
  console.log("Posted to discord");
}

async function createContent(
  imageUrl: string,
  caption: string
): Promise<string> {
  const url = new URL(
    `https://graph.facebook.com/v12.0/${INSTAGRAM_ACCOUNT_ID}/media`
  );
  url.searchParams.set("access_token", INSTAGRAM_ACCESS_TOKEN);
  url.searchParams.set("image_url", imageUrl);
  url.searchParams.set("caption", caption);
  const response = await fetch(url, { method: "POST" });
  if (!response.ok) {
    throw new Error(`API error: ${await response.text()}`);
  }

  console.log("crate content status", response.status);
  const result: { id: string } = await response.json();
  console.log(result);

  return result.id;
}

async function publish(id: string): Promise<string> {
  const url = new URL(
    `https://graph.facebook.com/v12.0/${INSTAGRAM_ACCOUNT_ID}/media_publish`
  );
  url.searchParams.set("access_token", INSTAGRAM_ACCESS_TOKEN);
  url.searchParams.set("creation_id", id);
  //url.searchParams.set("fields", "permalink");

  const response = await fetch(url, { method: "POST" });
  console.log("publish status", response.status);
  if (!response.ok) {
    throw new Error(`API error: ${await response.text()}`);
  }
  const result: { id: string; permalink: string } = await response.json();
  console.log("publish result", result);
  return result.id;
}

async function getPermalink(id: string): Promise<string> {
  const url = new URL(`https://graph.facebook.com/v12.0/${id}`);
  url.searchParams.set("access_token", INSTAGRAM_ACCESS_TOKEN);
  url.searchParams.set("fields", "permalink");

  const response = await fetch(url);
  console.log("permalink status", response.status);
  if (!response.ok) {
    throw new Error(`API error: ${await response.text()}`);
  }
  const result: { id: string; permalink: string } = await response.json();
  console.log("permalink result", result);
  return result.permalink;
}

const PADDING = 100;
const UPSCALE = 4;

async function post(md5: string): Promise<string> {
  const ctx = new UserContext();
  const skin = await SkinModel.fromMd5Assert(ctx, md5);
  const screenshot = await Skins.getScreenshotBuffer(md5);
  const { width, height } = await sharp(screenshot).metadata();

  const targetWidth = width * UPSCALE;
  const targetHeight = height * UPSCALE;

  const dimension = Math.max(targetWidth, targetHeight) + PADDING;

  const paddingX = (dimension - targetWidth) / 2;
  const paddingY = (dimension - targetHeight) / 2;

  const background = { r: 0, g: 0, b: 0, alpha: 255 };

  const image = await sharp(screenshot)
    .resize(targetWidth, targetHeight, {
      kernel: sharp.kernel.nearest,
    })
    .extend({
      top: paddingY,
      bottom: paddingY,
      left: paddingX,
      right: paddingX,
      background,
    })
    .toBuffer();

  const name = await skin.getFileName();

  const text = `${name}
.
.
.
.
.
#winampskins #winamp #nostalgia #napster #skins #windows #nullsoft #digitalart #design #software #ui #uidesign`;
  console.log("Uplaoding to S3");
  const uploadFileName = `${md5}.png`;
  await S3.putTemp(uploadFileName, image);
  console.log("Done uploading to S3");
  const imageUrl = `https://cdn.webampskins.org/temp/${uploadFileName}`;

  console.log("Creating content...");
  const contentId = await createContent(imageUrl, text);

  console.log("Deleting temp file");
  await S3.putTemp(uploadFileName, image);
  console.log("Publishing content...");
  const id = await publish(contentId);

  console.log("Getting permalink");
  const permalink = await getPermalink(id);
  console.log("Permalink", permalink);

  console.log("Marking posted in DB");
  await Skins.markAsPostedToInstagram(md5, id, permalink);

  return permalink;
}


text:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE erlref SYSTEM "erlref.dtd">

<erlref>

    <copyright>
      <year>2006</year><year>2016</year>
      <holder>Ericsson AB. All Rights Reserved.</holder>
    </copyright>
    <legalnotice>
      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.

    </legalnotice>

    <title>snmpa_conf</title>
    <prepared></prepared>
    <responsible></responsible>
    <docno></docno>
    <approved></approved>
    <checked></checked>
    <date></date>
    <rev></rev>
    <file>snmpa_conf.xml</file>

  <module>snmpa_conf</module>
  <modulesummary>Utility functions for handling the agent config files.</modulesummary>
  <description>

The module <c>snmpa_conf</c> contains various utility functions to
      used for manipulating (write/append/read) the config files of the
      SNMP agent.

    <marker id="types"></marker>
  </description>

    <title>DATA TYPES</title>
    <![CDATA[
transportDomain() = transportDomainUdpIpv4 | transportDomainUdpIpv6

transportAddress() =
    transportAddressIPv4() | transportAddressIPv6()

transportAddressWithPort() =
    transportAddressIPv4WithPort() | transportAddressIPv6WithPort()

transportAddressWithoutPort() =
    transportAddressIPv4WithoutPort() | transportAddressIPv6WithoutPort()

transportAddressIPv4() =
    transportAddressIPv4WithPort() | transportAddressIPv4WithoutPort()
transportAddressIPv4WithPort =
    {transportAddressIPv4WithoutPort(), inet:port_number()} |
    [byte() x 4, byte() x 2]
transportAddressIPv4WithoutPort =
    inet:ip4_address() | [byte() x 4]

transportAddressIPv6() =
    transportAddressIPv6WithPort() | transportAddressIPv6WithoutPort()
transportAddressIPv6WithPort =
    {transportAddressIPv6WithoutPort(), inet:port_number()} |
    [word() x 8, inet:port_number()] |
    [word() x 8, byte() x 2] |
    {byte() x 16, byte() x 2]
transportAddressIPv6WithoutPort =
    inet:ip6_address() | [word() x 8] | [byte() x 16]

transportAddressMask() =
    [] | transportAddressWithPort()

byte() = 0..255
word() = 0..65535
    ]]>

For <c>inet:ip4_address()</c>, <c>inet:ip6_address()</c>
    and <c>inet:port_number()</c>, see also
    <seealso marker="kernel:inet#type-ip_address">
    <c>inet:ip_address()</c></seealso>

    <marker id="agent_entry"></marker>

  <funcs>
    <func>
      <name>agent_entry(Tag, Val) -> agent_entry()</name>
      <fsummary>Create an agent entry</fsummary>
      <type>
        <v>Tag = intAgentTransports | intAgentUDPPort | intAgentMaxPacketSize | snmpEngineMaxMessageSize | snmpEngineID</v>
        <v>Val = term()</v>
        <v>agent_entry() = term()</v>
      </type>
      <desc>

Create an entry for the agent config file, <c>agent.conf</c>.

The type of <c>Val</c> depends on the value of <c>Tag</c>,
          see
          <seealso marker="snmp_agent_config_files#agent_information">Agent Information</seealso>
          for more info.

        <marker id="write_agent_config"></marker>
      </desc>
    </func>

    <func>
      <name>write_agent_config(Dir, Conf) -> ok</name>
      <name>write_agent_config(Dir, Hdr, Conf) -> ok</name>
      <fsummary>Write the agent config to the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Hdr = string()</v>
        <v>Conf = [agent_entry()]</v>
      </type>
      <desc>

Write the agent config to the agent config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

<c>Hdr</c> is an optional file header (note that this text is
          written to the file as is).

See
          <seealso marker="snmp_agent_config_files#agent_information">Agent Information</seealso>
          for more info.

        <marker id="append_agent_config"></marker>
      </desc>
    </func>

    <func>
      <name>append_agent_config(Dir, Conf) -> ok</name>
      <fsummary>Append the agent config to the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Conf = [agent_entry()]</v>
      </type>
      <desc>

Append the config to the current agent config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

See
          <seealso marker="snmp_agent_config_files#agent_information">Agent Information</seealso>
          for more info.

        <marker id="read_agent_config"></marker>
      </desc>
    </func>

    <func>
      <name>read_agent_config(Dir) -> Conf</name>
      <fsummary>Read the agent config from the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Conf = [agent_entry()]</v>
      </type>
      <desc>

Read the current agent config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

See
          <seealso marker="snmp_agent_config_files#agent_information">Agent Information</seealso>
          for more info.

        <marker id="standard_entry"></marker>
      </desc>
    </func>

    <func>
      <name>standard_entry(Tag, Val) -> standard_entry()</name>
      <fsummary>Create an standard entry</fsummary>
      <type>
        <v>Tag = sysDescr | sysObjectID | sysContact | sysName | sysLocation | sysServices | snmpEnableAuthenTraps</v>
        <v>Val = term()</v>
        <v>standard_entry() = term()</v>
      </type>
      <desc>

Create an entry for the agent standard config file,
          <c>standard.conf</c>.

The type of <c>Val</c> depends on the value of <c>Tag</c>,
          see
          <seealso marker="snmp_agent_config_files#system_information">System Information</seealso>
          for more info.

        <marker id="write_standard_config"></marker>
      </desc>
    </func>

    <func>
      <name>write_standard_config(Dir, Conf) -> ok</name>
      <name>write_standard_config(Dir, Hdr, Conf) -> ok</name>
      <fsummary>Write the agent standard config to the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Hdr = string()</v>
        <v>Conf = [standard_entry()]</v>
      </type>
      <desc>

Write the agent standard config to the agent standard
          config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

<c>Hdr</c> is an optional file header (note that this text is
          written to the file as is).

See
          <seealso marker="snmp_agent_config_files#system_information">System Information</seealso>
          for more info.

        <marker id="append_standard_config"></marker>
      </desc>
    </func>

    <func>
      <name>append_standard_config(Dir, Conf) -> ok</name>
      <fsummary>Append the agent standard config to the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Conf = [standard_entry()]</v>
      </type>
      <desc>

Append the standard config to the current agent standard
          config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

See
          <seealso marker="snmp_agent_config_files#system_information">System Information</seealso>
          for more info.

        <marker id="read_standard_config"></marker>
      </desc>
    </func>

    <func>
      <name>read_standard_config(Dir) -> Conf</name>
      <fsummary>Read the agent standard config from the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Conf = [standard_entry()]</v>
      </type>
      <desc>

Read the current agent standard config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

See
          <seealso marker="snmp_agent_config_files#system_information">System Information</seealso>
          for more info.

        <marker id="context_entry"></marker>
      </desc>
    </func>

    <func>
      <name>context_entry(Context) -> context_entry()</name>
      <fsummary>Create an context entry</fsummary>
      <type>
        <v>Context = string()</v>
        <v>context_entry() = term()</v>
      </type>
      <desc>

Create an entry for the agent context config file,
          <c>context.conf</c>.

See
          <seealso marker="snmp_agent_config_files#context">Contexts</seealso>
          for more info.

        <marker id="write_context_config"></marker>
      </desc>
    </func>

    <func>
      <name>write_context_config(Dir, Conf) -> ok</name>
      <name>write_context_config(Dir, Hdr, Conf) -> ok</name>
      <fsummary>Write the agent context(s) to the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Hdr = string()</v>
        <v>Conf = [context_entry()]</v>
      </type>
      <desc>

Write the agent context config to the agent context
          config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

<c>Hdr</c> is an optional file header (note that this text is
          written to the file as is).

See
          <seealso marker="snmp_agent_config_files#context">Contexts</seealso>
          for more info.

        <marker id="append_context_config"></marker>
      </desc>
    </func>

    <func>
      <name>append_context_config(Dir, Conf) -> ok</name>
      <fsummary>Append the agent context(s) to the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Conf = [context_entry()]</v>
      </type>
      <desc>

Append the context config to the current agent context
          config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

See
          <seealso marker="snmp_agent_config_files#context">Contexts</seealso>
          for more info.

        <marker id="read_context_config"></marker>
      </desc>
    </func>

    <func>
      <name>read_context_config(Dir) -> Conf</name>
      <fsummary>Read the agent context config from the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Conf = [context_entry()]</v>
      </type>
      <desc>

Read the current agent context config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

See
          <seealso marker="snmp_agent_config_files#context">Contexts</seealso>
          for more info.

        <marker id="community_entry"></marker>
      </desc>
    </func>

    <func>
      <name>community_entry(CommunityIndex) -> community_entry()</name>
      <name>community_entry(CommunityIndex, CommunityName, SecName, ContextName, TransportTag) -> community_entry()</name>
      <fsummary>Create an community entry</fsummary>
      <type>
        <v>CommunityIndex = string()</v>
        <v>CommunityName = string()</v>
        <v>SecName = string()</v>
        <v>CtxName = string()</v>
        <v>TransportTag = string()</v>
        <v>community_entry() = term()</v>
      </type>
      <desc>

Create an entry for the agent community config file,
          <c>community.conf</c>.

<c>CommunityIndex</c> must be a non-empty string.

<c>community_entry("public")</c> translates to the following call:
          <c>community_entry(CommunityIndex, CommunityIndex, "initial", "", "")</c>.

<c>community_entry("all-rights")</c> translates to the following
          call: <c>community_entry(CommunityIndex, CommunityIndex, CommunityIndex, "", "")</c>.

See
          <seealso marker="snmp_agent_config_files#community">Community</seealso>
          for more info.

        <marker id="write_community_config"></marker>
      </desc>
    </func>

    <func>
      <name>write_community_config(Dir, Conf) -> ok</name>
      <name>write_community_config(Dir, Hdr, Conf) -> ok</name>
      <fsummary>Write the agent community config to the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Hdr = string()</v>
        <v>Conf = [community_entry()]</v>
      </type>
      <desc>

Write the agent community config to the agent community
          config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

<c>Hdr</c> is an optional file header (note that this text is
          written to the file as is).

See
          <seealso marker="snmp_agent_config_files#community">Community</seealso>
          for more info.

        <marker id="append_community_config"></marker>
      </desc>
    </func>

    <func>
      <name>append_community_config(Dir, Conf) -> ok</name>
      <fsummary>Append the agent community config to the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Conf = [community_entry()]</v>
      </type>
      <desc>

Append the community config to the current agent community
          config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

See
          <seealso marker="snmp_agent_config_files#community">Community</seealso>
          for more info.

        <marker id="read_community_config"></marker>
      </desc>
    </func>

    <func>
      <name>read_community_config(Dir) -> Conf</name>
      <fsummary>Read the agent community config from the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Conf = [community_entry()]</v>
      </type>
      <desc>

Read the current agent community config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

See
          <seealso marker="snmp_agent_config_files#community">Communities</seealso>
          for more info.

        <marker id="target_addr_entry"></marker>
      </desc>
    </func>

    <func>
      <name>target_addr_entry(Name, Domain, Addr, TagList, ParamsName, EngineId) -> target_addr_entry()</name>
      <name>target_addr_entry(Name, Domain, Addr, TagList, ParamsName, EngineId, TMask) -> target_addr_entry()</name>
      <name>target_addr_entry(Name, Domain, Addr, TagList, ParamsName, EngineId, TMask, MaxMessageSize) -> target_addr_entry()</name>
      <name>target_addr_entry(Name, Domain, Addr, Timeout, RetryCount, TagList, ParamsName, EngineId, TMask, MaxMessageSize) -> target_addr_entry()</name>
      <fsummary>Create an target_addr entry</fsummary>
      <type>
        <v>Name = string()</v>
        <v>Domain = transportDomain()</v>
        <v>Ip = transportAddress() (depends on Domain)</v>
        <v>Timeout = integer()</v>
        <v>RetryCount = integer()</v>
        <v>TagList = string()</v>
        <v>ParamsName = string()</v>
        <v>EngineId = string()</v>
        <v>TMask = transportAddressMask() (depends on Domain)</v>
        <v>MaxMessageSize = integer()</v>
        <v>target_addr_entry() = term()</v>
      </type>
      <desc>

Create an entry for the agent target_addr config file,
          <c>target_addr.conf</c>.

<c>Name</c> must be a non-empty string.

<c>target_addr_entry/6</c> translates to the following call:
          <c>target_addr_entry(Name, Domain, Addr, TagList, ParamsName, EngineId, [])</c>.

<c>target_addr_entry/7</c> translates to the following call:
          <c>target_addr_entry(Name, Domain, Addr, TagList, ParamsName, EngineId, TMask, 2048)</c>.

<c>target_addr_entry/8</c> translates to the following call:
          <c>target_addr_entry(Name, Domain, Addr, 1500, 3, TagList, ParamsName, EngineId, TMask, MaxMessageSize)</c>.

See
          <seealso marker="snmp_agent_config_files#target_addr">Target Address Definitions</seealso>
          for more info.

        <marker id="write_target_addr_config"></marker>
      </desc>
    </func>

    <func>
      <name>write_target_addr_config(Dir, Conf) -> ok</name>
      <name>write_target_addr_config(Dir, Hdr, Conf) -> ok</name>
      <fsummary>Write the agent target_addr config to the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Hdr = string()</v>
        <v>Conf = [target_addr_entry()]</v>
      </type>
      <desc>

Write the agent target_addr config to the agent target_addr
          config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

<c>Hdr</c> is an optional file header (note that this text is
          written to the file as is).

See
          <seealso marker="snmp_agent_config_files#target_addr">Target Address Definitions</seealso>
          for more info.

        <marker id="append_target_addr_config"></marker>
      </desc>
    </func>

    <func>
      <name>append_target_addr_config(Dir, Conf) -> ok</name>
      <fsummary>Append the agent target_addr config to the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Conf = [target_addr_entry()]</v>
      </type>
      <desc>

Append the target_addr config to the current agent target_addr
          config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

See
          <seealso marker="snmp_agent_config_files#target_addr">Target Address Definitions</seealso>
          for more info.

        <marker id="read_target_addr_config"></marker>
      </desc>
    </func>

    <func>
      <name>read_target_addr_config(Dir) -> Conf</name>
      <fsummary>Read the agent target_addr config from the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Conf = [target_addr_entry()]</v>
      </type>
      <desc>

Read the current agent target_addr config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

See
          <seealso marker="snmp_agent_config_files#target_addr">Target Address Definitions</seealso>
          for more info.

        <marker id="target_params_entry"></marker>
      </desc>
    </func>

    <func>
      <name>target_params_entry(Name, Vsn) -> target_params_entry()</name>
      <name>target_params_entry(Name, Vsn, SecName, SecLevel) -> target_params_entry()</name>
      <name>target_params_entry(Name, MPModel, SecModel, SecName, SecLevel) -> target_params_entry()</name>
      <fsummary>Create an target_params entry</fsummary>
      <type>
        <v>Name = string()</v>
        <v>Vsn = v1 | v2 | v3</v>
        <v>MPModel = v1 | v2c | v3</v>
        <v>SecModel = v1 | v2c | usm</v>
        <v>SecName = string()</v>
        <v>SecLevel = noAuthNoPriv | authNoPriv | authPriv</v>
        <v>target_params_entry() = term()</v>
      </type>
      <desc>

Create an entry for the agent target_params config file,
          <c>target_params.conf</c>.

<c>Name</c> must be a non-empty string.

<c>Vsn</c> translates into <c>MPModel</c> and <c>SecModel</c> as follows:

\011  Vsn = v1 => MPModel = v1,  SecModel = v1
\011  Vsn = v2 => MPModel = v2c, SecModel = v2c
\011  Vsn = v3 => MPModel = v3,  SecModel = usm

<c>target_params_entry/2</c> translates to the following call:
          <c>target_params_entry(Name, Vsn, "initial", noAuthNoPriv)</c>.

<c>target_params_entry/4</c> translates to the following
          call: <c>target_params_entry(Name, MPModel, SecModel, SecName, SecLevel)</c> where <c>MPModel</c> and
          <c>SecModel</c> is mapped from <c>Vsn</c>, see above.

See
          <seealso marker="snmp_agent_config_files#target_params">Target Parameters Definitions</seealso>
          for more info.

        <marker id="write_target_params_config"></marker>
      </desc>
    </func>

    <func>
      <name>write_target_params_config(Dir, Conf) -> ok</name>
      <name>write_target_params_config(Dir, Hdr, Conf) -> ok</name>
      <fsummary>Write the agent target_params config to the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Hdr = string()</v>
        <v>Conf = [target_params_entry()]</v>
      </type>
      <desc>

Write the agent target_params config to the agent target_params
          config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

<c>Hdr</c> is an optional file header (note that this text is
          written to the file as is).

See
          <seealso marker="snmp_agent_config_files#target_params">Target Parameters Definitions</seealso>
          for more info.

        <marker id="append_target_params_config"></marker>
      </desc>
    </func>

    <func>
      <name>append_target_params_config(Dir, Conf) -> ok</name>
      <fsummary>Append the agent target_params config to the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Conf = [target_params_entry()]</v>
      </type>
      <desc>

Append the target_params config to the current agent target_params
          config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

See
          <seealso marker="snmp_agent_config_files#target_params">Target Parameters Definitions</seealso>
          for more info.

        <marker id="read_target_params_config"></marker>
      </desc>
    </func>

    <func>
      <name>read_target_params_config(Dir) -> Conf</name>
      <fsummary>Read the agent target_params config from the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Conf = [target_params_entry()]</v>
      </type>
      <desc>

Read the current agent target_params config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

See
          <seealso marker="snmp_agent_config_files#target_params">Target Parameters Definitions</seealso>
          for more info.

        <marker id="vacm_entry"></marker>
      </desc>
    </func>

    <func>
      <name>vacm_s2g_entry(SecModel, SecName, GroupName) -> vacm_s2g_entry()</name>
      <name>vacm_acc_entry(GroupName, Prefix, SecModel, SecLevel, Match, ReadView, WriteView, NotifyView) -> vacm_acc_entry()</name>
      <name>vacm_vtf_entry(ViewIndex, ViewSubtree) -> vacm_vtf_entry()</name>
      <name>vacm_vtf_entry(ViewIndex, ViewSubtree, ViewStatus, ViewMask) -> vacm_vtf_entry()</name>
      <fsummary>Create an vacm entry</fsummary>
      <type>
        <v>SecModel = v1 | v2c | usm</v>
        <v>SecName = string()</v>
        <v>GroupName = string()</v>
        <v>Prefix = string()</v>
        <v>SecLevel = noAuthNoPriv | authNoPriv | authPriv</v>
        <v>Match = prefix | exact</v>
        <v>ReadView = string()</v>
        <v>WriteView = string()</v>
        <v>NotifyView = string()</v>
        <v>ViewIndex = integer()</v>
        <v>ViewSubtree = [integer()]</v>
        <v>ViewStatus = included | excluded</v>
        <v>ViewMask = null | [zero_or_one()]</v>
        <v>zero_or_one() = 0 | 1</v>
        <v>vacm_s2g_entry() = term()</v>
        <v>vacm_acc_entry() = term()</v>
        <v>vacm_vtf_entry() = term()</v>
      </type>
      <desc>

Create an entry for the agent vacm config file,
          <c>vacm.conf</c>.

<c>vacm_vtf_entry/2</c> translates to the following call:
          <c>vacm_vtf_entry(ViewIndex, ViewSubtree, included, null)</c>.

See
          <seealso marker="snmp_agent_config_files#vacm">MIB Views for VACM</seealso>
          for more info.

        <marker id="write_vacm_config"></marker>
      </desc>
    </func>

    <func>
      <name>write_vacm_config(Dir, Conf) -> ok</name>
      <name>write_vacm_config(Dir, Hdr, Conf) -> ok</name>
      <fsummary>Write the agent vacm config to the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Hdr = string()</v>
        <v>Conf = [vacm_entry()]</v>
        <v>vacm_entry() = vacm_sg2_entry() | vacm_acc_entry() | vacm_vtf_entry()</v>
      </type>
      <desc>

Write the agent vacm config to the agent vacm
          config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

<c>Hdr</c> is an optional file header (note that this text is
          written to the file as is).

See
          <seealso marker="snmp_agent_config_files#vacm">MIB Views for VACM</seealso>
          for more info.

        <marker id="append_vacm_config"></marker>
      </desc>
    </func>

    <func>
      <name>append_vacm_config(Dir, Conf) -> ok</name>
      <fsummary>Append the agent vacm config to the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Conf = [vacm_entry()]</v>
      </type>
      <desc>

Append the vacm config to the current agent vacm
          config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

See
          <seealso marker="snmp_agent_config_files#vacm">MIB Views for VACM</seealso>
          for more info.

        <marker id="read_vacm_config"></marker>
      </desc>
    </func>

    <func>
      <name>read_vacm_config(Dir) -> Conf</name>
      <fsummary>Read the agent vacm config from the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Conf = [vacm_entry()]</v>
      </type>
      <desc>

Read the current agent vacm config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

See
          <seealso marker="snmp_agent_config_files#vacm">MIB Views for VACM</seealso>
          for more info.

        <marker id="usm_entry"></marker>
      </desc>
    </func>

    <func>
      <name>usm_entry(EngineId) -> usm_entry()</name>
      <name>usm_entry(EngineID, UserName, SecName, Clone, AuthP, AuthKeyC, OwnAuthKeyC, PrivP, PrivKeyC, OwnPrivKeyC, Public, AuthKey, PrivKey) -> usm_entry()</name>
      <fsummary>Create an usm entry</fsummary>
      <type>
        <v>EngineId = string()</v>
        <v>UserName = string()</v>
        <v>SecName = string()</v>
        <v>Clone = zeroDotZero | [integer()]</v>
        <v>AuthP = usmNoAuthProtocol | usmHMACMD5AuthProtocol, | usmHMACSHAAuthProtocol</v>
        <v>AuthKeyC = string()</v>
        <v>OwnAuthKeyC = string()</v>
        <v>PrivP = usmNoPrivProtocol | usmDESPrivProtocol | usmAesCfb128Protocol</v>
        <v>PrivKeyC = string()</v>
        <v>OwnPrivKeyC = string()</v>
        <v>Public = string()</v>
        <v>AuthKey = [integer()]</v>
        <v>PrivKey = [integer()]</v>
        <v>usm_entry() = term()</v>
      </type>
      <desc>

Create an entry for the agent vacm config file,
          <c>vacm.conf</c>.

<c>usm_entry/1</c> translates to the following call:
          <c>usm_entry("initial", "initial", zeroDotZero, usmNoAuthProtocol, "", "", usmNoPrivProtocol, "", "", "", "", "")</c>.

See
          <seealso marker="snmp_agent_config_files#usm">Security data for USM</seealso>
          for more info.

        <marker id="write_usm_config"></marker>
      </desc>
    </func>

    <func>
      <name>write_usm_config(Dir, Conf) -> ok</name>
      <name>write_usm_config(Dir, Hdr, Conf) -> ok</name>
      <fsummary>Write the agent usm config to the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Hdr = string()</v>
        <v>Conf = [usm_entry()]</v>
      </type>
      <desc>

Write the agent usm config to the agent usm
          config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

<c>Hdr</c> is an optional file header (note that this text is
          written to the file as is).

See
          <seealso marker="snmp_agent_config_files#usm">Security data for USM</seealso>
          for more info.

        <marker id="append_usm_config"></marker>
      </desc>
    </func>

    <func>
      <name>append_usm_config(Dir, Conf) -> ok</name>
      <fsummary>Append the agent usm config to the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Conf = [usm_entry()]</v>
      </type>
      <desc>

Append the usm config to the current agent vacm
          config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

See
          <seealso marker="snmp_agent_config_files#usm">Security data for USM</seealso>
          for more info.

        <marker id="read_usm_config"></marker>
      </desc>
    </func>

    <func>
      <name>read_usm_config(Dir) -> Conf</name>
      <fsummary>Read the agent usm config from the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Conf = [usm_entry()]</v>
      </type>
      <desc>

Read the current agent usm config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

See
          <seealso marker="snmp_agent_config_files#usm">Security data for USM</seealso>
          for more info.

        <marker id="notify_entry"></marker>
      </desc>
    </func>

    <func>
      <name>notify_entry(Name, Tag, Type) -> notify_entry()</name>
      <fsummary>Create an notify entry</fsummary>
      <type>
        <v>Name = string()</v>
        <v>Tag = string()</v>
        <v>Type = trap | inform</v>
        <v>community_entry() = term()</v>
      </type>
      <desc>

Create an entry for the agent notify config file,
          <c>notify.conf</c>.

<c>Name</c> must be a non-empty string.

See
          <seealso marker="snmp_agent_config_files#notify">Notify Definitions</seealso>
          for more info.

        <marker id="write_notify_config"></marker>
      </desc>
    </func>

    <func>
      <name>write_notify_config(Dir, Conf) -> ok</name>
      <name>write_notify_config(Dir, Hdr, Conf) -> ok</name>
      <fsummary>Write the agent notify config to the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Hdr = string()</v>
        <v>Conf = [notify_entry()]</v>
      </type>
      <desc>

Write the agent notify config to the agent notify
          config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

<c>Hdr</c> is an optional file header (note that this text is
          written to the file as is).

See
          <seealso marker="snmp_agent_config_files#notify">Notify Definitions</seealso>
          for more info.

        <marker id="append_notify_config"></marker>
      </desc>
    </func>

    <func>
      <name>append_notify_config(Dir, Conf) -> ok</name>
      <fsummary>Append the agent notify config to the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Conf = [notify_entry()]</v>
      </type>
      <desc>

Append the notify config to the current agent notify
          config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

See
          <seealso marker="snmp_agent_config_files#notify">Notify Definitions</seealso>
          for more info.

        <marker id="read_notify_config"></marker>
      </desc>
    </func>

    <func>
      <name>read_notify_config(Dir) -> Conf</name>
      <fsummary>Read the agent notify config from the config file</fsummary>
      <type>
        <v>Dir = string()</v>
        <v>Conf = [community_entry()]</v>
      </type>
      <desc>

Read the current agent notify config file.

<c>Dir</c> is the path to the directory where to store the
          config file.

See
          <seealso marker="snmp_agent_config_files#notify">Notify Definitions</seealso>
          for more info.

        <marker id="end"></marker>
      </desc>
    </func>
  </funcs>

</erlref>


text:
package woko.async;

/**
 * Listeners for {@link Job} execution notifications.
 */
public interface JobListener {

    /**
     * Invoked when the job has started
     * @param job the job
     */
    void onStart(Job job);

    /**
     * Invoked when the job has progressed
     * @param job the job
     */
    void onProgress(Job job);

    /**
     * Invoked when the job has throw an excption
     * @param job the job
     * @param e the exception
     */
    void onException(Job job, Exception e);

    /**
     * Invoked when the job has ended normally or has been killed
     * @param job the job
     * @param killed true if the job was killed, false otherwise
     */
    void onEnd(Job job, boolean killed);

}


text:
{% extends 'base.html' %}

{% block content %}

            {{ article.author }}, {{ article.date_added }}

    {{ article.content }}

    ← Back to main
{% endblock %}


text:
if(Meteor.isClient){
  // Write your tests here!
// Here is an example.
  Tinytest.add('example', function (test) {

    var datapipe = new DataPipe();

    datapipe.setFetch(function () {
      return [1,2,3,4];
    });

    datapipe.fetch();

    state = datapipe.getState();

    var step = function (res) {
      return res.map(r => {return r*r})
    }

    datapipe.addStep(step);
    datapipe.addStep(function(res){return res;});

    datapipe.process();
    //test.equal(state, 'data processed');

    var res = datapipe.getResult();

    test.equal(res, step([1,2,3,4]));
  });

}


text:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using AM;

using IrbisUI.Grid;

using ManagedIrbis;
using ManagedIrbis.ImportExport;
using ManagedIrbis.Search;
using ManagedIrbis.Worksheet;

using CM=System.Configuration.ConfigurationManager;

namespace SiberianGrider
{
    public partial class Form4
        : Form
    {
        public SiberianTermGrid Grid { get; set; }

        public IrbisConnection Connection { get; set; }

        public Form4()
        {
            InitializeComponent();

            string connectionString = CM.AppSettings["connectionString"];
            Connection = new IrbisConnection();
            Connection.ParseConnectionString(connectionString);
            Connection.Connect();

            Grid = new SiberianTermGrid
            {
                Dock = DockStyle.Fill
            };
            Controls.Add(Grid);

            TermParameters parameters = new TermParameters
            {
                //Database = "IBIS",
                NumberOfTerms = 100,
                //ReverseOrder = false,
                StartTerm = "K=",
                //Format = null
            };

            TermInfo[] terms = Connection.ReadTerms(parameters);
            terms = TermInfo.TrimPrefix(terms, "K=");

            Grid.Load(terms);

            FormClosed += _FormClosed;
        }

        void _FormClosed
            (
                object sender,
                FormClosedEventArgs e
            )
        {
            if (Connection != null)
            {
                Connection.Dispose();
            }
        }

    }
}


text:
package com.example.helloworld.db.jdbi;

import com.example.helloworld.db.FortuneDAO;
import com.example.helloworld.db.model.Fortune;
import org.jdbi.v3.core.Jdbi;

import java.util.List;

public class FortuneRepository implements FortuneDAO {
    private final Jdbi jdbi;

    public FortuneRepository(Jdbi jdbi) {
        this.jdbi = jdbi;
    }

    @Override
    public List<Fortune> list() {
        return jdbi.withExtension(FortuneJDBIImpl.class, FortuneJDBIImpl::list);
    }
}