text:
package org.apache.openwhisk.core.loadBalancer

import java.nio.charset.StandardCharsets
import java.util.concurrent.ThreadLocalRandom
import java.util.concurrent.atomic.LongAdder
import akka.actor.{Actor, ActorRef, ActorRefFactory, ActorSystem, Cancellable, Props}
import akka.event.Logging.InfoLevel
import akka.pattern.ask
import akka.util.Timeout
import org.apache.openwhisk.common.InvokerState.{Healthy, Offline, Unhealthy}
import org.apache.openwhisk.common.LoggingMarkers._
import org.apache.openwhisk.common._
import org.apache.openwhisk.core.connector._
import org.apache.openwhisk.core.controller.Controller
import org.apache.openwhisk.core.entity._
import org.apache.openwhisk.core.entity.size._
import org.apache.openwhisk.core.etcd.EtcdKV.{InvokerKeys, QueueKeys, SchedulerKeys, ThrottlingKeys}
import org.apache.openwhisk.core.etcd.EtcdType._
import org.apache.openwhisk.core.etcd.{EtcdClient, EtcdConfig}
import org.apache.openwhisk.core.scheduler.queue.{CreateQueue, CreateQueueResponse, QueueManager}
import org.apache.openwhisk.core.scheduler.{SchedulerEndpoints, SchedulerStates}
import org.apache.openwhisk.core.service._
import org.apache.openwhisk.core.{ConfigKeys, WarmUp, WhiskConfig}
import org.apache.openwhisk.spi.SpiLoader
import org.apache.openwhisk.utils.retry
import pureconfig._
import pureconfig.generic.auto._

import scala.collection.JavaConverters._
import scala.collection.concurrent.TrieMap
import scala.concurrent.duration._
import scala.concurrent.{ExecutionContext, ExecutionContextExecutor, Future, Promise}
import scala.language.postfixOps
import scala.util.{Failure, Random, Success, Try}

case class FPCPoolBalancerConfig(usePerMinThrottle: Boolean)

class FPCPoolBalancer(config: WhiskConfig,
                      controllerInstance: ControllerInstanceId,
                      etcdClient: EtcdClient,
                      private val feedFactory: FeedFactory,
                      lbConfig: ShardingContainerPoolBalancerConfig =
                        loadConfigOrThrow[ShardingContainerPoolBalancerConfig](ConfigKeys.loadbalancer),
                      private val messagingProvider: MessagingProvider = SpiLoader.get[MessagingProvider])(
  implicit val actorSystem: ActorSystem,
  logging: Logging)
    extends LoadBalancer {

  private implicit val executionContext: ExecutionContext = actorSystem.dispatcher
  // This value is given according to the total waiting time at QueueManager for a new queue to be created.
  private implicit val requestTimeout: Timeout = Timeout(8.seconds)

  private val entityStore = WhiskEntityStore.datastore()

  private val clusterName = loadConfigOrThrow[String](ConfigKeys.whiskClusterName)

  /** key: SchedulerEndpoints, value: SchedulerStates */
  private val schedulerEndpoints = TrieMap[SchedulerEndpoints, SchedulerStates]()
  private val messageProducer = messagingProvider.getProducer(config, Some(ActivationEntityLimit.MAX_ACTIVATION_LIMIT))

  private val watcherName = "distributed-pool-balancer"
  val watcherService: ActorRef = actorSystem.actorOf(WatcherService.props(etcdClient))

  /** State related to invocations and throttling */
  protected[loadBalancer] val activationSlots = TrieMap[ActivationId, DistributedActivationEntry]()
  protected[loadBalancer] val activationPromises =
    TrieMap[ActivationId, Promise[Either[ActivationId, WhiskActivation]]]()

  /** key: queue/${invocationNs}/ns/action/leader, value: SchedulerEndpoints */
  private val queueEndpoints = TrieMap[String, SchedulerEndpoints]()

  private val activationsPerNamespace = TrieMap[UUID, LongAdder]()
  private val activationsPerController = TrieMap[ControllerInstanceId, LongAdder]()
  private val totalActivations = new LongAdder()
  private val totalActivationMemory = new LongAdder()
  private val throttlers = TrieMap[String, Boolean]()

  /**
   * Publishes activation message on internal bus for an invoker to pick up.
   *
   * @param action the action to invoke
   * @param msg the activation message to publish on an invoker topic
   * @param transid the transaction id for the request
   * @return result a nested Future the outer indicating completion of publishing and
   *         the inner the completion of the action (i.e., the result)
   *         if it is ready before timeout (Right) otherwise the activation id (Left).
   *         The future is guaranteed to complete within the declared action time limit
   *         plus a grace period (see activeAckTimeoutGrace).
   */
  override def publish(action: ExecutableWhiskActionMetaData, msg: ActivationMessage)(
    implicit transid: TransactionId): Future[Future[Either[ActivationId, WhiskActivation]]] = {

    val topicBaseName = if (schedulerEndpoints.isEmpty) {
      logging.error(
        this,
        s"Failed to invoke action ${action.fullyQualifiedName(false)}, error: no scheduler endpoint available")
      Future.failed(LoadBalancerException("No scheduler endpoint available"))
    } else {
      val invocationNamespace = msg.user.namespace.name.asString
      val key = QueueKeys.queue(invocationNamespace, action.fullyQualifiedName(false), true)

      queueEndpoints.get(key) match {
        case Some(endPoint) =>
          Future.successful(
            schedulerEndpoints.getOrElse(endPoint, Random.shuffle(schedulerEndpoints.toList).head._2).sid.toString)
        case None =>
          etcdClient
            .get(key)
            .map { res =>
              res.getKvsList.asScala.headOption map { kv =>
                val endPoint: String = kv.getValue
                SchedulerEndpoints
                  .parse(endPoint)
                  .map { endPoint =>
                    queueEndpoints.update(kv.getKey, endPoint)
                    Some(
                      schedulerEndpoints
                        .getOrElse(endPoint, Random.shuffle(schedulerEndpoints.toList).head._2)
                        .sid
                        .toString)
                  }
                  .getOrElse {
                    FPCPoolBalancer.schedule(schedulerEndpoints.values.toIndexedSeq).map { scheduler =>
                      createQueue(invocationNamespace, action.toWhiskAction, msg.action, msg.revision, scheduler)
                      scheduler.sid.toString
                    }
                  }
              } getOrElse {
                FPCPoolBalancer.schedule(schedulerEndpoints.values.toIndexedSeq).map { scheduler =>
                  createQueue(invocationNamespace, action.toWhiskAction, msg.action, msg.revision, scheduler)
                  scheduler.sid.toString
                }
              }
            }
            .map { _.get }
            .recoverWith {
              case _ =>
                Future.failed(LoadBalancerException("No scheduler endpoint available"))
            }
      }
    }
    topicBaseName.flatMap { baseName =>
      val topicName = Controller.topicPrefix + baseName
      val activationResult = setupActivation(msg, action)
      sendActivationToKafka(messageProducer, msg, topicName).map(_ => activationResult)
    }
  }

  private def createQueue(
    invocationNamespace: String,
    actionMetaData: WhiskActionMetaData,
    fullyQualifiedEntityName: FullyQualifiedEntityName,
    revision: DocRevision,
    scheduler: SchedulerStates,
    retryCount: Int = 5,
    excludeSchedulers: Set[SchedulerInstanceId] = Set.empty)(implicit transid: TransactionId): Unit = {
    if (retryCount >= 0)
      scheduler
        .getRemoteRef(QueueManager.actorName)
        .ask(CreateQueue(invocationNamespace, fullyQualifiedEntityName, revision, actionMetaData))
        .mapTo[CreateQueueResponse]
        .onComplete {
          case Success(_) =>
            logging.info(
              this,
              s"Created queue successfully for $invocationNamespace/$fullyQualifiedEntityName on ${scheduler.sid}")
          case Failure(t) =>
            logging.error(
              this,
              s"failed to get response from ${scheduler}, error is $t, will retry for ${retryCount} times")
            // try another scheduler
            FPCPoolBalancer
              .schedule(schedulerEndpoints.values.toIndexedSeq, excludeSchedulers + scheduler.sid)
              .map { newScheduler =>
                createQueue(
                  invocationNamespace,
                  actionMetaData,
                  fullyQualifiedEntityName,
                  revision,
                  newScheduler,
                  retryCount - 1,
                  excludeSchedulers + scheduler.sid)
              }
              .getOrElse {
                logging.error(
                  this,
                  s"failed to create queue for $invocationNamespace/$fullyQualifiedEntityName, no scheduler endpoint available related activations may fail")
              }
        } else
      logging.error(
        this,
        s"failed to create queue for $invocationNamespace/$fullyQualifiedEntityName, related activations may fail")
  }

  /**
   * 2. Update local state with the to be executed activation.
   *
   * All activations are tracked in the activationSlots map. Additionally, blocking invokes
   * are tracked in the activation results map. When a result is received via activeack, it
   * will cause the result to be forwarded to the caller waiting on the result, and cancel
   * the DB poll which is also trying to do the same.
   */
  private def setupActivation(msg: ActivationMessage,
                              action: ExecutableWhiskActionMetaData): Future[Either[ActivationId, WhiskActivation]] = {
    val isBlackboxInvocation = action.exec.pull

    totalActivations.increment()
    totalActivationMemory.add(action.limits.memory.megabytes)
    activationsPerNamespace.getOrElseUpdate(msg.user.namespace.uuid, new LongAdder()).increment()
    activationsPerController.getOrElseUpdate(controllerInstance, new LongAdder()).increment()

    // Timeout is a multiple of the configured maximum action duration. The minimum timeout is the configured standard
    // value for action durations to avoid too tight timeouts.
    // Timeouts in general are diluted by a configurable factor. In essence this factor controls how much slack you want
    // to allow in your topics before you start reporting failed activations.
    val timeout = (action.limits.timeout.duration.max(TimeLimit.STD_DURATION) * lbConfig.timeoutFactor) + 1.minute

    val resultPromise = if (msg.blocking) {
      activationPromises.getOrElseUpdate(msg.activationId, Promise[Either[ActivationId, WhiskActivation]]()).future
    } else Future.successful(Left(msg.activationId))

    // Install a timeout handler for the catastrophic case where an active ack is not received at all
    // (because say an invoker is down completely, or the connection to the message bus is disrupted) or when
    // the active ack is significantly delayed (possibly dues to long queues but the subject should not be penalized);
    // in this case, if the activation handler is still registered, remove it and update the books.
    activationSlots.getOrElseUpdate(
      msg.activationId, {
        val timeoutHandler = actorSystem.scheduler.scheduleOnce(timeout) {
          processCompletion(msg.activationId, msg.transid, forced = true, isSystemError = false)
        }

        // please note: timeoutHandler.cancel must be called on all non-timeout paths, e.g. Success
        DistributedActivationEntry(
          msg.activationId,
          msg.user.namespace.uuid,
          msg.user.namespace.name.asString,
          msg.revision,
          msg.transid,
          action.limits.memory.megabytes.MB,
          action.limits.concurrency.maxConcurrent,
          action.fullyQualifiedName(true),
          timeoutHandler,
          isBlackboxInvocation,
          msg.blocking,
          controllerInstance)
      })

    resultPromise
  }

  /** 3. Send the activation to the kafka */
  private def sendActivationToKafka(producer: MessageProducer,
                                    msg: ActivationMessage,
                                    topic: String): Future[ResultMetadata] = {
    implicit val transid: TransactionId = msg.transid

    MetricEmitter.emitCounterMetric(LoggingMarkers.LOADBALANCER_ACTIVATION_START)
    val start = transid.started(this, LoggingMarkers.CONTROLLER_KAFKA)

    producer.send(topic, msg).andThen {
      case Success(status) =>
        transid.finished(
          this,
          start,
          s"posted to ${status.topic}[${status.partition}][${status.offset}]",
          logLevel = InfoLevel)
      case Failure(_) => transid.failed(this, start, s"error on posting to topic $topic")
    }
  }

  /**
   * Subscribes to active acks (completion messages from the invokers), and
   * registers a handler for received active acks from invokers.
   */
  private val activationFeed: ActorRef =
    feedFactory.createFeed(actorSystem, messagingProvider, processAcknowledgement)

  /** 4. Get the active-ack message and parse it */
  protected[loadBalancer] def processAcknowledgement(bytes: Array[Byte]): Future[Unit] = Future {
    val raw = new String(bytes, StandardCharsets.UTF_8)
    AcknowledegmentMessage.parse(raw) match {
      case Success(acknowledegment) =>
        acknowledegment.isSlotFree.foreach { invoker =>
          processCompletion(
            acknowledegment.activationId,
            acknowledegment.transid,
            forced = false,
            isSystemError = acknowledegment.isSystemError.getOrElse(false))
        }

        acknowledegment.result.foreach { response =>
          processResult(acknowledegment.activationId, acknowledegment.transid, response)
        }

        activationFeed ! MessageFeed.Processed
      case Failure(t) =>
        activationFeed ! MessageFeed.Processed
        logging.error(this, s"failed processing message: $raw")

      case _ =>
        activationFeed ! MessageFeed.Processed
        logging.warn(this, s"Unexpected Acknowledgment message received by loadbalancer: $raw")
    }
  }

  private def renewTimeoutHandler(entry: DistributedActivationEntry,
                                  msg: ActivationMessage,
                                  isSystemError: Boolean): Unit = {
    entry.timeoutHandler.cancel()

    val timeout = (TimeLimit.MAX_DURATION * lbConfig.timeoutFactor) + 1.minute
    val timeoutHandler = actorSystem.scheduler.scheduleOnce(timeout) {
      processCompletion(msg.activationId, msg.transid, forced = true, isSystemError)
    }
    activationSlots.update(msg.activationId, entry.copy(timeoutHandler = timeoutHandler))
  }

  /** 5. Process the result ack and return it to the user */
  private def processResult(aid: ActivationId,
                            tid: TransactionId,
                            response: Either[ActivationId, WhiskActivation]): Unit = {
    // Resolve the promise to send the result back to the user.
    // The activation will be removed from the activation slots later, when the completion message
    // is received (because the slot in the invoker is not yet free for new activations).
    activationPromises.remove(aid).foreach(_.trySuccess(response))
    logging.info(this, s"received result ack for '$aid'")(tid)
  }

  private def deleteActivationSlot(aid: ActivationId, tid: TransactionId): Option[DistributedActivationEntry] = {
    activationSlots.remove(aid) match {
      case option =>
        if (activationSlots.contains(aid)) {
          logging.warn(this, s"Failed to delete $aid from activation slots")(tid)
          throw new Exception(s"Failed to delete $aid from activation slots")
        }
        option
    }
  }

  // Singletons for counter metrics related to completion acks
  protected val LOADBALANCER_COMPLETION_ACK_REGULAR =
    LoggingMarkers.LOADBALANCER_COMPLETION_ACK(controllerInstance, RegularCompletionAck)
  protected val LOADBALANCER_COMPLETION_ACK_FORCED =
    LoggingMarkers.LOADBALANCER_COMPLETION_ACK(controllerInstance, ForcedCompletionAck)
  protected val LOADBALANCER_COMPLETION_ACK_REGULAR_AFTER_FORCED =
    LoggingMarkers.LOADBALANCER_COMPLETION_ACK(controllerInstance, RegularAfterForcedCompletionAck)
  protected val LOADBALANCER_COMPLETION_ACK_FORCED_AFTER_REGULAR =
    LoggingMarkers.LOADBALANCER_COMPLETION_ACK(controllerInstance, ForcedAfterRegularCompletionAck)

  /** Process the completion ack and update the state */
  protected[loadBalancer] def processCompletion(aid: ActivationId,
                                                tid: TransactionId,
                                                forced: Boolean,
                                                isSystemError: Boolean): Unit = {
    implicit val transid = tid
    activationSlots.remove(aid) match {
      case Some(entry) =>
        if (activationSlots.contains(aid))
          Try { retry(deleteActivationSlot(aid, tid)) } recover {
            case _ =>
              logging.error(this, s"Failed to delete $aid from activation slots")
          }
        totalActivations.decrement()
        totalActivationMemory.add(entry.memory.toMB * (-1))
        activationsPerNamespace.get(entry.namespaceId).foreach(_.decrement())
        activationsPerController.get(entry.controllerName).foreach(_.decrement())

        if (!forced) {
          entry.timeoutHandler.cancel()
          // notice here that the activationPromises is not touched, because the expectation is that
          // the active ack is received as expected, and processing that message removed the promise
          // from the corresponding map
          logging.info(this, s"received completion ack for '$aid', system error=$isSystemError")(tid)
          MetricEmitter.emitCounterMetric(LOADBALANCER_COMPLETION_ACK_REGULAR)
        } else {
          logging.error(this, s"Failed to invoke action ${aid.toString}, error: timeout waiting for the active ack")
          MetricEmitter.emitCounterMetric(LOADBALANCER_COMPLETION_ACK_FORCED)

          // the entry has timed out; if the active ack is still around, remove its entry also
          // and complete the promise with a failure if necessary
          activationPromises
            .remove(aid)
            .foreach(
              _.tryFailure(new Throwable("Activation entry has timed out, no completion or active ack received yet")))
        }

      // Active acks that are received here are strictly from user actions - health actions are not part of
      // the load balancer's activation map. Inform the invoker pool supervisor of the user action completion.
      case None if !forced =>
        // Received a completion ack that has already been taken out of the state because of a timeout (forced ack).
        // The result is ignored because a timeout has already been reported to the invokerPool per the force.
        // Logging this condition as a warning because the invoker processed the activation and sent a completion
        // message - but not in time.
        logging.warn(this, s"received completion ack for '$aid' which has no entry, system error=$isSystemError")(tid)
        MetricEmitter.emitCounterMetric(LOADBALANCER_COMPLETION_ACK_REGULAR_AFTER_FORCED)
      case None =>
        // The entry has already been removed by a completion ack. This part of the code is reached by the timeout and can
        // happen if completion ack and timeout happen roughly at the same time (the timeout was triggered before the completion
        // ack canceled the timer). As the completion ack is already processed we don't have to do anything here.
        logging.debug(this, s"forced completion ack for '$aid' which has no entry")(tid)
        MetricEmitter.emitCounterMetric(LOADBALANCER_COMPLETION_ACK_FORCED_AFTER_REGULAR)
    }
  }

  private val queueKey = QueueKeys.queuePrefix
  private val schedulerKey = SchedulerKeys.prefix
  private val throttlingKey = ThrottlingKeys.prefix
  private val watchedKeys = Set(queueKey, schedulerKey, throttlingKey)

  private val watcher = actorSystem.actorOf(Props(new Actor {
    watchedKeys.foreach { key =>
      watcherService ! WatchEndpoint(key, "", true, watcherName, Set(PutEvent, DeleteEvent))
    }

    override def receive: Receive = {
      case WatchEndpointRemoved(watchKey, key, value, true) =>
        watchKey match {
          case `queueKey` =>
            if (key.contains("leader")) {
              queueEndpoints.remove(key)
              activationSlots.values
                .find(entry =>
                  //the leader key's value is queue/invocationNamespace/ns/pkg/act/leader
                  QueueKeys
                    .queue(entry.invocationNamespace, entry.fullyQualifiedEntityName.copy(version = None), true) == key)
                .foreach {
                  entry =>
                    implicit val transid = entry.transactionId
                    logging.warn(
                      this,
                      s"The $key is deleted from ETCD, but there are still unhandled activations for this action, try to create a new queue")
                    WhiskActionMetaData
                      .get(
                        entityStore,
                        entry.fullyQualifiedEntityName.toDocId,
                        DocRevision.empty,
                        entry.revision != DocRevision.empty)
                      .map { actionMetaData =>
                        FPCPoolBalancer
                          .schedule(schedulerEndpoints.values.toIndexedSeq)
                          .map { scheduler =>
                            createQueue(
                              entry.invocationNamespace,
                              actionMetaData,
                              entry.fullyQualifiedEntityName,
                              entry.revision,
                              scheduler)
                          }
                          .getOrElse {
                            logging.error(
                              this,
                              s"Failed to recreate queue for ${entry.fullyQualifiedEntityName}, no scheduler endpoint available")
                          }
                      }
                }
            }
          case `schedulerKey` =>
            SchedulerStates
              .parse(value)
              .map { state =>
                logging.info(this, s"remove scheduler endpoint $state")
                schedulerEndpoints.remove(state.endpoints)
              }
              .recover {
                case t =>
                  logging.error(this, s"Unexpected error$t")
              }

          case `throttlingKey` =>
            throttlers.remove(key)
          case _ =>
        }

      case WatchEndpointInserted(watchKey, key, value, true) =>
        watchKey match {
          case `queueKey` =>
            //ignore parse follower value, just parse leader value's normal value, e.g. on special case, leader key's value may be Removing
            if (key.contains("leader") && value.contains("host")) {
              SchedulerEndpoints
                .parse(value)
                .map { endpoints =>
                  queueEndpoints.update(key, endpoints)
                }
                .recover {
                  case t =>
                    logging.error(this, s"Unexpected error$t")
                }
            }
          case `schedulerKey` =>
            SchedulerStates
              .parse(value)
              .map { state =>
                // if this is a new scheduler, warm up it
                if (!schedulerEndpoints.contains(state.endpoints))
                  warmUpScheduler(key, state.endpoints)
                schedulerEndpoints.update(state.endpoints, state)
              }
              .recover {
                case t =>
                  logging.error(this, s"Unexpected error$t")
              }
          case `throttlingKey` =>
            val throttled = Try {
              value.toBoolean
            }.getOrElse(false)
            throttlers.update(key, throttled)
          case _ =>
        }
    }
  }))

  private[loadBalancer] def getSchedulerEndpoint() = {
    schedulerEndpoints
  }

  private val warmUpQueueCreationRequest =
    ExecManifest.runtimesManifest
      .resolveDefaultRuntime("nodejs:default")
      .map { manifest =>
        val metadata = ExecutableWhiskActionMetaData(
          WarmUp.warmUpAction.path,
          WarmUp.warmUpAction.name,
          CodeExecMetaDataAsString(manifest, false, entryPoint = None))
        CreateQueue(
          WarmUp.warmUpActionIdentity.namespace.name.asString,
          WarmUp.warmUpAction,
          DocRevision.empty,
          metadata.toWhiskAction)
      }

  private def warmUpScheduler(schedulerName: String, scheduler: SchedulerEndpoints): Unit = {
    implicit val transId = TransactionId.warmUp
    logging.info(this, s"Warm up scheduler $scheduler")
    sendActivationToKafka(
      messageProducer,
      WarmUp.warmUpActivation(controllerInstance),
      Controller.topicPrefix + schedulerName.replace(s"$clusterName/", "").replace("/", "")) // warm up kafka

    warmUpQueueCreationRequest.foreach { request =>
      scheduler.getRemoteRef(QueueManager.actorName).ask(request).mapTo[CreateQueueResponse].onComplete {
        case _ => logging.info(this, s"Warmed up scheduler $scheduler")
      }
    }
  }

  protected def loadSchedulerEndpoint(): Unit = {
    etcdClient
      .getPrefix(SchedulerKeys.prefix)
      .map { res =>
        res.getKvsList.asScala.map { kv =>
          val schedulerStates: String = kv.getValue
          SchedulerStates
            .parse(schedulerStates)
            .map { state =>
              // if this is a new scheduler, warm up it
              if (!schedulerEndpoints.contains(state.endpoints))
                warmUpScheduler(kv.getKey, state.endpoints)
              schedulerEndpoints.update(state.endpoints, state)
            }
            .recover {
              case t =>
                logging.error(this, s"Unexpected error$t")
            }
        }
      }
  }

  loadSchedulerEndpoint()

  override def close(): Unit = {
    watchedKeys.foreach { key =>
      watcherService ! UnwatchEndpoint(key, true, watcherName)
    }
    activationFeed ! GracefulShutdown
  }

  /**
   * Returns a message indicating the health of the containers and/or container pool in general.
   *
   * @return a Future[IndexedSeq[InvokerHealth]] representing the health of the pools managed by the loadbalancer.
   **/
  override def invokerHealth(): Future[IndexedSeq[InvokerHealth]] = {
    etcdClient.getPrefix(s"${InvokerKeys.prefix}/").map { res =>
      val healthsFromEtcd = res.getKvsList.asScala.map { kv =>
        val (memory, busyMemory, status, tags, dedicatedNamespaces) = InvokerResourceMessage
          .parse(kv.getValue.toString(StandardCharsets.UTF_8))
          .map { resourceMessage =>
            val status = resourceMessage.status match {
              case Healthy.asString   => Healthy
              case Unhealthy.asString => Unhealthy
              case Offline.asString   => Offline
            }
            (
              resourceMessage.freeMemory.MB,
              resourceMessage.busyMemory.MB,
              status,
              resourceMessage.tags,
              resourceMessage.dedicatedNamespaces)
          }
          .get
        val temporalId = InvokerKeys.getInstanceId(kv.getKey.toString(StandardCharsets.UTF_8))
        val invoker = temporalId.copy(
          userMemory = memory,
          busyMemory = Some(busyMemory),
          tags = tags,
          dedicatedNamespaces = dedicatedNamespaces)

        new InvokerHealth(invoker, status)
      }.toIndexedSeq
      val missingHealths =
        if (healthsFromEtcd.isEmpty) Set.empty[InvokerHealth]
        else
          ((0 to healthsFromEtcd.maxBy(_.id.toInt).id.toInt).toSet -- healthsFromEtcd.map(_.id.toInt))
            .map(id => new InvokerHealth(InvokerInstanceId(id, Some(id.toString), userMemory = 0 MB), Offline))
      (healthsFromEtcd ++ missingHealths) sortBy (_.id.toInt)
    }
  }

  def emitMetrics() = {
    invokerHealth().map(invokers => {
      MetricEmitter.emitGaugeMetric(HEALTHY_INVOKERS, invokers.count(_.status == Healthy))
      MetricEmitter.emitGaugeMetric(UNHEALTHY_INVOKERS, invokers.count(_.status == Unhealthy))
      MetricEmitter.emitGaugeMetric(OFFLINE_INVOKERS, invokers.count(_.status == Offline))
      // Add both user memory and busy memory because user memory represents free memory in this case
      MetricEmitter.emitGaugeMetric(INVOKER_TOTALMEM, invokers.foldLeft(0L) { (total, curr) =>
        if (curr.status.isUsable) {
          curr.id.userMemory.toMB + curr.id.busyMemory.getOrElse(ByteSize(0, SizeUnits.BYTE)).toMB + total
        } else {
          total
        }
      })
      MetricEmitter.emitGaugeMetric(LOADBALANCER_ACTIVATIONS_INFLIGHT(controllerInstance), totalActivations.longValue)
      MetricEmitter
        .emitGaugeMetric(LOADBALANCER_MEMORY_INFLIGHT(controllerInstance, ""), totalActivationMemory.longValue)
    })
  }

  actorSystem.scheduler.scheduleAtFixedRate(10.seconds, 10.seconds)(() => emitMetrics())

  /** Gets the number of in-flight activations for a specific user. */
  override def activeActivationsFor(namespace: UUID): Future[Int] =
    Future.successful(activationsPerNamespace.get(namespace).map(_.intValue()).getOrElse(0))

  /** Gets the number of in-flight activations for a specific controller. */
  override def activeActivationsByController(controller: String): Future[Int] =
    Future.successful(activationsPerController.get(ControllerInstanceId(controller)).map(_.intValue()).getOrElse(0))

  /** Gets the in-flight activations */
  override def activeActivationsByController: Future[List[(String, String)]] =
    Future.successful(
      activationSlots.values.map(entry => (entry.id.asString, entry.fullyQualifiedEntityName.toString)).toList)

  /** Gets the number of in-flight activations for a specific invoker. */
  override def activeActivationsByInvoker(invoker: String): Future[Int] = Future.successful(0)

  /** Gets the number of in-flight activations in the system. */
  override def totalActiveActivations: Future[Int] = Future.successful(totalActivations.intValue())

  /** Gets the throttling for given action. */
  override def checkThrottle(namespace: EntityPath, fqn: String): Boolean = {

    /**
     * Note! The throttle key is assumed to exist unconditionally and is not limited to throttle if not present.
     *
     * Action Throttle true      -> 429
     *                 false     -> Pass (wait 429, Container already exist)
     *                 not exist -> Namespace Throttled true      -> 429 (Cannot create more containers)
     *                                                  false     -> Pass
     *                                                  not exist -> Pass
     */
    throttlers.getOrElse(
      ThrottlingKeys.action(namespace.namespace, fqn),
      throttlers.getOrElse(ThrottlingKeys.namespace(namespace.root), false))
  }
}

object FPCPoolBalancer extends LoadBalancerProvider {

  override def instance(whiskConfig: WhiskConfig, instance: ControllerInstanceId)(implicit actorSystem: ActorSystem,
                                                                                logging: Logging): LoadBalancer = {

    implicit val exe: ExecutionContextExecutor = actorSystem.dispatcher
    val activeAckTopic = s"${Controller.topicPrefix}completed${instance.asString}"
    val maxActiveAcksPerPoll = 128
    val activeAckPollDuration = 1.second

    val feedFactory = new FeedFactory {
      def createFeed(f: ActorRefFactory, provider: MessagingProvider, acker: Array[Byte] => Future[Unit]): ActorRef = {
        f.actorOf(Props {
          new MessageFeed(
            "activeack",
            logging,
            provider.getConsumer(whiskConfig, activeAckTopic, activeAckTopic, maxPeek = maxActiveAcksPerPoll),
            maxActiveAcksPerPoll,
            activeAckPollDuration,
            acker)
        })
      }
    }

    val etcd = EtcdClient(loadConfigOrThrow[EtcdConfig](ConfigKeys.etcd))

    new FPCPoolBalancer(whiskConfig, instance, etcd, feedFactory)
  }

  def requiredProperties: Map[String, String] = WhiskConfig.kafkaHosts

  // TODO modularize rng algorithm
  /**
   * The rng algorithm is responsible for the invoker distribution, and the better the distribution, the smaller the number of rescheduling.
   *
   */
  def rng(mod: Int): Int = ThreadLocalRandom.current().nextInt(mod)

  /**
   * Assign a scheduler to a message, return the scheduler which has least queues
   *
   * @param schedulers Scheduler pool
   * @param excludeSchedulers schedulers which should not be chose
   * @return Assigned a scheduler
   */
  def schedule(schedulers: IndexedSeq[SchedulerStates],
               excludeSchedulers: Set[SchedulerInstanceId] = Set.empty): Option[SchedulerStates] = {
    schedulers.filter(scheduler => !excludeSchedulers.contains(scheduler.sid)).sortBy(_.queueSize).headOption
  }

}

/**
 * State kept for each activation slot until completion.
 *
 * @param id id of the activation
 * @param namespaceId namespace that invoked the action
 * @param timeoutHandler times out completion of this activation, should be canceled on good paths
 */
case class DistributedActivationEntry(id: ActivationId,
                                      namespaceId: UUID,
                                      invocationNamespace: String,
                                      revision: DocRevision,
                                      transactionId: TransactionId,
                                      memory: ByteSize,
                                      maxConcurrent: Int,
                                      fullyQualifiedEntityName: FullyQualifiedEntityName,
                                      timeoutHandler: Cancellable,
                                      isBlackbox: Boolean,
                                      isBlocking: Boolean,
                                      controllerName: ControllerInstanceId = ControllerInstanceId("0"))


text:
'use strict';

angular.module('plumberfinderApp', ['ui.router','ngResource','ngDialog'])
.config(function($stateProvider, $urlRouterProvider) {
        $stateProvider

            // route for the home page
            .state('app', {
                url:'/',
                views: {
                    'header': {
                        templateUrl : 'views/header.html',
                        controller  : 'HeaderController'
                    },
                    'content': {
                        templateUrl : 'views/home.html',
                        controller  : 'HomeController'
                    },
                    'footer': {
                        templateUrl : 'views/footer.html',
                    }
                }

            })

            // route for the info-client page
            .state('app.infoClient', {
                url:'client-info',
                views: {
                    'content@': {
                        templateUrl : 'views/info-client.html',
                        controller  : 'infoClientController'
                    }
                }
            })

            // route for the info-contractor page
            .state('app.infoContractor', {
                url:'contractor-info',
                views: {
                    'content@': {
                        templateUrl : 'views/info-contractor.html',
                        controller  : 'infoContractorController'
                    }
                }
            })

            // route for the register-client page
            .state('app.registerClient', {
                url:'client-register',
                views: {
                    'content@': {
                        templateUrl : 'views/register-client.html',
                        controller  : 'RegisterClientController'
                    }
                }
            })

            // route for the register-contractor page
            .state('app.registerContractor', {
                url:'contractor-register',
                views: {
                    'content@': {
                        templateUrl : 'views/register-contractor.html',
                        controller  : 'RegisterContractorController'
                    }
                }
            })

            // route for the user type page
            .state('app.userTypePage', {
                url:'user-type-page',
                views: {
                    'content@': {
                        templateUrl : 'views/user-type-page.html',
                        controller  : 'UserTypePageController'
                    }
                }
            })

            // route for the user type page
            .state('app.userTypeLogin', {
                url:'user-type-login',
                views: {
                    'content@': {
                        templateUrl : 'views/user-type-login.html',
                        controller  : 'UserTypeLoginController'
                    }
                }
            })

            // route for the client login
            .state('app.loginClient', {
                url:'client-login',
                views: {
                    'content@': {
                        templateUrl : 'views/login-client.html',
                        controller  : 'LoginClientController'
                    }
                }
            })

            // route for the contractor login
            .state('app.loginContractor', {
                url:'contractor-login',
                views: {
                    'content@': {
                        templateUrl : 'views/login-contractor.html',
                        controller  : 'LoginContractorController'
                    }
                }
            })

            // route for the profile page
            .state('app.client', {
                url: 'clients/:id',
                views: {
                    'content@': {
                        templateUrl : 'views/profile.html',
                        controller  : 'ClientController'
                    }
                }
            })

            // route for the profile page
            .state('app.contractor', {
                url: 'contractors/:id',
                views: {
                    'content@': {
                        templateUrl : 'views/profile.html',
                        controller  : 'ContractorController'
                    }
                }
            })

            // route for the jobs page
            .state('app.myJobs', {
                url: 'jobs',
                views: {
                    'content@': {
                        templateUrl : 'views/jobs.html',
                        controller  : 'MyJobsController'
                    }
                }
            })

            // route for the find jobs page
            .state('app.findJob', {
                url: 'find-job',
                views: {
                    'content@': {
                        templateUrl : 'views/job-find.html',
                        controller  : 'FindJobController'
                    }
                }
            })

        $urlRouterProvider.otherwise('/');
    })
;

redpajama_set_name: RedPajamaGithub


text:
'expression!' -match '...........'

'expression!' -match '.*'

'' -match '.*'
#endregion

#region Plus_sign_quantifier

'expression' -match '\w\w\w\w\w\w\w\w\w\w'

'expression' -match '\w+'

'' -match '\w+'

#endregion

#region Optional_matches

'expression','expressions','expressionsss' -match 'expressions?$'

'expression','expressions','expressionsss' -match 'expressions*'

#endregion

#region Maximum_number_of_matches

(Get-ADUser -Filter * | Where-Object Name -Match '\w+account').Name

(Get-ADUser -Filter * | Where-Object Name -Match '\w{3}_\w+').Name

#endregion

#region Minimum_&_maximum_number_of_matches

$PhoneNumber = (Get-ADUser jgreen -Properties OfficePhone).OfficePhone

$PhoneNumber -match '\d+-\d+-\d+'

$Extension = (Get-ADUser -Identity bbailey -Properties OfficePhone).OfficePhone
$LongDistance = (Get-ADUser -Identity gbailey -Properties OfficePhone).OfficePhone

$Extension,$LongDistance -match '\d?-?\d{3}-\d{3}-\d{4}|\d{3,5}'

#endregion


text:
namespace OmniXaml
{
    using System.Collections.Generic;
    using System.Linq;
    using System.Xml.Linq;

    public class DirectiveExtractor
    {
        private const string SpecialNamespace = "special";

        public IEnumerable<Directive> GetDirectives(XElement node)
        {
            return from attr in node.Attributes()
                where !attr.IsNamespaceDeclaration && attr.Name.Namespace == SpecialNamespace
                select new Directive(attr.Name.LocalName, attr.Value);

        }
    }
}


text:
/*jslint browser: true, sloppy: true, white: true, plusplus: true */
/*global ActiveXObject, window */

var PDFObject = function (obj){

    if(!obj || !obj.url){ return false; }

    var pdfobjectversion = "1.2",
        //Set reasonable defaults
        id = obj.id || false,
        width = obj.width || "100%",
        height = obj.height || "100%",
        pdfOpenParams = obj.pdfOpenParams,
        url,
        pluginTypeFound,

        //declare functions
        createAXO,
        hasReaderActiveX,
        hasReader,
        hasGeneric,
        pluginFound,
        setCssForFullWindowPdf,
        buildQueryString,
        get,
        embed;

    /* ----------------------------------------------------
       Supporting functions
       ---------------------------------------------------- */

    createAXO = function (type){
        var ax;
        try {
            ax = new ActiveXObject(type);
        } catch (e) {
            //ensure ax remains null
            ax = null;
        }
        return ax;
    };

    //Tests specifically for Adobe Reader (aka Acrobat) in Internet Explorer
    hasReaderActiveX = function (){

        var axObj = null;

        if (window.ActiveXObject !== undefined) {

            axObj = createAXO("AcroPDF.PDF");

            //If "AcroPDF.PDF" didn't work, try "PDF.PdfCtrl"
            if(!axObj){ axObj = createAXO("PDF.PdfCtrl"); }

            //If either "AcroPDF.PDF" or "PDF.PdfCtrl" are found, return true
            if (axObj !== null) { return true; }

        }

        //If you got to this point, there's no ActiveXObject for PDFs
        return false;

    };

    //Tests specifically for Adobe Reader (aka Adobe Acrobat) in non-IE browsers
    hasReader = function (){

        var i,
            n = navigator.plugins,
            count = n.length,
            regx = /Adobe Reader|Adobe PDF|Acrobat/gi;

        for(i=0; i<count; i++){
            if(regx.test(n[i].name)){
                return true;
            }
        }

        return false;

    };

    //Detects unbranded PDF support
    hasGeneric = function (){
        var plugin = navigator.mimeTypes["application/pdf"];
        return (plugin && plugin.enabledPlugin);
    };

    //Determines what kind of PDF support is available: iPad, Adobe, generic
    pluginFound = function (){
        if(navigator.userAgent.match(/iPad/i) != null) {
            return "iPad";
        }
        if(hasReader() || hasReaderActiveX()){
            return "Adobe";
        }
        if(hasGeneric()) {
            return "generic";
        }
        return null;
    };

    //If setting PDF to fill page, need to handle some CSS first
    setCssForFullWindowPdf = function (){

        var html = document.getElementsByTagName("html"),
            html_style,
            body_style;

        if(!html){ return false; }

        html_style = html[0].style;
        body_style = document.body.style;

        html_style.height = "100%";
        html_style.overflow = "hidden";
        body_style.margin = "0";
        body_style.padding = "0";
        body_style.height = "100%";
        body_style.overflow = "hidden";

    };

    //Creating a querystring for using PDF Open parameters when embedding PDF
    buildQueryString = function(pdfParams){

        var string = "",
            prop;

        if(!pdfParams){ return string; }

        for (prop in pdfParams) {

            if (pdfParams.hasOwnProperty(prop)) {

                string += prop + "=";

                if(prop === "search") {

                    string += encodeURI(pdfParams[prop]);

                } else {

                    string += pdfParams[prop];

                }

                string += "&";

            }

        }

        //Remove last ampersand
        return string.slice(0, string.length - 1);

    };

    //Simple function for returning values from PDFObject
    get = function(prop){

        var value = null;

        switch(prop){
            case "url" : value = url; break;
            case "id" : value = id; break;
            case "width" : value = width; break;
            case "height" : value = height; break;
            case "pdfOpenParams" : value = pdfOpenParams; break;
            case "pluginTypeFound" : value = pluginTypeFound; break;
            case "pdfobjectversion" : value = pdfobjectversion; break;
        }

        return value;

    };

    /* ----------------------------------------------------
       PDF Embedding functions
       ---------------------------------------------------- */

    embed = function(targetID){

        if(!pluginTypeFound){ return false; }

        var targetNode = null;

        if(targetID){

            //Allow users to pass an element OR an element's ID
            targetNode = (targetID.nodeType && targetID.nodeType === 1) ? targetID : document.getElementById(targetID);

            //Ensure target element is found in document before continuing
            if(!targetNode){ return false; }

        } else {

            targetNode = document.body;
            setCssForFullWindowPdf();
            // width = "100%";
            // height = "100%";
            if(pluginTypeFound === 'iPad') {
                // Ideally we want the width and height to be the same as the rendered pdf document.
                // Use large values as default to make sure most pdfs is visible
                width = width || '1000';
                height = height || '4000';
            } else {
                width = "100%";
                height = "100%";
            }

        }

        // targetNode.innerHTML = '<object    data="' +url +'" type="application/pdf" width="' +width +'" height="' +height +'"></object>';
        targetNode.innerHTML = !window.chrome ? '<object data="' + url +'" type="application/pdf" width="' + width + '" height="' + height + '"></object>'
            : '<iframe src="' + url + '" width="' + width + '" height="' + height + '"></iframe>';

        return targetNode.getElementsByTagName("object")[0] || targetNode.getElementsByTagName("iframe")[0];

    };

    //The hash (#) prevents odd behavior in Windows
    //Append optional Adobe params for opening document
    url = encodeURI(obj.url) + "#" + buildQueryString(pdfOpenParams);
    pluginTypeFound = pluginFound();

    this.get = function(prop){ return get(prop); };
    this.embed = function(id){ return embed(id); };
    this.pdfobjectversion = pdfobjectversion;

    return this;

};


text:
package fr.sii.atlantique.siistem.client.model;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonRootName;

import java.io.Serializable;

/**
 * Class Person, with JPA
 * @author Dorian Coqueron & Pierre Gaultier
 * @version 1.0
 */
@JsonRootName("Person")
public class Person implements Serializable{

	private static final long serialVersionUID = 7525202378849284784L;

	@JsonProperty("PersonId")
	private int personID;

	@JsonProperty("Password")
	private String password;

	@JsonProperty("Pseudo")
	private String pseudo;

	@JsonProperty("LastName")
	private String lastName;

	@JsonProperty("FirstName")
	private String firstName;

	@JsonProperty("Job")
	private String job;

	@JsonProperty("PersonEmail")
	private String personEmail;

	@JsonProperty("Phone")
	private String personTelephone;

	@JsonProperty("MailNotif")
	private Boolean mailNotif;

	@JsonProperty("TelNotif")
	private Boolean telNotif;

	@JsonProperty("IDpreference")
	private NotifPreference typeNotif;

	public Person(String pseudo, String job, String personTelephone ) {
		this.pseudo = pseudo;
		this.job = job;
		this.personTelephone = personTelephone;
	}

	public Person(){
		//JPA need empty constructor
	}

	public Boolean getMailNotif() {
		return mailNotif;
	}

	public void setMailNotif(Boolean mailNotif) {
		this.mailNotif = mailNotif;
	}

	public Boolean getTelNotif() {
		return telNotif;
	}

	public void setTelNotif(Boolean telNotif) {
		this.telNotif = telNotif;
	}

	public int getPersonID(){
		return this.personID;
	}

	public void setPersonID(int id){
		this.personID = id;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getPseudo(){
		return this.pseudo;
	}

	public void setPseudo(String pseudo){
		this.pseudo = pseudo;
	}

	public String getLastName(){
		return this.lastName;
	}

	public void setLastName(String lastName){
		this.lastName = lastName;
	}

	public String getFirstName(){
		return this.firstName;
	}

	public void setFirstName(String firstName){
		this.firstName = firstName;
	}

	public String getJob(){
		return this.job;
	}

	public void setString(String job){
		this.job = job;
	}

	public String getPersonEmail() {
		return personEmail;
	}

	public void setPersonEmail(String personEmail) {
		this.personEmail = personEmail;
	}

	public String getPersonTelephone() {
		return personTelephone;
	}

	public void setPersonTelephone(String personTelephone) {
		this.personTelephone = personTelephone;
	}

	public void setJob(String job) {
		this.job = job;
	}

	public NotifPreference getTypeNotif() {
		return typeNotif;
	}

	public void setTypeNotif(NotifPreference typeNotif) {
		this.typeNotif = typeNotif;
	}

	@Override
	public String toString() {
		return "Person [personID=" + personID + ", pseudo=" + pseudo + ", lastName=" + lastName + ", firstName="
				+ firstName + ", job=" + job + ", personEmail=" + personEmail + ", personTelephone=" + personTelephone
				+ "]";
	}

	public boolean checkPerson(){
		return pseudo != null && job != null && lastName != null && personEmail != null;
	}

}


text:
package nz.co.gregs.dbvolution.databases.definitions;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import nz.co.gregs.dbvolution.databases.NuoDB;
import nz.co.gregs.dbvolution.datatypes.DBBoolean;
import nz.co.gregs.dbvolution.datatypes.DBBooleanArray;
import nz.co.gregs.dbvolution.datatypes.DBDate;
import nz.co.gregs.dbvolution.datatypes.DBJavaObject;
import nz.co.gregs.dbvolution.datatypes.QueryableDatatype;

/**
 * Defines the features of the NuoDB database that differ from the standard
 * database.
 *
 *

 * This DBDefinition is automatically included in {@link NuoDB} instances, and
 * you should not need to use it directly.
 *
 *
Support DBvolution at
 * Patreon

 *
 * @author Gregory Graham
 */
public class NuoDBDefinition extends DBDefinition {

	private static final DateFormat DATETIME_FORMAT = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss.SSS");

	@Override
	@SuppressWarnings("deprecation")
	public String getDateFormattedForQuery(Date date) {

		return " DATE_FROM_STR('" + DATETIME_FORMAT.format(date) + "', 'dd/MM/yyyy HH:mm:ss.SSS') ";

	}

	@Override
	protected String getDatabaseDataTypeOfQueryableDatatype(QueryableDatatype qdt) {
		if (qdt instanceof DBBoolean) {
			return " boolean ";
		} else if (qdt instanceof DBBooleanArray) {
			return " VARCHAR(64) ";
		} else if (qdt instanceof DBDate) {
			return " TIMESTAMP(0) ";
		} else if (qdt instanceof DBJavaObject) {
			return " BLOB ";
		} else {
			return super.getDatabaseDataTypeOfQueryableDatatype(qdt);
		}
	}

	@Override
	public String doTruncTransform(String firstString, String secondString) {
		//A1-MOD(A1,1*(A1/ABS(A1)))
//		return ""+firstString+"-MOD("+firstString+",1*("+firstString+"/ABS("+firstString+")))";
		return "(((CAST(((" + firstString + ")>0) AS INTEGER))-0.5)*2)*floor(abs(" + firstString + "))";
	}

	@Override
	public boolean supportsExpFunction() {
		return false;
	}

	@Override
	public String getCurrentUserFunctionName() {
		return "USER()";
	}

	@Override
	public boolean supportsStandardDeviationFunction() {
		return false;
	}

	/**
	 * NuoDB follows the standard, unlike anyone else, and pads the short
	 * string with spaces before comparing.
	 *
	 *

	 * This effectively means strings are trimmed during comparisons whether you
	 * like it or not.
	 *
	 *

	 * While this seems useful, in fact it prevents checking for incorrect strings
	 * and breaks the industrial standard.
	 *
	 * @param firstSQLExpression firstSQLExpression
	 * @param secondSQLExpression secondSQLExpression
	 *
Support DBvolution at
	 * Patreon

	 *
	 * @return SQL
	 */
	@Override
	public String doStringEqualsTransform(String firstSQLExpression, String secondSQLExpression) {
		return "(" + firstSQLExpression + "||'@') = (" + secondSQLExpression + "||'@')";
	}

	@Override
	public String doAddHoursTransform(String dateValue, String numberOfHours) {
		return "DATE_ADD(" + dateValue + ", INTERVAL ((" + numberOfHours + ")*60*60) SECOND )";
	}

	@Override
	public String doAddMinutesTransform(String dateValue, String numberOfMinutes) {
		return "DATE_ADD(" + dateValue + ", INTERVAL ((" + numberOfMinutes + ")*60) SECOND )";
	}

	@Override
	public String doCurrentDateOnlyTransform() {
		return getCurrentDateOnlyFunctionName().trim();
	}

	@Override
	public String doDayDifferenceTransform(String dateValue, String otherDateValue) {
		return "ROUND(CAST(" + otherDateValue + " AS TIMESTAMP) - CAST(" + dateValue + " AS TIMESTAMP))";
	}

	@Override
	public String doWeekDifferenceTransform(String dateValue, String otherDateValue) {
		return "(" + doDayDifferenceTransform(dateValue, otherDateValue) + "/7)";
	}

	@Override
	public String doMonthDifferenceTransform(String dateValue, String otherDateValue) {
		return "ROUND((CAST(" + otherDateValue + " AS TIMESTAMP) - CAST(" + dateValue + " AS TIMESTAMP))/30.43)";
	}

	@Override
	public String doYearDifferenceTransform(String dateValue, String otherDateValue) {
		return "ROUND((CAST(" + otherDateValue + " AS TIMESTAMP) - CAST(" + dateValue + " AS TIMESTAMP))/365.25)";
	}

	@Override
	public String doHourDifferenceTransform(String dateValue, String otherDateValue) {
		return "ROUND((CAST(" + otherDateValue + " AS TIMESTAMP) - CAST(" + dateValue + " AS TIMESTAMP))*24)";
	}

	@Override
	public String doMinuteDifferenceTransform(String dateValue, String otherDateValue) {
		return "ROUND((CAST(" + otherDateValue + " AS TIMESTAMP) - CAST(" + dateValue + " AS TIMESTAMP))*24*60)";
	}

	@Override
	public String doSecondDifferenceTransform(String dateValue, String otherDateValue) {
		return "ROUND((CAST(" + otherDateValue + " AS TIMESTAMP) - CAST(" + dateValue + " AS TIMESTAMP))*24*60*60)";
	}

	@Override
	public String doDayOfWeekTransform(String dateSQL) {
		return " DAYOFWEEK(" + dateSQL + ")";
	}

	@Override
	public boolean supportsArraysNatively() {
		return false;
	}

	@Override
	public String doNumberEqualsTransform(String leftHandSide, String rightHandSide) {
		return "((" + super.doNumberEqualsTransform(leftHandSide, rightHandSide) + ")=true)";
	}

}


text:
import Ember from 'ember';
import Permissions from 'ember-osf/const/permissions';
import Analytics from '../mixins/analytics';
import {stripDiacritics} from 'ember-power-select/utils/group-utils';
/**
 * @module ember-preprints
 * @submodule components
 */

/**
 * Preprint form project select widget - handles all ADD mode cases where the first step is to select an existing OSF project to contain
 * your preprint.  Also used in EDIT mode - as we keep the project locked after preprint has been published.  Therefore, you must use an existing project!
 *
 *  Uses the file-uploader component, hence the large number of properties for this component, that are passed along to the file-uploader.
 *  Cases not needing the file-uploader are where you are selecting an existing file on an existing node, or copying a file into
 *  a newly-created component - no file uploading needed.
 *
 * {{preprint-form-project-select
 * ```handlebars
 *      changeInitialState=(action 'changeInitialState')
 *      finishUpload=(action 'finishUpload')
 *     clearDownstreamFields=(action 'clearDownstreamFields')
 *     nextUploadSection=(action 'nextUploadSection')
 *     existingNodeExistingFile=(action 'existingNodeExistingFile')
 *     createComponentCopyFile=(action "createComponentCopyFile")
 *     selectFile=(action "selectExistingFile")
 *     highlightSuccessOrFailure=(action 'highlightSuccessOrFailure')
 *     startPreprint=(action 'startPreprint')
 *     discardUploadChanges=(action 'discardUploadChanges')
 *     startState=_State.START
 *     existingState=existingState
 *     _existingState=_existingState
 *     nodeTitle=nodeTitle
 *     currentUser=user
 *     selectedFile=selectedFile
 *     hasFile=hasFile
 *     file=file
 *     node=node
 *     userNodes=userNodes
 *     selectedNode=node
 *     contributors=contributors
 *     fileSelect=true
 *     currentState=filePickerState
 *     parentNode=parentNode
 *     convertProjectConfirmed=convertProjectConfirmed
 *     userNodesLoaded=userNodesLoaded
 *     convertOrCopy=convertOrCopy
 *     isTopLevelNode=isTopLevelNode
 *     nodeLocked=nodeLocked
 *     osfStorageProvider=osfStorageProvider
 *     osfProviderLoaded=osfProviderLoaded
 *     titleValid=titleValid
 *     uploadChanged=uploadChanged
 *     uploadInProgress=uploadInProgress
 *     abandonedPreprint=abandonedPreprint
 *     resumeAbandonedPreprint=(action 'resumeAbandonedPreprint')
 *     basicsAbstract=basicsAbstract
 *     editMode=editMode
 *     newNode=newNode
 *     applyLicense=applyLicense
 * }}
 * @class preprint-form-project-select
 */
export default Ember.Component.extend(Analytics, {
    userNodes: Ember.A(),
    selectedNode: null,
    isAdmin: Ember.computed('selectedNode', function() {
        return this.get('selectedNode') ? (this.get('selectedNode.currentUserPermissions') || []).includes(Permissions.ADMIN) : false;
    }),
    actions: {
        nodeSelected(node) {
            // Sets selectedNode, then loads node's osfstorage provider. Once osfProviderLoaded, file-browser component can be loaded.
            this.attrs.clearDownstreamFields('belowNode');
            this.set('selectedNode', node);
            this.set('osfProviderLoaded', false);
            this.send('changeExistingState', this.get('_existingState').CHOOSE);
            this.get('selectedNode.files').then((files) => {
                this.set('osfStorageProvider', files.findBy('name', 'osfstorage'));
                this.set('osfProviderLoaded', true);
            });
            this.attrs.nextUploadSection('chooseProject', 'chooseFile');
            Ember.get(this, 'metrics')
                .trackEvent({
                    category: 'dropdown',
                    action: 'select',
                    label: 'Preprints - Submit - Choose Project'
                });

        },
        selectFile(file) {
            // Select existing file from file-browser
            this.attrs.clearDownstreamFields('belowFile');
            this.attrs.selectFile(file);
            this.attrs.nextUploadSection('selectExistingFile', 'organize');
            Ember.get(this, 'metrics')
                .trackEvent({
                    category: 'file browser',
                    action: 'select',
                    label: 'Preprints - Submit - Existing File Selected'
                });
        },
        changeExistingState(newState) {
            // Toggles existingState between 'existing' or 'new', meaning user wants to select existing file from file browser
            // or upload a new file.
            this.attrs.clearDownstreamFields('belowNode');
            this.set('existingState', newState);
            if (newState === this.get('_existingState').EXISTINGFILE) {
                this.attrs.nextUploadSection('chooseFile', 'selectExistingFile');
                Ember.get(this, 'metrics')
                    .trackEvent({
                        category: 'button',
                        action: 'click',
                        label: 'Preprints - Submit - Choose Select Existing File as Preprint'
                    });

            } else if (newState === this.get('_existingState').NEWFILE) {
                this.attrs.nextUploadSection('chooseFile', 'uploadNewFile');
                Ember.get(this, 'metrics')
                    .trackEvent({
                        category: 'button',
                        action: 'click',
                        label: 'Preprints - Submit - Choose Upload Preprint'
                    });
            }
        },
    },

    /**
     * Whether to show the file selection dropdown box
     * @property {boolean} fileSelect
     */
    fileSelect: false,

    titleMatcher(node, term) {
        // Passed into power-select component for customized searching.
        // Returns results if match in node, root, or parent title
        const fields = [
            'title',
            'root.title',
            'parent.title'
        ];

        const sanitizedTerm = stripDiacritics(term).toLowerCase();

        for (const field of fields) {
            const fieldValue = node.get(field) || '';

            if (!fieldValue) continue;

            const sanitizedValue = stripDiacritics(fieldValue).toLowerCase();

            if (sanitizedValue.includes(sanitizedTerm)) {
                return 1;
            }
        }
        return -1;
    }
});


text:
module LitmosClient
  module Users
    def users(params={})
      get(:users, params)
    end

    def find_user_by_id(id)
      get("users/#{id}")
    rescue NotFound
      nil
    end

    def create_user(options={})
      raise ArgumentError.new(":username is required") if options[:username].blank?
      raise ArgumentError.new(":first_name is required") if options[:first_name].blank?
      raise ArgumentError.new(":last_name is required") if options[:last_name].blank?
      raise ArgumentError.new(":email is required") if options[:email].blank?

      params = {
        'UserName' => options[:username],
        'FirstName' => options[:first_name],
        'LastName' => options[:last_name],
        'Email' => options[:email],
        'DisableMessages' => true,
        'IsCustomUsername' => true,
        'SkipFirstLogin' => true
      }

      post("users", params)
    end

    def delete_user(id)
      delete "users/#{id}"
    end

    def update_user(id, options={})
      put("users/#{id}", params)
    end
  end
end


text:
uhome="/user/cloudland/warehouse"
hname="/usr/hdp/2.3.2.0-2950/hadoop"
tables_list_path="/letv/cloudland/app_jobs/rsync-hdfs"
destination="hdfs://centos10-10.letv.cn:8020/user/cloudland/warehouse"
origin="hftp://10.149.10.99:50070/user/hive/warehouse"

getArray() {
    local i=0
    array=() # Clear array
    while IFS= read -r line # Read a line
    do
        array+=( "$line" ) # Append line to the array
    done < "$1"
}

# check parameters:
if (("$#" != 3))
then
  echo "$(date) error: Schema and start, end range must be assigned. And the start must be less then the end."
  echo "Usage: ./<schema> start end"
  exit 1
fi

schema=$1
start=$2
end=$3

for ((i=${start}; i<=${end}; i++))
do
	current=$(date +%Y%m%d -d -${i}day)
	#rsync schema dwd of data
	getArray "/letv/cloudland/app_jobs/rsync-hdfs/hdfs-addition/added-tables-list.txt"
	for tname in "${array[@]}"
	do
	    echo "===== [$tname] start loading ..."
	    ${hname}/bin/hadoop distcp -update -skipcrccheck ${origin}/${schema}.db/${tname}/dt=${current}/ $uhome/phone/datamarts/${schema}.db/${tname}/dt=${current}/

		echo "=====++++++++ [$tname] partition ${current} data start loading  ..."
        hql="LOAD DATA INPATH '${destination}/phone/datamarts/${schema}.db/${tname}/dt=${current}/*' INTO TABLE ${schema}.${tname} PARTITION (dt=${current});"
        echo $hql
        hive -e "$hql"
        echo "=====++++++++ [$tname] partition ${current} data loaded  ..."
	done
done


text:
package com.intellij.remoteServer.impl.module;

import com.intellij.openapi.Disposable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.remoteServer.configuration.RemoteServer;
import com.intellij.remoteServer.runtime.Deployment;
import com.intellij.remoteServer.runtime.ServerConnection;
import com.intellij.remoteServer.runtime.ServerConnector;
import com.intellij.remoteServer.runtime.deployment.ServerRuntimeInstance;
import com.intellij.remoteServer.util.*;
import com.intellij.util.concurrency.Semaphore;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicReference;

public abstract class CloudSourceApplicationConfigurable<
  SC extends CloudConfigurationBase,
  DC extends CloudDeploymentNameConfiguration,
  SR extends CloudMultiSourceServerRuntimeInstance<DC, ?, ?, ?>,
  AC extends CloudApplicationConfiguration> extends CloudApplicationConfigurable {

  private final Project myProject;
  private final Disposable myParentDisposable;

  private DelayedRunner myRunner;

  private RemoteServer<?> myAccount;

  public CloudSourceApplicationConfigurable(@Nullable Project project, Disposable parentDisposable) {
    myProject = project;
    myParentDisposable = parentDisposable;
  }

  @Override
  public void setAccount(RemoteServer<?> account) {
    myAccount = account;
    clearCloudData();
  }

  protected RemoteServer<SC> getAccount() {
    return (RemoteServer<SC>)myAccount;
  }

  @Override
  public JComponent getComponent() {
    JComponent result = getMainPanel();
    if (myRunner == null) {
      myRunner = new DelayedRunner(result) {

        private RemoteServer<?> myPreviousAccount;

        @Override
        protected boolean wasChanged() {
          boolean result = myPreviousAccount != myAccount;
          if (result) {
            myPreviousAccount = myAccount;
          }
          return result;
        }

        @Override
        protected void run() {
          loadCloudData();
        }
      };
      Disposer.register(myParentDisposable, myRunner);
    }
    return result;
  }

  protected void clearCloudData() {
    getExistingComboBox().removeAllItems();
  }

  protected void loadCloudData() {
    new ConnectionTask<Collection<Deployment>>("Loading existing applications list") {

      @Override
      protected void run(final ServerConnection<DC> connection,
                         final Semaphore semaphore,
                         final AtomicReference<Collection<Deployment>> result) {
        connection.connectIfNeeded(new ServerConnector.ConnectionCallback<DC>() {

          @Override
          public void connected(@NotNull ServerRuntimeInstance<DC> serverRuntimeInstance) {
            connection.computeDeployments(new Runnable() {

              @Override
              public void run() {
                result.set(connection.getDeployments());
                semaphore.up();
                UIUtil.invokeLaterIfNeeded(new Runnable() {
                  @Override
                  public void run() {
                    if (!Disposer.isDisposed(myParentDisposable)) {
                      setupExistingApplications(result.get());
                    }
                  }
                });
              }
            });
          }

          @Override
          public void errorOccurred(@NotNull String errorMessage) {
            runtimeErrorOccurred(errorMessage);
            semaphore.up();
          }
        });
      }

      @Override
      protected Collection<Deployment> run(SR serverRuntimeInstance) throws ServerRuntimeException {
        return null;
      }
    }.performAsync();
  }

  private void setupExistingApplications(Collection<Deployment> deployments) {
    JComboBox existingComboBox = getExistingComboBox();
    existingComboBox.removeAllItems();
    for (Deployment deployment : deployments) {
      existingComboBox.addItem(deployment.getName());
    }
  }

  protected Project getProject() {
    return myProject;
  }

  protected abstract JComboBox getExistingComboBox();

  protected abstract JComponent getMainPanel();

  @Override
  public abstract AC createConfiguration();

  protected abstract class ConnectionTask<T> extends CloudConnectionTask<T, SC, DC, SR> {

    public ConnectionTask(String title) {
      super(myProject, title, CloudSourceApplicationConfigurable.this.getAccount());
    }
  }
}


text:
using NSubstitute;
using Octokit.Reactive;
using System;
using System.Collections.Generic;
using Xunit;

namespace Octokit.Tests
{
    public class ObservableUserEmailsClientTests
    {
        private static ObservableUserEmailsClient CreateFixtureWithNonReactiveClient()
        {
            var nonreactiveClient = new UserEmailsClient(Substitute.For<IApiConnection>());
            var github = Substitute.For<IGitHubClient>();
            github.User.Email.Returns(nonreactiveClient);
            return new ObservableUserEmailsClient(github);
        }

        public class TheGetAllMethod
        {
            [Fact]
            public void GetsCorrectUrl()
            {
                var expectedUri = new Uri("user/emails", UriKind.Relative);
                var github = Substitute.For<IGitHubClient>();
                var client = new ObservableUserEmailsClient(github);

                client.GetAll();

                github.Connection.Received(1).GetResponse<List<EmailAddress>>(expectedUri);
            }
        }

        public class TheAddMethod
        {
            public IGitHubClient GitHubClient;

            public ObservableUserEmailsClient Client;

            [Fact]
            public void CallsAddOnClient()
            {
                var github = Substitute.For<IGitHubClient>();
                var client = new ObservableUserEmailsClient(github);
                string email = "octo@github.com";

                client.Add(email);

                github.User.Email.Received(1).Add(Arg.Is(email));
            }

            [Fact]
            public void EnsuresNonNullArguments()
            {
                var client = CreateFixtureWithNonReactiveClient();

                Assert.Throws<ArgumentNullException>(() => client.Add(null));
                Assert.Throws<ArgumentException>(() => client.Add("octo@github.com", null));
            }

            [Fact]
            public void EnsuresNonEmptyArguments()
            {
                var client = CreateFixtureWithNonReactiveClient();

                Assert.Throws<ArgumentException>(() => client.Add(""));
                Assert.Throws<ArgumentException>(() => client.Add("octo@github.com", ""));
            }
        }

        public class TheCtor
        {
            [Fact]
            public void EnsuresNonNullArguments()
            {
                Assert.Throws<ArgumentNullException>(
                    () => new ObservableUserEmailsClient(null));
            }
        }
    }
}


text:
* Primary Domain: [http://learn.jquery.com](http://learn.jquery.com)
* Staging Domain: [http://stage.learn.jquery.com](http://stage.learn.jquery.com)

## About

The goal of this site is twofold:

1. To serve as a central, trustworthy, narrative compendium of information about how to use jQuery and JavaScript.
2. To remain a timely, vibrant, and community-driven reference with a relatively low barrier to contribution.

Much of the initial content - and spirit - comes from [jQuery Fundamentals](https://github.com/rmurphey/jqfundamentals), an open-source book about jQuery, originally written by [Rebecca Murphey](http://www.rmurphey.com/) and released in 2010. In 2011, Rebecca [bequeathed the book](http://rmurphey.com/blog/2011/03/17/the-future-of-jquery-fundamentals-and-a-confession/) unto the jQuery Foundation to serve as the basis for this site.

## How This Site Works

This site's core content consists of [Markdown](http://daringfireball.net/projects/markdown/) files. The template that controls the site's appearance is a [child theme](https://github.com/jquery/jquery-wp-content/tree/master/themes/learn.jquery.com) of the jQuery [web base template](https://github.com/jquery/jquery-wp-content), and any issues with the presentation should be directed to [that repository](https://github.com/jquery/jquery-wp-content).

### Site Organization

All of the content lives inside of the subdirectories of the `page` directory. Each of these subdirectories is considered a **chapter**, and contains one or more **articles**, and there is also a top level file that corresponds to each chapter, which contains the chapter's human-readable title and an overview, which will appear on the chapter's landing page.

The [`order.yml`](https://github.com/jquery/learn.jquery.com/blob/master/order.yml) file controls the order that chapters and articles appear in the site.

### YAML Conventions

Each of the articles on the site has some [YAML "Front Matter"](https://github.com/mojombo/jekyll/wiki/YAML-Front-Matter) that contains metadata. All articles should include the following:

* title - the title of the article as it will appear in the site. if it contains special characters, put the string in quotes

`title: "jQuery Event Extensions"`

* level - the approximate level of jQuery experience required to find the article useful. Options: `beginner`, `intermediate`, or `advanced`

`level: advanced`

## Building && Working Locally

As this site is part of the jQuery network of sites, its presentation is controlled by our [web base template](https://github.com/jquery/jquery-wp-content). To preview the site locally, first follow the [instructions there](https://github.com/jquery/jquery-wp-content) to set up a local version of the jQuery WordPress network. Then, clone this repo and run the following steps (node.js required).

1. `npm install`
2. `cp config-sample.json config.json`
3. Edit config.json to use the username and password for your local WordPress network
4. `grunt`

*Windows note: Line endings need to be Unix-style (line-feed only). Make sure your text editor creates new files with Unix-style line endings. In addition, the following setting to your git config will keep the Unix-style line endings when pulling from the repository.*

```
$ git config --global core.autocrlf true
```

## How Can I Help?

We encourage contribution from anyone. For more comprehensive documentation on how to get involved, please read our [contributing guide](http://learn.jquery.com/contributing).


text:
<component name="ProjectDictionaryState">
  <dictionary name="eoin">
    <words>
      <w>okhttp</w>
    </words>
  </dictionary>
</component>


text:
namespace gpopt
{

	// fwd declarations
	class CTableDescriptor;
	class CName;
	class CColRefSet;

	//---------------------------------------------------------------------------
	//	@class:
	//		CLogicalGet
	//
	//	@doc:
	//		Basic table accessor
	//
	//---------------------------------------------------------------------------
	class CLogicalGet : public CLogical
	{

		private:

			// alias for table
			const CName *m_pnameAlias;

			// table descriptor
			CTableDescriptor *m_ptabdesc;

			// output columns
			DrgPcr *m_pdrgpcrOutput;

			// partition keys
			DrgDrgPcr *m_pdrgpdrgpcrPart;

			// distribution columns (empty for master only tables)
			CColRefSet *m_pcrsDist;

			void
			CreatePartCols(IMemoryPool *pmp, const DrgPul *pdrgpulPart);

			// private copy ctor
			CLogicalGet(const CLogicalGet &);

		public:

			// ctors
			explicit
			CLogicalGet(IMemoryPool *pmp);

			CLogicalGet
				(
				IMemoryPool *pmp,
				const CName *pnameAlias,
				CTableDescriptor *ptabdesc
				);

			CLogicalGet
				(
				IMemoryPool *pmp,
				const CName *pnameAlias,
				CTableDescriptor *ptabdesc,
				DrgPcr *pdrgpcrOutput
				);

			// dtor
			virtual
			~CLogicalGet();

			// ident accessors
			virtual
			EOperatorId Eopid() const
			{
				return EopLogicalGet;
			}

			// distribution columns
			virtual
			const CColRefSet *PcrsDist() const
			{
				return m_pcrsDist;
			}

			// return a string for operator name
			virtual
			const CHAR *SzId() const
			{
				return "CLogicalGet";
			}

			// accessors
			DrgPcr *PdrgpcrOutput() const
			{
				return m_pdrgpcrOutput;
			}

			// return table's name
			const CName &Name() const
			{
				return *m_pnameAlias;
			}

			// return table's descriptor
			CTableDescriptor *Ptabdesc() const
			{
				return m_ptabdesc;
			}

			// partition columns
			DrgDrgPcr *
			PdrgpdrgpcrPartColumns() const
			{
				return m_pdrgpdrgpcrPart;
			}

			// operator specific hash function
			virtual
			ULONG UlHash() const;

			// match function
			BOOL FMatch(COperator *pop) const;

			// sensitivity to order of inputs
			BOOL FInputOrderSensitive() const;

			// return a copy of the operator with remapped columns
			virtual
			COperator *PopCopyWithRemappedColumns(IMemoryPool *pmp, HMUlCr *phmulcr, BOOL fMustExist);

			//-------------------------------------------------------------------------------------
			// Derived Relational Properties
			//-------------------------------------------------------------------------------------

			// derive output columns
			virtual
			CColRefSet *PcrsDeriveOutput(IMemoryPool *pmp, CExpressionHandle &exprhdl);

			// derive not nullable output columns
			virtual
			CColRefSet *PcrsDeriveNotNull(IMemoryPool *pmp, CExpressionHandle &exprhdl) const;

			// derive partition consumer info
			virtual
			CPartInfo *PpartinfoDerive
				(
				IMemoryPool *pmp,
				CExpressionHandle & // exprhdl
				)
				const
			{
				return GPOS_NEW(pmp) CPartInfo(pmp);
			}

			// derive constraint property
			virtual
			CPropConstraint *PpcDeriveConstraint
				(
				IMemoryPool *pmp,
				CExpressionHandle & // exprhdl
				)
				const
			{
				return PpcDeriveConstraintFromTable(pmp, m_ptabdesc, m_pdrgpcrOutput);
			}

			// derive join depth
			virtual
			ULONG UlJoinDepth
				(
				IMemoryPool *, // pmp
				CExpressionHandle & // exprhdl
				)
				const
			{
				return 1;
			}

			//-------------------------------------------------------------------------------------
			// Required Relational Properties
			//-------------------------------------------------------------------------------------

			// compute required stat columns of the n-th child
			virtual
			CColRefSet *PcrsStat
				(
				IMemoryPool *, // pmp,
				CExpressionHandle &, // exprhdl
				CColRefSet *, // pcrsInput
				ULONG // ulChildIndex
				)
				const
			{
				GPOS_ASSERT(!"CLogicalGet has no children");
				return NULL;
			}

			//-------------------------------------------------------------------------------------
			// Transformations
			//-------------------------------------------------------------------------------------

			// candidate set of xforms
			virtual
			CXformSet *PxfsCandidates(IMemoryPool *pmp) const;

			// derive key collections
			virtual
			CKeyCollection *PkcDeriveKeys(IMemoryPool *pmp, CExpressionHandle &exprhdl) const;

			// derive statistics
			virtual
			IStatistics *PstatsDerive
						(
						IMemoryPool *pmp,
						CExpressionHandle &exprhdl,
						DrgPstat *pdrgpstatCtxt
						)
						const;

			// stat promise
			virtual
			EStatPromise Esp(CExpressionHandle &) const
			{
				return CLogical::EspHigh;
			}

			//-------------------------------------------------------------------------------------
			//-------------------------------------------------------------------------------------
			//-------------------------------------------------------------------------------------

			// conversion function
			static
			CLogicalGet *PopConvert
				(
				COperator *pop
				)
			{
				GPOS_ASSERT(NULL != pop);
				GPOS_ASSERT(EopLogicalGet == pop->Eopid() ||
							EopLogicalExternalGet == pop->Eopid());

				return dynamic_cast<CLogicalGet*>(pop);
			}

			// debug print
			virtual
			IOstream &OsPrint(IOstream &) const;

	}; // class CLogicalGet

}

#endif // !GPOPT_CLogicalGet_H

// EOF


text:
"""A sensor platform that give you information about the next space launch."""
from __future__ import annotations

from datetime import timedelta
import logging

from pylaunches import PyLaunches, PyLaunchesException
import voluptuous as vol

from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
from homeassistant.const import ATTR_ATTRIBUTION, CONF_NAME
from homeassistant.helpers.aiohttp_client import async_get_clientsession
import homeassistant.helpers.config_validation as cv

from .const import (
    ATTR_AGENCY,
    ATTR_AGENCY_COUNTRY_CODE,
    ATTR_LAUNCH_TIME,
    ATTR_STREAM,
    ATTRIBUTION,
    DEFAULT_NAME,
)

_LOGGER = logging.getLogger(__name__)

SCAN_INTERVAL = timedelta(hours=1)

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
    {vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string}
)

async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
    """Create the launch sensor."""
    name = config[CONF_NAME]
    session = async_get_clientsession(hass)
    launches = PyLaunches(session)

    async_add_entities([LaunchLibrarySensor(launches, name)], True)

class LaunchLibrarySensor(SensorEntity):
    """Representation of a launch_library Sensor."""

    _attr_icon = "mdi:rocket"

    def __init__(self, api: PyLaunches, name: str) -> None:
        """Initialize the sensor."""
        self.api = api
        self._attr_name = name

    async def async_update(self) -> None:
        """Get the latest data."""
        try:
            launches = await self.api.upcoming_launches()
        except PyLaunchesException as exception:
            _LOGGER.error("Error getting data, %s", exception)
            self._attr_available = False
        else:
            if next_launch := next((launch for launch in launches), None):
                self._attr_available = True
                self._attr_native_value = next_launch.name
                self._attr_extra_state_attributes = {
                    ATTR_LAUNCH_TIME: next_launch.net,
                    ATTR_AGENCY: next_launch.launch_service_provider.name,
                    ATTR_AGENCY_COUNTRY_CODE: next_launch.pad.location.country_code,
                    ATTR_STREAM: next_launch.webcast_live,
                    ATTR_ATTRIBUTION: ATTRIBUTION,
                }


text:
import { platformNativeScriptDynamic } from "nativescript-angular/platform";
import firebase = require("nativescript-plugin-firebase");
import { AppModule } from "./app.module";
import { UserService } from "./services/user.service";

firebase.init({
  onAuthStateChanged: (data: any) => {
    console.log(JSON.stringify(data));
    if (data.loggedIn) {
      UserService.userId = data.user.uid;
      // could also store data.user.email
    }
    else {
      UserService.userId = '';
    }
  }
}).then(
  function (instance) {
    console.log("firebase.init done");
  },
  function (error) {
    console.log("firebase.init error: " + error);
  }
);

const platform = platformNativeScriptDynamic();
platform.bootstrapModule(AppModule);


text:
<?php

declare(strict_types=1);
namespace Monad;

/**
 * Monad Interface Definition
 */
interface Monadic
{
    /**
     * Return value of Monad
     * Does not manipulate the value in any way
     *
     * @return mixed
     */
    public function value();

    /**
     * Return value of Monad as a base type.
     * If value === \Closure, will evaluate the function and return it's value
     * If value === \Monadic, will recurse
     *
     * @return mixed
     */
    public function flatten();

    /**
     * Bind monad with function.
     *
     * Function is in form f($value) {}
     *
     * You can pass additional parameters in the $args array in which case your
     * function should be in the form f($value, $arg1, ..., $argN) {}
     *
     * @param \Closure $function
     * @param array $args additional arguments to pass to function
     *
     * @return Monadic
     */
    public function bind(\Closure $function, array $args = []);

    /**
     * Static factory creator for the Monad
     *
     * @param mixed $value
     *
     * @return Monadic
     */
    public static function create($value);
}


text:
    Version 1.0.0

  Copyright © 2006-2015 handu.com All Rights Reserved


text:
package com.baidu.bjf.remoting.protobuf.descriptor;

import java.util.List;

import com.baidu.bjf.remoting.protobuf.FieldType;
import com.baidu.bjf.remoting.protobuf.annotation.Protobuf;
import com.google.protobuf.DescriptorProtos.MethodOptions;

/**
 * JProtobuf POJO supports for {@link MethodOptions}
 * @author xiemalin
 * @since 2.0.1
 */
public class MethodOptionsPOJO {

    @Protobuf(order = MethodOptions.DEPRECATED_FIELD_NUMBER)
    public Boolean deprecated;

    @Protobuf(order = MethodOptions.UNINTERPRETED_OPTION_FIELD_NUMBER, fieldType = FieldType.OBJECT)
    public List<UninterpretedOptionPOJO> uninterpretedOptions;
}


text: training project


text:
<?php
/**
 * Created by PhpStorm.
 * User: jmadueno
 * Date: 05/03/2015
 * Time: 16:45
 */

namespace RM\PlantillaBundle\Parsers;

use RM\ClienteBundle\Entity\Cliente;
use RM\ComunicacionBundle\Entity\Comunicacion;
use RM\ComunicacionBundle\Entity\Creatividad;
use RM\ComunicacionBundle\Entity\InstanciaComunicacion;
use RM\PlantillaBundle\DependencyInjection\GeneraPlantillaComunicacion;
use RM\PlantillaBundle\Entity\GrupoSlots;
use RM\PlantillaBundle\Entity\Slot;
use RM\PlantillaBundle\Model\Interfaces\GrupoSlotsInterface;
use RM\PlantillaBundle\Model\Interfaces\Parser\ParserInterface;
use RM\PlantillaBundle\Model\Interfaces\PlantillaInterface;
use RM\ProductoBundle\Entity\Producto;
use RM\ProductoBundle\Entity\Promocion;
use RM\RMMongoBundle\DependencyInjection\ManagerInstanciaComunicacionCliente;
use Symfony\Bridge\Twig\Extension\AssetExtension;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Component\Filesystem\Exception\FileNotFoundException;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Templating\Asset\PackageInterface;

class EmailParser implements ParserInterface
{

    /**
     * @var PlantillaInterface
     */
    private $plantilla;

    /**
     * @var Comunicacion
     */
    private $comunicacion;

    /**
     * @var InstanciaComunicacion
     */
    private $instancia;

    /**
     * @var Crawler
     */
    private $crawler;

    /**
     * @var GeneraPlantillaComunicacion
     */
    private $plantillaGenerator;

    /**
     * @var ManagerInstanciaComunicacionCliente
     */
    private $manager;

    /**
     * @var Cliente
     */
    private $cliente;

    /** @var  string */
    private $empresa;

    /**
     * @var PackageInterface
     */
    private $asset;

    public function __construct(
        GeneraPlantillaComunicacion $plantillaGenerator,
        ManagerInstanciaComunicacionCliente $manager,
        TokenStorageInterface $token,
        AssetExtension $asset
        )
    {
        $this->crawler  = new Crawler();
        $this->manager    = $manager;
        $this->plantillaGenerator = $plantillaGenerator;
        $this->empresa = $token->getToken()->getUser()->getCliente();
        $this->asset = $asset;

        $this->document = new \DOMDocument();

    }

    /**
     * @param InstanciaComunicacion $instancia
     * @param Cliente               $cliente
     *
     * @return $this|mixed
     */
    public function parse(InstanciaComunicacion $instancia, Cliente $cliente)
    {
        $comunicacion = $instancia
            ->getIdSegmentoComunicacion()
            ->getIdComunicacion();

        $this->setComunicacion($comunicacion);
        $this->setInstancia($instancia);

        $plantilla = $comunicacion->getPlantilla();
        $this->setPlantilla($plantilla);
        $this->setCliente($cliente);

        $this->document = new \DOMDocument();

        if(file_exists($this->getRutaPlantillaGenerada())){
            return $this;
        }

        if(!file_exists($this->getRutaPlantilla())) {
            $this->plantillaGenerator->creaArchivoPlantilla($this->plantilla);
        }

        $this->document->preserveWhiteSpace = false;
        $this->document->loadHTML(file_get_contents($this->getRutaPlantilla()));

        $this->document
            ->getElementById('inv')
            ->setAttribute('src',
                sprintf('http://localhost:8080/RM2/web/app_dev.php/tracking/aperture?centro=%s&instancia=%s',
                    $this->empresa,
                    $this->instancia->getIdInstancia()
                )
            );

        $this->fillPlantilla();

        $this->document->formatOutput = true;
        $this->document->saveHTMLFile($this->getRutaPlantillaGenerada());

        return $this;

    }

    /**
     * @throws \Exception
     */
    private function fillPlantilla()
    {
        $gruposSlots = $this->plantilla->getGruposSlots();

        /** @var GrupoSlots $grupo */
        foreach($gruposSlots as $grupo)
        {
            $slots = $grupo->getSlots();

            /** @var Slot $slot */
            foreach($slots as $slot)
            {
                $this->fillSlot($grupo, $slot);
            }
        }
    }

    /**
     * @param GrupoSlotsInterface $grupo
     * @param Slot $slot
     * @throws \Exception
     */
    private function fillSlot(GrupoSlotsInterface $grupo, Slot $slot)
    {
        $promocion = $this->getPromocion($this->cliente->getIdCliente(), $slot->getIdSlot());

        $tipo = $grupo->getTipo();
        switch($tipo)
        {
            case GrupoSlots::PROMOCION:
                $this->fillSlotPromocion($grupo, $slot, $promocion);
                break;
            case GrupoSlots::CREATIVIDADES:
                $this->fillSlotCreatividad($grupo, $slot, $promocion);
                break;
            default:
                throw new \Exception(sprintf(
                        'No existen GruposSlots de tipo "%s"',
                        $tipo
                    ));
        }
    }

    /**
     * @param GrupoSlotsInterface $grupo
     * @param Slot $slot
     * @param Promocion $promocion
     * @throws \Exception
     */
    private function fillSlotPromocion(GrupoSlotsInterface $grupo, Slot $slot, Promocion $promocion)
    {
        $id = $this->getId($grupo, $slot);

        if($grupo->getMImgProducto()) {
            $this->fillNodoImagenProducto($id, $promocion);
        }

        if($grupo->getMNombreProducto()) {
            $this->fillNodoNombreProducto($id, $promocion);
        }

        if($grupo->getMPrecio()) {
            $this->fillNodoPrecio($id, $promocion);
        }

        if($grupo->getMTexto()) {
            $this->fillNodoTexto($id, $promocion);
        }

        if($grupo->getMCondiciones()) {
            $this->fillNodoCondiciones($id, $promocion);
        }

        if($grupo->getMFidelizacion()) {
            $this->fillNodoFidelizacion($id, $promocion);
        }

        if($grupo->getMVoucher()) {
           $this->fillNodoVoucher($id, $promocion);
        }

        if($grupo->getMVolumen()) {
            $this->fillNodoVolumen($id, $promocion);
        }

    }

    /**
     * @param GrupoSlotsInterface $grupo
     * @param Slot $slot
     * @param Promocion $promocion
     * @throws \Exception
     */
    private function fillSlotCreatividad(GrupoSlotsInterface $grupo, Slot $slot, Promocion $promocion)
    {
        $id = $this->getId($grupo, $slot);

        if($grupo->getMImgProducto()) {
            $this->fillNodoImagenProducto($id, $promocion);
        }

        if($grupo->getMTexto()) {
            $this->fillNodoTexto($id, $promocion);
        }
    }

    /**
     * @param GrupoSlotsInterface $grupo
     * @param Slot $slot
     * @return string
     */
    private function getId(GrupoSlotsInterface $grupo, Slot $slot)
    {
        return sprintf("%s-%s", 'slot',$slot->getIdSlot());
    }

    /**
     * @param $id
     * @return \DOMElement
     * @throws \Exception
     */
    private function getElementById($id)
    {
        $element = $this->document->getElementById($id);
        if(!$element) {
            throw new \Exception(sprintf(
                    'No se ha encontrado el elemento con id = "%s"', $id
                ));
        }

        return $element;
    }

    /**
     * @param Cliente $cliente
     */
    private function setCliente(Cliente $cliente)
    {
        $this->cliente = $cliente;
    }

    /**
     * @param PlantillaInterface $plantilla
     * @return $this
     */
    public function setPlantilla(PlantillaInterface $plantilla)
    {
        $this->plantilla = $plantilla;
        return $this;
    }

    /**
     * @param Comunicacion $comunicacion
     *
     * @return $this
     */
    public function setComunicacion(Comunicacion $comunicacion)
    {
        $this->comunicacion = $comunicacion;
        return $this;
    }

    /**
     * @param InstanciaComunicacion $instancia
     */
    public function setInstancia(InstanciaComunicacion $instancia)
    {
        $this->instancia = $instancia;
    }

    /**
     * @return string
     * @throws FileNotFoundException
     */
    public function getEstilosPlantilla()
    {
        if(!file_exists($this->getRutaPlantilla())) {
            throw new FileNotFoundException("No se ha encontrado la plantilla maquetada");
        }

        $crawler = new Crawler(file_get_contents($this->getRutaPlantilla()));
        $estilos = $crawler->filter('head>style');

        return $estilos->html();
    }

    /**
     * @return string
     */
    private function getRutaPlantilla()
    {
        return $this->plantillaGenerator
            ->getRutaPlantilla($this->plantilla);
    }

    /**
     * @return string
     */
    public function getRutaPlantillaGenerada()
    {
        return $this->getRutaComunicacionGenerada(). '/'. $this->cliente->getIdCliente().'.html';
    }

    /**
     * @return string
     */
    private function getRutaComunicacionGenerada()
    {
        $ruta =  $this
                ->plantillaGenerator
                ->getRutaCarpetaComunicacionesGeneradas().'/' .
                $this->instancia->getIdInstancia() ;

        if(!file_exists($ruta)) {
            mkdir($ruta, 0777, true);
        }

        return $ruta;
    }

    /**
     * @param $cliente
     * @param $slot
     * @return \RM\ProductoBundle\Entity\Promocion
     * @throws \Exception
     */
    private function getPromocion($cliente, $slot)
    {
        $promocion =  $this->manager
            ->findPromocionBySlotyCliente(
                $slot,
                $cliente,
                $this->instancia->getIdInstancia()
            );

        return $promocion;
    }

    /**
     * @param $id
     * @param Promocion $promocion
     */
    private function fillNodoImagenProducto($id, Promocion $promocion)
    {
        $imagen = $this->getElementById(sprintf("%s-imagen", $id));

        $producto = $promocion->getIdProducto();

        if(!$producto) {
            $creatividad = $promocion->getCreatividad();
            $imagen->setAttribute('src', $this->getRutaCreatividad($creatividad));
            return;
        }

        $grupo = $promocion->getNumPromocion()->getIdGrupo();

        $dimensiones = [
            $grupo->getIdTamanyoSlot()->getAncho(),
            $grupo->getIdTamanyoSlot()->getAlto()
        ];

        //Hace falta inyectar assetic
        $imagen->setAttribute('src', $this->getRutaImagen($producto, $dimensiones));

    }

    /**
     * @param Producto $producto
     *
     * @return string
     */
    private function getRutaImagen(Producto $producto, $dimensiones = [])
    {
        if(!$producto->getImagen()) {
            if(count($dimensiones) == 2) {
                return  "http://placehold.it/$dimensiones[0]x$dimensiones[1]";
            } else {
                return  "http://placehold.it/300x150";
            }
        }

        $path = sprintf('%s/%s/%s', $this->empresa, 'imagenesProducto', $producto->getImagen());
        return $this->absoluteRouteImagenProducto($path);
    }

    /**
     * @param Creatividad $creatividad
     *
     * @return string
     */
    private function getRutaCreatividad(Creatividad $creatividad)
    {
        $path = sprintf('%s/%s/%s', $this->empresa, 'imagenesCreatividad', $creatividad->getImagen());
        return $this->absoluteRouteImagenProducto($path);
    }

    /**
     * @param           $id
     * @param Promocion $promocion
     *
     * @throws \Exception
     */
    private function fillNodoNombreProducto($id, Promocion $promocion)
    {
        $nodo = $this->getElementById(sprintf("%s-nombreProducto", $id));

        $nombre = $promocion->getIdProducto()->getNombre();
        $nodo->nodeValue = $nombre;
    }

    /**
     * @param $id
     * @param Promocion $promocion
     */
    private function fillNodoPrecio($id, Promocion $promocion)
    {
        $nodo = $this->getElementById(sprintf("%s-precio", $id));

        $precio = $promocion->getIdProducto()->getPrecioVenta();
        $nodo->nodeValue = sprintf("%.2F € ", $precio);
    }

    /**
     * @param $id
     * @param Promocion $promocion
     */
    private function fillNodoVolumen($id, Promocion $promocion)
    {
        $nodo = $this->getElementById(sprintf("%s-volumen", $id));

        $volumen = $promocion;
        $nodo->nodeValue = '';
    }

    /**
     * @param $id
     * @param Promocion $promocion
     */
    private function fillNodoVoucher($id, Promocion $promocion)
    {
        $nodo = $this->getElementById(sprintf("%s-voucher", $id));

        $voucher = (string) $promocion->getVoucher();
        $nodo->nodeValue = $voucher;
    }

    /**
     * @param $id
     * @param Promocion $promocion
     */
    private function fillNodoCondiciones($id, Promocion $promocion)
    {
        $nodo = $this->getElementById(sprintf("%s-condiciones", $id));
        $condiciones = (string) $promocion->getCondiciones();

        $nodo->nodeValue = $condiciones;
    }

    /**
     * @param $id
     * @param Promocion $promocion
     */
    private function fillNodoFidelizacion($id, Promocion $promocion)
    {
        $nodo =  $this->getElementById(sprintf("%s-fidelizacion", $id));

        $fidelizacion = $promocion->getFidelizacion();
        $nodo->nodeValue = $fidelizacion;
    }

    /**
     * @param $id
     * @param Promocion $promocion
     */
    private function fillNodoTexto( $id, Promocion $promocion)
    {
        $nodo = $this->getElementById(sprintf("%s-texto", $id));
        $texto = (string) $promocion->getDescripcion();

        $nodo->nodeValue = $texto;

    }

    /**
     * @param $path
     *
     * @return string
     */
    private function absoluteRouteImagenProducto($path)
    {
        try {
            return $this->asset->getAssetUrl($path, null, $absolute = false);
        } catch (\Exception $e) {
            return '';
        }

    }

}