text:
//
//  NetService.m
//  ky
//
//  Created by MacBook on 13-10-11.
//  Copyright (c) 2013年 pipi. All rights reserved.
//
#import "NetService.h"
#import "NSString+Encoding.h"
#import "NSData+Des.h"
#import "NSData+Base64.h"
#import "Reachability.h"
#import <AFNetworking/AFNetworking.h>
#import "AFDownloadRequestOperation.h"
#define DEFAULT_QUEUEID (@"defualt_queue_id")
@implementation NetServiceResponseInfo
@end
@implementation NetService{
    NSString* _rootUrl;
    NSString* _serviceUrl;
    NSString* _resourceRootUrl;

    Reachability* _hostReachability;
    NetServiceNetworkCheckBlock _networkCheck;
    NetworkStatus _currentState;

    NSHashTable* _networkCheckDelegates;
    NSMutableDictionary* _domains;

}

-(void)setRootUrl:(NSString *) rootUrl{
    _rootUrl=rootUrl;
    if(_resourceRootUrl==nil){
        _resourceRootUrl=rootUrl;
    }
}

-(void)setResourceRootUrl:(NSString *) rootUrl{
    _resourceRootUrl=rootUrl;
}

-(void)setServiceUrl:(NSString *) serviceUrl{
    _serviceUrl=serviceUrl;
}

+(NetService*)shareInstance{
    static NetService *instance=nil;
//    static dispatch_once_t onceToken;
//    dispatch_once(&onceToken, ^{
//        instance = [[self alloc] init];
//    });
    @synchronized(self) {
        if (instance == nil) {
            NSLog(@"share instance");
            instance=[[self alloc] init];
        }
    }
    return instance;
}
-(id)init {
    if (self = [super init]) {
        NSLog(@"NetService init");
        //init property
        _rootUrl=nil;
        _serviceUrl=nil;
        _defaultParse=[[NetServiceBaseParse alloc] init];
        _currentState=100;
        _networkCheckDelegates=[NSHashTable hashTableWithOptions:NSPointerFunctionsWeakMemory];
        _domains=[NSMutableDictionary dictionary];
        [self createDomain:DEFAULT_QUEUEID];
    }
    return self;
}

- (void)dealloc{
    _rootUrl=nil;
    _serviceUrl=nil;
}

-(void)setNetworkCheck:(NetServiceNetworkCheckBlock)networkCheck{
     _networkCheck=networkCheck;
    if(_hostReachability==nil){
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name:kReachabilityChangedNotification object:nil];
        _hostReachability = [Reachability reachabilityWithHostname:_rootUrl];
        [_hostReachability startNotifier];
    }
}
-(void)addNetworkCheck:(id<NetServiceReceiveDataDelegate>)checkDelegate{
    [_networkCheckDelegates addObject:checkDelegate];
}

/*!
 * Called by Reachability whenever status changes.
 */
- (void) reachabilityChanged:(NSNotification *)note
{
    Reachability* curReach = [note object];
	NSParameterAssert([curReach isKindOfClass:[Reachability class]]);
	[self updateInterfaceWithReachability:curReach];
}

- (void)updateInterfaceWithReachability:(Reachability *)reachability
{
    NetworkStatus _newState=[reachability currentReachabilityStatus];
    NetServiceNetworkSwitchStatus switchState=NetServiceNetworkSwitchStatusNone;
    if(_currentState==NotReachable&& _newState!=NotReachable){
        switchState=NetServiceNetworkSwitchStatusYes;
    }else if(_currentState!=NotReachable&& _newState==NotReachable){
        switchState=NetServiceNetworkSwitchStatusNo;
    }
    _networkCheck(switchState,_newState);
    for(id<NetServiceReceiveDataDelegate> delegate in _networkCheckDelegates){
        if([delegate respondsToSelector:@selector(reachabilityChanged:networkStatus:)]){
            [delegate reachabilityChanged:switchState networkStatus:_newState];
        }
    }
    _currentState=_newState;
    /*
    int64_t delayInSeconds = 2.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){

    });*/
}

-(void) sendData:(NSString*)serviceName delegate:(id<NetServiceReceiveDataDelegate>)delegate data:(id)data parse:(id<NetServiceParseDelegate>)parse {
    if(data==nil){
        [self sendData:serviceName delegate:delegate parse:parse];
        return;
    }
    //    NSLog(@"---------------------");
    //    NSLog(@"%@%@%@",_rootUrl,_serviceUrl,serviceName);
    //    NSLog(@"---------------------");
    if(parse==nil){
        parse=_defaultParse;
    }
    NSError *error;
    NSData *byteData = [parse encode:data error:&error];
    if(error!=nil){
        NSLog(@"sendData parse error:%@", [error localizedDescription]);
        return;
    }
    NSString *dataStr=[byteData base64EncodedString];
    NSString *furl=[[NSString alloc] initWithFormat:@"%@%@%@",_rootUrl,_serviceUrl,serviceName];

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    manager.responseSerializer=[AFHTTPResponseSerializer serializer];
    manager.requestSerializer=[AFHTTPRequestSerializer serializer];
    NSDictionary *parameters = @{@"data": dataStr};
    [manager POST:furl parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSError *error;
        NSData* responseData= [NSData dataFromBase64String:operation.responseString];
        id data = [parse decode:responseData error:&error];
        if([delegate respondsToSelector:@selector(receiveData:data:responseStatus:)]){
            if(error){
                [delegate receiveData:serviceName data:data responseStatus:NetServiceResponseStatusParseFail];
            }else{
                [delegate receiveData:serviceName data:data responseStatus:NetServiceResponseStatusSuccess];
            }
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"request receive data fail %@",error);
        if([delegate respondsToSelector:@selector(receiveData:data:responseStatus:)]){
            [delegate receiveData:serviceName data:nil responseStatus:NetServiceResponseStatusFail];
        }
    }];
}
-(void) sendData:(NSString*)serviceName delegate:(id<NetServiceReceiveDataDelegate>)delegate parse:(id<NetServiceParseDelegate>)parse{
    if(parse==nil){
        parse=_defaultParse;
    }
    NSString *furl=[[NSString alloc] initWithFormat:@"%@%@%@",_rootUrl,_serviceUrl,serviceName];
//    NSLog(@"---------------------");
//    NSLog(@"%@%@%@",_rootUrl,_serviceUrl,serviceName);
//    NSLog(@"---------------------");
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    manager.responseSerializer=[AFHTTPResponseSerializer serializer];
    manager.requestSerializer=[AFHTTPRequestSerializer serializer];
    [manager GET:furl parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSError *error;
        NSData* responseData= [NSData dataFromBase64String:operation.responseString];
        id data = [parse decode:responseData error:&error];
        if([delegate respondsToSelector:@selector(receiveData:data:responseStatus:)]){
            if(error){
                [delegate receiveData:serviceName data:data responseStatus:NetServiceResponseStatusParseFail];
            }else{
                [delegate receiveData:serviceName data:data responseStatus:NetServiceResponseStatusSuccess];
            }
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"request receive data fail %@",error);
        if([delegate respondsToSelector:@selector(receiveData:data:responseStatus:)]){
            [delegate receiveData:serviceName data:nil responseStatus:NetServiceResponseStatusFail];
        }
    }];
}

-(void) sendData:(NSString*)serviceName delegate:(id<NetServiceReceiveDataDelegate>)delegate data:(id)data uploadFileDatas:(NSArray*)uploadFileDatas parse:(id<NetServiceParseDelegate>)parse{
    NSString *furl=[[NSString alloc] initWithFormat:@"%@%@%@",_rootUrl,_serviceUrl,serviceName];
//    NSLog(@"---------------------");
//    NSLog(@"%@%@%@",_rootUrl,_serviceUrl,serviceName);
//    NSLog(@"---------------------");
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    manager.responseSerializer=[AFHTTPResponseSerializer serializer];
    manager.requestSerializer=[AFHTTPRequestSerializer serializer];
    NSDictionary *parameters=nil;
    if(data!=nil){
        NSError *error;
        NSData *byteData =[parse encode:data error:&error];
        if(error!=nil){
            NSLog(@"parse error:%@", [error localizedDescription]);
            return;
        }
        NSString *dataStr=[byteData base64EncodedString];
        parameters = @{@"data": dataStr};
    }
    [manager POST:furl parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        for(NSInteger i=0;i<uploadFileDatas.count;i++){
            NSDictionary *rowData=uploadFileDatas[i];
            NSString* refUrl=rowData[UIImagePickerControllerReferenceURL];
            refUrl=[[NSString alloc] initWithFormat:@"%@",refUrl];
            NSArray* refUrlCompoment=[refUrl componentsSeparatedByString:@"ext="];
            NSString* type=@"png";
            if(refUrlCompoment.count==2){
                type=[refUrlCompoment[1] lowercaseString];
            }
            NSString* name=[NSString stringWithFormat:@"file%li",(long)i];
            NSString* filename=[NSString stringWithFormat:@"%@.%@",name,type];
            NSString* contentType=[NSString stringWithFormat:@"%@%@",@"image/",type];
            UIImage* image=rowData[UIImagePickerControllerOriginalImage];
            NSData* imageData;
            if([type isEqualToString:@"jpg"]){
                imageData = UIImageJPEGRepresentation(image, 1.0);
            }else{
                imageData = UIImagePNGRepresentation(image);
            }
            [formData appendPartWithFileData:imageData name:name fileName:filename mimeType:contentType];
        }
    } success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSError *error;
         NSData* responseData= [NSData dataFromBase64String:operation.responseString];
        id data = [parse decode:responseData error:&error];
        if([delegate respondsToSelector:@selector(receiveData:data:responseStatus:)]){
            if(error){
                [delegate receiveData:serviceName data:data responseStatus:NetServiceResponseStatusParseFail];
            }else{
                [delegate receiveData:serviceName data:data responseStatus:NetServiceResponseStatusSuccess];
            }
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"request receive data fail %@",error);
        if([delegate respondsToSelector:@selector(receiveData:data:responseStatus:)]){
            [delegate receiveData:serviceName data:nil responseStatus:NetServiceResponseStatusFail];
        }
    }];
}

-(void) sendData:(NSString*)serviceName completionBlock:(NetServiceSendDataCompleteBlock)completionBlock parse:(id<NetServiceParseDelegate>)parse
{
    if(parse==nil){
        parse=_defaultParse;
    }
    NSString *furl=[[NSString alloc] initWithFormat:@"%@%@%@",_rootUrl,_serviceUrl,serviceName];
//    NSLog(@"---------------------");
//    NSLog(@"%@%@%@",_rootUrl,_serviceUrl,serviceName);
//    NSLog(@"---------------------");
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    manager.responseSerializer=[AFHTTPResponseSerializer serializer];
    manager.requestSerializer=[AFHTTPRequestSerializer serializer];
    [manager GET:furl parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSError *error;
        NSData* responseData= [NSData dataFromBase64String:operation.responseString];
        id data =[parse decode:responseData error:&error];
        NetServiceResponseInfo* responseInfo=[[NetServiceResponseInfo alloc] init];
        if(error){
            completionBlock(data,NetServiceResponseStatusParseFail,responseInfo);
        }else{
            completionBlock(data,NetServiceResponseStatusSuccess,responseInfo);
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"request receive data fail %@",error);
        completionBlock(nil,NetServiceResponseStatusFail,nil);
    }];
}

-(void) sendData:(NSString*)serviceName data:(id)data completionBlock:(NetServiceSendDataCompleteBlock)completionBlock parse:(id<NetServiceParseDelegate>)parse{
    if(data==nil){
        [self sendData:serviceName completionBlock:completionBlock parse:parse];
        return;
    }
    //    NSLog(@"---------------------");
    //    NSLog(@"%@%@%@",_rootUrl,_serviceUrl,serviceName);
    //    NSLog(@"---------------------");
    if(parse==nil){
        parse=_defaultParse;
    }
    NSError *error;
    NSData *byteData =[parse encode:data error:&error];
    if(error!=nil){
        NSLog(@"parse format error:%@", [error localizedDescription]);
        return;
    }
    NSString *dataStr=[byteData base64EncodedString];
    NSString *furl=[[NSString alloc] initWithFormat:@"%@%@%@",_rootUrl,_serviceUrl,serviceName];
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    manager.responseSerializer=[AFHTTPResponseSerializer serializer];
    manager.requestSerializer=[AFHTTPRequestSerializer serializer];
    NSDictionary *parameters = @{@"data": dataStr};
    [manager POST:furl parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSError *error;
        NSData* responseData= [NSData dataFromBase64String:operation.responseString];
        id data =[parse decode:responseData error:&error];
        NetServiceResponseInfo* responseInfo=[[NetServiceResponseInfo alloc] init];
        if(error){
            completionBlock(data,NetServiceResponseStatusParseFail,responseInfo);
        }else{
            completionBlock(data,NetServiceResponseStatusSuccess,responseInfo);
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"request receive data fail %@",error);
        completionBlock(nil,NetServiceResponseStatusFail,nil);
    }];
}

-(void) sendData:(NSString*)serviceName data:(id)data  uploadFileDatas:(NSArray*)uploadFileDatas completionBlock:(NetServiceSendDataCompleteBlock)completionBlock parse:(id<NetServiceParseDelegate>)parse{
    if(parse==nil){
        parse=_defaultParse;
    }
    NSString *furl=[[NSString alloc] initWithFormat:@"%@%@%@",_rootUrl,_serviceUrl,serviceName];
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    manager.responseSerializer=[AFHTTPResponseSerializer serializer];
    manager.requestSerializer=[AFHTTPRequestSerializer serializer];
    NSDictionary *parameters=nil;
    if(data!=nil){
        NSError *error;
        NSData *byteData =[parse encode:data error:&error];
        if(error!=nil){
            NSLog(@"parse error:%@", [error localizedDescription]);
            return;
        }
        NSString *dataStr=[byteData base64EncodedString];
        parameters = @{@"data": dataStr};
    }
    [manager POST:furl parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        for(NSInteger i=0;i<uploadFileDatas.count;i++){
            NSDictionary *rowData=uploadFileDatas[i];
            NSString* refUrl=rowData[UIImagePickerControllerReferenceURL];
            refUrl=[[NSString alloc] initWithFormat:@"%@",refUrl];
            NSArray* refUrlCompoment=[refUrl componentsSeparatedByString:@"ext="];
            NSString* type=@"png";
            if(refUrlCompoment.count==2){
                type=[refUrlCompoment[1] lowercaseString];
            }
            NSString* name=[NSString stringWithFormat:@"file%li",(long)i];
            NSString* filename=[NSString stringWithFormat:@"%@.%@",name,type];
            NSString* contentType=[NSString stringWithFormat:@"%@%@",@"image/",type];
            UIImage* image=rowData[UIImagePickerControllerOriginalImage];
            NSData* imageData;
            if([type isEqualToString:@"jpg"]){
                imageData = UIImageJPEGRepresentation(image, 1.0);
            }else{
                imageData = UIImagePNGRepresentation(image);
            }
            [formData appendPartWithFileData:imageData name:name fileName:filename mimeType:contentType];
        }
    } success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSError *error;
        NSData* responseData= [NSData dataFromBase64String:operation.responseString];
        id data = [parse decode:responseData error:&error];
        NetServiceResponseInfo* responseInfo=[[NetServiceResponseInfo alloc] init];
        if(error){
            completionBlock(data,NetServiceResponseStatusParseFail,responseInfo);
        }else{
            completionBlock(data,NetServiceResponseStatusSuccess,responseInfo);
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"request receive data fail %@",error);
        completionBlock(nil,NetServiceResponseStatusFail,nil);
    }];
}

-(NetServiceDamain*)createDomain:(NSString*)domainid{
    NetServiceDamain* _domain;
    if(_domains[domainid]){
        _domain=_domains[domainid];
        [_domain cancelAllOperations];
    }
    _domain=[[NetServiceDamain alloc] init];
    [_domain setMaxConcurrentOperationCount:1];
    [_domain setStoragePath:@"download"];
    _domains[domainid]=_domain;
    return _domain;
}

-(void)removeDomain:(NSString*)domainid{
    if(domainid==nil){
        domainid=DEFAULT_QUEUEID;
    }
    if(_domains[domainid]){
        NetServiceDamain* _networkQueue=_domains[domainid];
        [_networkQueue cancelAllOperations];
        if(![domainid isEqualToString:DEFAULT_QUEUEID]){
            [_domains removeObjectForKey:domainid];
        }
    }
}
-(NetServiceDamain*)getDomain:(NSString*)domainid{
    if(domainid==nil){
        domainid=DEFAULT_QUEUEID;
    }
    return _domains[domainid];
}

-(void)cacelDomainLoading:(NSString*)domainid{
    if(domainid==nil){
        domainid=DEFAULT_QUEUEID;
    }
    if(_domains[domainid]){
        NetServiceDamain* _networkQueue=_domains[domainid];
        [_networkQueue cancelAllOperations];
    }
}

-(void)networkQueueCompleteAction:(id)sender{

}

-(void)requestDidStartAction:(id)sender{
  //  ASIHTTPRequest* _request=sender;
    //NSLog(@"requestDidStartAction:%@",_request.url);
}

-(void)requestDidFinishAction:(id)sender{
   // ASIHTTPRequest* _request=sender;
    //NSLog(@"requestDidFinishAction:%@",_request.url);
}

-(void)requestDidFailAction:(id)sender{
  //  ASIHTTPRequest* _request=sender;
    //NSLog(@"requestDidFailAction:%@",_request.url);
}

- (void) loadImage:(NSString*)relaviteUrl complete:(NetServiceLoadImageCompleteBlock)completeBlock{
    [self loadImage:relaviteUrl complete:completeBlock domainid:DEFAULT_QUEUEID];
}
- (void) loadImage:(NSString*)relaviteUrl complete:(NetServiceLoadImageCompleteBlock)completeBlock domainid:(NSString *)domainid{
    NSString* imageURL;
    if([[relaviteUrl substringToIndex:1] isEqualToString:@"/"] ||[[relaviteUrl substringToIndex:6] isEqualToString:@"upload"]){
        imageURL=[[NSString alloc] initWithFormat:@"%@%@",_resourceRootUrl,relaviteUrl];
    }else{
        imageURL=relaviteUrl;
    }
//    NSLog(@"---------------------");
//    NSLog(@"loadImage%@",imageURL);
//    NSLog(@"---------------------");
    NetServiceDamain* domain=_domains[domainid];
    if(domain==nil){
        domain=_domains[DEFAULT_QUEUEID];
    }
    NSURL *URL = [NSURL URLWithString:imageURL];
    NSURLRequest *request = [NSURLRequest requestWithURL:URL];
    AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    op.responseSerializer = [AFImageResponseSerializer serializer];
    [op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        UIImage* image=responseObject;
        @try {
            completeBlock(image);
        }
        @catch (NSException *exception) {
            NSLog(@"*****************load image fail,message:%@",exception.name);
        }
        @finally {
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"************************async image download failed");
    }];
    [domain addOperation:op];
}

//data
- (void) loadData:(NSString*)relaviteUrl complete:(NetServiceSendDataCompleteBlock)completeBlock parse:(id<NetServiceParseDelegate>)parse{
    [self loadData:relaviteUrl complete:completeBlock parse:parse domainid:DEFAULT_QUEUEID];
}
- (void) loadData:(NSString*)relaviteUrl complete:(NetServiceSendDataCompleteBlock)completeBlock  parse:(id<NetServiceParseDelegate>)parse domainid:(NSString *)domainid{
    NSString* url;
    if([[relaviteUrl substringToIndex:1] isEqualToString:@"/"] ||[[relaviteUrl substringToIndex:6] isEqualToString:@"upload"]){
        url=[[NSString alloc] initWithFormat:@"%@%@",_resourceRootUrl,relaviteUrl];
    }else{
        url=relaviteUrl;
    }
    if(parse==nil){
        parse=_defaultParse;
    }
    NetServiceDamain* domain=_domains[domainid];
    if(domain==nil){
        domain=_domains[DEFAULT_QUEUEID];
    }
    NSURL *URL = [NSURL URLWithString:url];
    /*
    NSData* storageData=[domain.storage getStorageData:URL];
    if(storageData){
        NSError* error;
        id idata=[parse decode:storageData error:&error];
        NetServiceResponseInfo* responseInfo=[[NetServiceResponseInfo alloc] init];
        responseInfo.url=URL;
        responseInfo.cache=true;
        if(error){
            completeBlock(nil,NetServiceResponseStatusParseFail,responseInfo);
        }else{
            completeBlock(idata,NetServiceResponseStatusSuccess,responseInfo);
        }
    }else{
     */
        NSURLRequest *request = [NSURLRequest requestWithURL:URL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60];
        AFHTTPRequestOperation* op=[[AFHTTPRequestOperation alloc] initWithRequest:request];
        op.responseSerializer = [AFHTTPResponseSerializer serializer];
        [op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject){
            NSData* data=responseObject;
            NSError* error;
            id idata=[parse decode:data error:&error];
            NetServiceResponseInfo* responseInfo=[[NetServiceResponseInfo alloc] init];
            responseInfo.cache=false;
            responseInfo.url=operation.request.URL;
            if(error){
                completeBlock(nil,NetServiceResponseStatusParseFail,responseInfo);
            }else{
                //[domain.storage saveStorageData:storageData url:URL];
                completeBlock(idata,NetServiceResponseStatusSuccess,responseInfo);
            }
        } failure:^(AFHTTPRequestOperation *operation, NSError *error){
            NSLog(@"************************async image download failed%@",error.description);
            completeBlock(nil,NetServiceResponseStatusFail,nil);
        }];
        [domain addOperation:op];
   // }
}

@end
@implementation NetServiceDamain
- (instancetype)init
{
    self = [super init];
    if (self) {

    }
    return self;
}
-(void)setStoragePath:(NSString *)storagePath{
    _storage=[[AFDownloadStorage alloc] initWithStoragePath:storagePath];
}

-(void)clearStoragePath{
    [_storage clear];
}

@end

@implementation NetServiceJsonParse

-(id)decode:(NSData*)data error:(NSError**)error{
    id jsonObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:error];
    return jsonObject;
}
-(NSData*)encode:(id)data error:(NSError**)error{
     NSData *byteData = [NSJSONSerialization dataWithJSONObject:data options:NSJSONWritingPrettyPrinted error:error];
    return byteData;
}

@end
@implementation NetServiceBaseParse
-(id)decode:(NSData*)data error:(NSError**)error{
    return data;
}
-(NSData*)encode:(id)data error:(NSError**)error{
    return data;
}
@end
@implementation NetServiceDesJsonParse
- (instancetype)init
{
    self = [super init];
    if (self) {
        _readingOptions=NSJSONReadingAllowFragments;
    }
    return self;
}
-(id)decode:(NSData*)data error:(NSError**)error{
    data=[data desDecoded];
    if(data==nil){
        NSString *description = @"des data after is nil";
        NSString *recoverySuggestion = @"please check data exception";
        NSInteger errorCode = -1;
        NSArray *keys = [NSArray arrayWithObjects: NSLocalizedDescriptionKey, NSLocalizedRecoverySuggestionErrorKey, nil];
        NSArray *values = [NSArray arrayWithObjects:description, recoverySuggestion, nil];
        NSDictionary *userDict = [NSDictionary dictionaryWithObjects:values forKeys:keys];
        if(error){
            *error=[[NSError alloc] initWithDomain:@"data domain" code:errorCode userInfo:userDict];
        }
        return nil;
    }
     NSError* err;
    id jsonObject = [NSJSONSerialization JSONObjectWithData:data options:_readingOptions error:&err];
    if(err){
        *error=err;
        return nil;
    }
    return jsonObject;
}

-(NSData*)encode:(id)data error:(NSError**)error{
    NSError* err;
    NSData *byteData = [NSJSONSerialization dataWithJSONObject:data options:NSJSONWritingPrettyPrinted error:&err];
    if(err){
        *error=err;
        return nil;
    }
    byteData=[byteData desEncoded];

    return byteData;
}

@end


text:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;

/*
Descrizione della classe "GeneraPercorso" nel Gdd

Questo script viene attaccato a un gameobject ,"GeneraPercorso", nella hierarchy e al suo interno
vengono messi dei gameobject vuoti che corrispondono a punti posizione nella scena .
L'ordine di sequenza di tali punti mi delinea il percorso che verra seguito dal soggetto designato

Variabili :
-una enumerazione sul TipoPercorso , con dentro il nome di ciascun percorso
-Schiera di gameobject contententi i posizionatori

Lo script viene eseguito nella scena in quanto c'e il metodo void OnDrawGizmos()
che me lo esegue in questo contesto.

Ogni qualvolta si attiva la scena cliccandoci sopra viene eseguito un ciclo dove ciascuna
scheera di posizionatori viene sistemata a un offset di distanza sopra l'oggetto che sta
sopra la sua verticale, in modo da avere un allineamento corretto anche al di sopra di supercifi

NOMI VARIABILI :
 - Transform[] PercorsoA,PercorsoB,PercorsoC

ENUMERAZIONE :
 - TipoPercorso.A,TipoPercorso.B,TipoPercorso.C

*/

public class GestorePercorso : MonoBehaviour
{
    //public List<Transform> Percorso = new List<Transform>();
    public Transform this[int idx]
    {
        get
        {
            if (transform.childCount < 1) return null;
            if (idx >=0 && idx < transform.childCount)
                return transform.GetChild(idx);
            else return transform.GetChild(0);
        }
    }

    public float offsetSpostaOggetto = 0.5f;
    public Color colore = Color.black;
    public int IndexPercorso = -1;

    private RaycastHit hitinfo;
    private Vector3 nuovaPosizione;

    void OnDrawGizmos()
    {
        if (Application.isPlaying)
            return;
        if (transform.childCount > 0)
        {
            Transform[] path = new Transform[transform.childCount];
            for (int i = 0; i < transform.childCount; i++)
            {
                path[i] = transform.GetChild(i);
                Ray raggio = new Ray(new Vector3(this[i].transform.position.x, 1000f, this[i].transform.position.z), Vector3.down);
                if (Physics.Raycast(raggio, out hitinfo))
                {
                    nuovaPosizione = new Vector3(this[i].transform.position.x, hitinfo.point.y + offsetSpostaOggetto, this[i].transform.position.z);
                    this[i].transform.position = nuovaPosizione;
                }

            }

            if (transform.childCount > 1)
                iTween.DrawPathGizmos(path, colore);
            // iTween.DrawLineHandles(path, colore);
        }

    }

}

redpajama_set_name: RedPajamaGithub


text:
using System.Collections.Generic;
using NPOI.SS.UserModel;
using Trendyol.Excelsior.Validation;

namespace Trendyol.Excelsior
{
    public interface IExcelsior
    {
        IEnumerable<T> Listify<T>(string filePath, bool hasHeaderRow = false);

        IEnumerable<T> Listify<T>(byte[] data, bool hasHeaderRow = false);

        IEnumerable<T> Listify<T>(IWorkbook workbook, bool hasHeaderRow = false);

        IEnumerable<IValidatedRow<T>> Listify<T>(string filePath, IRowValidator<T> rowValidator, bool hasHeaderRow = false);

        IEnumerable<IValidatedRow<T>> Listify<T>(byte[] data, IRowValidator<T> rowValidator, bool hasHeaderRow = false);

        IEnumerable<IValidatedRow<T>> Listify<T>(IWorkbook workbook, IRowValidator<T> rowValidator, bool hasHeaderRow = false);

        IEnumerable<string[]> Arrayify(string filePath, bool hasHeaderRow = false);

        IEnumerable<string[]> Arrayify(byte[] data, bool hasHeaderRow = false);

        IEnumerable<string[]> Arrayify(IWorkbook workbook, bool hasHeaderRow = false);

        byte[] Excelify<T>(IEnumerable<T> rows, bool printHeaderRow = false);
    }
}


text:
@implementation FileSystemInfo

@synthesize createdDateTime;
@synthesize lastModifiedDateTime;

@end


text:
require 'feature_helper'

describe "Bower Dependencies" do
  # As a JS developer
  # I want to be able to manage Bower dependencies

  let(:js_developer) { LicenseFinder::TestingDSL::User.new }

  specify "are shown in reports" do
    LicenseFinder::TestingDSL::BowerProject.create
    js_developer.run_license_finder
    expect(js_developer).to be_seeing_line "gmaps, 0.2.30, MIT"
  end
end


text:
var express = require('express');
var router = express.Router();
var path = require('path');

router.get('/', function (req, res) {
  res.sendFile('index.html', {root: path.join(__dirname, '../../public')});
});

module.exports = router;


text:
/** The group management methods for StudentsManager. */
Ext.define('devilry.administrator.studentsmanager.StudentsManagerManageGroups', {
    requires: [
        'devilry.administrator.studentsmanager.ManuallyCreateUsers',
        'devilry.extjshelpers.RestProxy'
    ],

    /**
     * @private
     */
    showCreateGroupsInBulkWindow: function(initialLines, currentGroupRecords) {
        var win = Ext.widget('window', {
            title: 'Create assignment groups',
            modal: true,
            width: 830,
            height: 600,
            maximizable: true,
            layout: 'fit',
            items: {
                xtype: 'manuallycreateusers',
                deadlinemodel: this.deadlinemodel,
                assignmentrecord: this.assignmentrecord,
                suggestedDeadline: this.guessDeadlineFromCurrentlyLoadedGroups(),
                currentGroupRecords: currentGroupRecords,
                initialLines: initialLines
            },
            listeners: {
                scope: this,
                close: function() {
                    this.refreshStore();
                }
            }
        });
        win.show();
    },

    /**
     * @private
     */
    createManyGroupsInBulk: function(initialLines) {
        this.getEl().mask('Loading current assignment groups...');
        devilry.administrator.studentsmanager.StudentsManager.getAllGroupsInAssignment(this.assignmentid, {
            scope: this,
            callback: function(records, op, success) {
                this.getEl().unmask();
                if(success) {
                    this.showCreateGroupsInBulkWindow(initialLines, records);
                } else {
                    Ext.MessageBox.alert('Failed to load current assignment groups. Please try again.');
                }
            }
        });
    },

    /**
     * @private
     *
     * Pick the latest deadline on the last group in the current view. The idea
     * is to get the last created group, however we do not load the last page,
     * so this is a balance of efficiency and convenience.
     */
    guessDeadlineFromCurrentlyLoadedGroups: function() {
        var groupRecords = this.assignmentgroupstore.data.items;
        if(groupRecords.length > 0) {
            var lastLoadedGroup = groupRecords[groupRecords.length-1];
            return lastLoadedGroup.data.latest_deadline_deadline;
        } else {
            return undefined;
        }
    },

    /**
     * @private
     */
    onManuallyCreateUsers: function() {
        this.createManyGroupsInBulk();
    },

    /**
     * @private
     */
    onOneGroupForEachRelatedStudent: function() {
        this.loadAllRelatedStudents({
            scope: this,
            callback: this.createOneGroupForEachRelatedStudent
            //args: ['Hello world']
        });
    },

    /**
     * @private
     */
    createOneGroupForEachRelatedStudent: function(relatedStudents) {
        var format = '{user__username}';
        if(this.assignmentrecord.data.anonymous) {
            format += '<tpl if="candidate_id">:{candidate_id}</tpl>'
        }
        format += '<tpl if="tags"> ({tags})</tpl>';
        var userspecs = this.relatedUserRecordsToStringArray(relatedStudents, format);
        this.createManyGroupsInBulk(userspecs);
    },

    onChangeGroupName: function() {
        if(!this.singleSelected()) {
            this.onNotSingleSelected();
            return;
        }

        var record = this.getSelection()[0];
        Ext.Msg.prompt('Change group name', 'Please enter a new group name:', function(btn, name){
            if (btn == 'ok'){
                record.data.name = name;
                record.save();
            }
        });
    },

    onChangeGroupMembers: function() {
        if(!this.singleSelected()) {
            this.onNotSingleSelected();
            return;
        }

        var record = this.getSelection()[0];
        var candidates = this.statics().getCandidateInfoFromGroupRecord(record);

        var candidatestrings = [];
        var statics = this.statics();
        Ext.each(candidates, function(candidate, index) {
            candidatestrings.push(statics.formatCandidateInfoAsString(candidate));
        });

        var win = Ext.widget('window', {
            title: 'Select members',
            modal: true,
            width: 500,
            height: 400,
            maximizable: true,
            layout: 'fit',
            items: {
                xtype: 'setlistofusers',
                usernames: candidatestrings,
                anonymous: record.data.parentnode__anonymous,
                helptpl: Ext.create('Ext.XTemplate',
                    '
',
                    '   <tpl if="anonymous">',
                    '
One candidate of on each line. Username and candidate ID is separated by a single colon. Note that candidate ID does not have to be a number.
',
                    '
Example:
',
                    '
bob:20\nalice:A753\neve:SEC-01\ndave:30
',
                    '   </tpl>',
                    '   <tpl if="!anonymous">',
                    '
One username on each line. Example
',
                    '
bob\nalice\neve\ndave
',
                    '   </tpl>',
                    '
'
                ),
                listeners: {
                    scope: this,
                    saveClicked: Ext.bind(this.changeGroupMembers, this, [record], true)
                }
            },
        });
        win.show();
    },

    changeGroupMembers: function(setlistofusersobj, candidateSpecs, caller, record) {
        var editRecord = this.createRecordFromStoreRecord(record);
        editRecord.data.fake_candidates = [];
        Ext.Array.each(candidateSpecs, function(candidateSpec) {
            editRecord.data.fake_candidates.push(devilry.administrator.studentsmanager.StudentsManagerManageGroups.parseCandidateSpec(candidateSpec));
        }, this);

        setlistofusersobj.getEl().mask("Changing group members");
        editRecord.save({
            scope: this,
            failure: function(records, operation) {
                setlistofusersobj.getEl().unmask();
                devilry.extjshelpers.RestProxy.showErrorMessagePopup(operation, 'Failed to change group members');
            },
            success: function() {
                setlistofusersobj.up('window').close();
                this.loadFirstPage();
            }
        });
    },

    onDeleteGroups: function() {
        //this.down('studentsmanager_studentsgrid').selModel.selectAll();
        if(this.noneSelected()) {
            this.onSelectNone();
            return;
        }
        Ext.MessageBox.show({
            title: 'Are you sure that you want to delete the selected groups',
            msg: '
Are you sure you want to delete the selected groups?

If you are a superadmin, this will delete the group and all their related data on this assignment, including deliveries and feedback.

If you are a normal administrator, you will only be permitted to delete groups without any deliveries.
',
            buttons: Ext.Msg.YESNO,
            icon: Ext.Msg.WARNING,
            scope: this,
            fn: function(btn) {
                if(btn == 'yes') {
                    this.down('studentsmanager_studentsgrid').gatherSelectedRecordsInArray({
                        scope: this,
                        callback: this.deleteGroups
                    });
                }
            }
        });

    },

    /**
     * @private
     */
    deleteGroups: function(groupRecords) {
        this.progressWindow.start('Delete groups');
        this._finishedSavingGroupCount = 0;
        Ext.each(groupRecords, function(groupRecord, index) {
            this.deleteGroup(groupRecord, index, groupRecords.length);
        }, this);
    },

    /**
     * @private
     */
    deleteGroup: function(record, index, totalSelectedGroups) {
        var msg = Ext.String.format('Deleting group {0}/{1}',
            index, totalSelectedGroups
        );
        this.getEl().mask(msg);

        var editRecord = this.createRecordFromStoreRecord(record);
        editRecord.destroy({
            scope: this,
            callback: function(r, operation) {
                if(operation.success) {
                    this.progressWindow.addSuccess(record, 'Group successfully deleted.');
                } else {
                    this.progressWindow.addErrorFromOperation(record, 'Failed to delete group.', operation);
                }

                this._finishedSavingGroupCount ++;
                if(this._finishedSavingGroupCount == totalSelectedGroups) {
                    this.loadFirstPage();
                    this.getEl().unmask();
                    this.progressWindow.finish();
                }
            }
        });
    },

    onImportGroupsFromAnotherAssignmentInCurrentPeriod: function() {
        Ext.widget('window', {
            title: 'Import from another assignment in the current Period',
            layout: 'fit',
            width: 830,
            height: 600,
            modal: true,
            items: {
                xtype: 'importgroupsfromanotherassignment',
                periodid: this.periodid,
                help: '
Select the assignment you wish to import assignment groups from, and click Next to further edit the selected groups.
',
                listeners: {
                    scope: this,
                    next: this._importGroupsFromAnotherAssignmentInCurrentPeriod
                }
            }
        }).show();
    },

    _convertGroupRecordToGroupSpec: function(groupRecord) {
        var statics = this.statics();
        var candidates = statics.getCandidateInfoFromGroupRecord(groupRecord);
        var groupString = '';
        Ext.each(candidates, function(candidate, index) {
            var candidateString = statics.formatCandidateInfoAsString(candidate);
            if(index != candidates.length-1)
                candidateString += ', ';
            groupString += candidateString;
        }, this);
        var tags = groupRecord.get('tags__tag');
        if(tags && tags.length > 0) {
            var tagsString = tags.join(',');
            groupString += Ext.String.format(' ({0})', tagsString);
        }
        var name = groupRecord.get('name');
        if(name) {
            groupString = name + ":: " + groupString;
        }
        return groupString;
    },

    _importGroupsFromAnotherAssignmentInCurrentPeriod: function(importPanel, assignmentGroupRecords) {
        importPanel.up('window').close();
        var groups = [];
        Ext.each(assignmentGroupRecords, function(groupRecord, index) {
            groups.push(this._convertGroupRecordToGroupSpec(groupRecord));
        }, this);
        this.createManyGroupsInBulk(groups);
    },

    onSetCandidateIdBulk: function() {
        if(this.noneSelected()) {
            this.onSelectNone();
            return;
        }
        var win = Ext.widget('window', {
            title: 'Import candidate IDs',
            modal: true,
            width: 800,
            height: 600,
            maximizable: true,
            layout: 'fit',
            items: {
                xtype: 'setlistofusers',
                usernames: [],
                fieldLabel: 'Candidates',
                anonymous: this.assignmentrecord.anonymous,
                helptpl: Ext.create('Ext.XTemplate',
                    '
',
                    '
Warning: This action will replace/clear candidate IDs on every selected group.
',
                    '
The intended use case for this window is to paste candidate IDs into Devilry instead of setting candidate IDs manually.
',
                    '
The format is one candidate on each line. Username and candidate ID is separated by whitespace and/or a single colon, comma or semicolon. Note that candidate ID does not have to be a number.
',
                    '
Example (using colon to separate username and candidate ID):
',
                    '
bob:20\nalice:A753\neve:SEC-01\ndave:30
',
                    '
Example (showing all of the supported separators):
',
                    '
bob    20\nalice : A753\neve, SEC-01\ndave;  30
',
                    '
'
                ),
                listeners: {
                    scope: this,
                    saveClicked: function(setlistofusersobj, candidateSpecs, caller) {
                        try {
                            var usernameToCandidateIdMap = this.parseCandidateImportFormat(candidateSpecs);
                        } catch(e) {
                            Ext.MessageBox.alert('Error', e);
                            return;
                        }
                        setlistofusersobj.up('window').close();
                        this.progressWindow.start('Set candidate ID on many');
                        this._finishedSavingGroupCount = 0;
                        this.down('studentsmanager_studentsgrid').performActionOnSelected({
                            scope: this,
                            callback: this.setCandidateId,
                            extraArgs: [usernameToCandidateIdMap]
                        });

                    },
                }
            }
        });
        win.show();

    },

    /**
     * @private
     */
    parseCandidateImportFormat: function(candidateSpecs) {
        var usernameToCandidateIdMap = {};
        Ext.each(candidateSpecs, function(candidateSpec, index) {
            var s = candidateSpec.split(/\s*[:,;\s]\s*/);
            if(candidateSpec.length > 0) {
                if(s.length != 2) {
                    throw Ext.String.format('Invalid format on line {0}: {1}', index, candidateSpec)
                }
                usernameToCandidateIdMap[s[0]] = s[1];
            }
        }, this);
        return usernameToCandidateIdMap;
    },

    /**
     * @private
     */
    setCandidateId: function(record, index, totalSelectedGroups, usernameToCandidateIdMap) {
        var msg = Ext.String.format('Setting candidate ID on group {0}/{1}',
            index, totalSelectedGroups
        );
        this.getEl().mask(msg);

        var editRecord = this.createRecordFromStoreRecord(record);
        editRecord.data.fake_candidates = [];

        var result_preview = '';
        var usernames = record.data.candidates__student__username;
        Ext.Array.each(usernames, function(username, index) {
            var candidate_id = usernameToCandidateIdMap[username];
            editRecord.data.fake_candidates.push({
                username: username,
                candidate_id: candidate_id
            });
            result_preview += username;
            if(candidate_id) {
                result_preview += username + ':';
            } else {
                this.progressWindow.addWarning(record, Ext.String.format('No Candidate ID for {0}.', username));
            }
            if(index < usernames.length) {
                result_preview += ', ';
            }
        }, this);

        editRecord.save({
            scope: this,
            callback: function(records, operation) {
                if(operation.success) {
                    this.progressWindow.addSuccess(record, Ext.String.format('Candidate IDs successfully updated to: {0}.', result_preview));
                } else {
                    this.progressWindow.addErrorFromOperation(record, 'Failed to save changes to group.', operation);
                }

                this._finishedSavingGroupCount ++;
                if(this._finishedSavingGroupCount == totalSelectedGroups) {
                    this.loadFirstPage();
                    this.getEl().unmask();
                    this.progressWindow.finish();
                }
            }
        });
    },

    statics: {
        getCandidateInfoFromGroupRecord: function(record) {
            var candidates = [];
            Ext.each(record.data.candidates__student__username, function(username, index) {
                candidate = {username: username};
                if(record.data.parentnode__anonymous) {
                    candidate.candidate_id = record.data.candidates__identifier[index];
                }
                candidates.push(candidate);
            });
            return candidates;
        },

        formatCandidateInfoAsString: function(candidate) {
            if(candidate.candidate_id == undefined || candidate.candidate_id == "candidate-id missing") {
                return candidate.username;
            } else {
                return Ext.String.format('{0}:{1}', candidate.username, candidate.candidate_id);
            }
        },

        parseCandidateSpec: function(candidateSpec) {
            var asArray = candidateSpec.split(/\s*:\s*/);
            var candidate_id = asArray.length > 1? asArray[1]: null;
            return {
                username: asArray[0],
                candidate_id: candidate_id
            };
        },
    }
});


text:
@implementation eLongSpecialPromotionItem
- (id) initWithType:(SpecialPromotionType)promotionType{
    if (self = [super initWithFrame:CGRectZero]) {
        self.contentMode = UIViewContentModeRight;
        switch (promotionType) {
            case SpecialPromotionHongbao:{
                self.frame = CGRectMake(0, 0, 24 + 4, 12);
                self.sortIndex = 3;
                UILabel *tagLbl = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width - 4, 12)];
                tagLbl.font = [UIFont systemFontOfSize:9];
                tagLbl.textColor = [UIColor colorWithHexStr:@"#4499ff"];
                tagLbl.layer.borderColor = [[UIColor colorWithHexStr:@"#4499ff"] CGColor];
                tagLbl.layer.borderWidth = SCREEN_SCALE;
                tagLbl.layer.cornerRadius = 1;
                tagLbl.layer.masksToBounds = YES;
                tagLbl.backgroundColor = [UIColor clearColor];
                tagLbl.textAlignment = NSTextAlignmentCenter;
                [self addSubview:tagLbl];
                tagLbl.text = @"红包";

            }
                break;
            case SpecialPromotionDiscount: {
                self.frame = CGRectMake(0, 0, 24 + 4, 12);
                self.sortIndex = 1;
                UILabel *tagLbl = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width - 4, 12)];
                tagLbl.font = [UIFont systemFontOfSize:9];
                tagLbl.textColor = [UIColor colorWithHexStr:@"#4499ff"];
                tagLbl.layer.borderColor = [[UIColor colorWithHexStr:@"#4499ff"] CGColor];
                tagLbl.layer.borderWidth = SCREEN_SCALE;
                tagLbl.layer.cornerRadius = 1;
                tagLbl.layer.masksToBounds = YES;
                tagLbl.backgroundColor = [UIColor clearColor];
                tagLbl.textAlignment = NSTextAlignmentCenter;
                [self addSubview:tagLbl];
                tagLbl.text = @"立减";
            }
            break;
            case SpecialPromotionDiscountHongbao:{
                self.frame = CGRectMake(0, 0, (24 + 2)*2, 12);
                self.image = [UIImage imageNamed:@"discount_hotellist"];
                self.sortIndex = 4;
                if([[[UIDevice currentDevice] systemVersion] floatValue] < 7.0){
                    self.discountLbl = [[UILabel alloc] initWithFrame:CGRectMake(1, 0, (24 + 2)*2, 12)];
                }else{
                    self.discountLbl = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, (24 + 2)*2, 12)];
                }
                self.discountLbl.font = [UIFont boldSystemFontOfSize:10.0f];
                self.discountLbl.backgroundColor = [UIColor clearColor];
                self.discountLbl.textColor = [UIColor clearColor];
                self.discountLbl.textAlignment = NSTextAlignmentRight;
                self.discountLbl.textColor = [UIColor colorWithHexStr:@"#4499ff"];
                self.discountLbl.layer.borderColor = [[UIColor colorWithHexStr:@"#4499ff"] CGColor];
                self.discountLbl.layer.borderWidth = SCREEN_SCALE;
                self.discountLbl.layer.cornerRadius = 1;
                self.discountLbl.layer.masksToBounds = YES;
                self.discountLbl.adjustsFontSizeToFitWidth = YES;
                [self addSubview:self.discountLbl];
            }
            break;
            case SpecialPromotionCoupon:{
                self.frame = CGRectMake(0, 0, 14 + 4, 12);
                self.sortIndex = 2;
                UILabel *tagLbl = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width - 4, 12)];
                tagLbl.font = [UIFont systemFontOfSize:9];
                tagLbl.textColor = [UIColor colorWithHexStr:@"#4499ff"];
                tagLbl.layer.borderColor = [[UIColor colorWithHexStr:@"#4499ff"] CGColor];
                tagLbl.layer.borderWidth = SCREEN_SCALE;
                tagLbl.layer.cornerRadius = 1;
                tagLbl.layer.masksToBounds = YES;
                tagLbl.backgroundColor = [UIColor clearColor];
                tagLbl.textAlignment = NSTextAlignmentCenter;
                [self addSubview:tagLbl];
                tagLbl.text = @"返";
            }
                break;
            case SpecialPromotionCouponNum:{
                self.frame = CGRectMake(0, 0, 24 + 2, 12);
                valueLbl = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 24 + 2, 12)];
                valueLbl.font = [UIFont systemFontOfSize:10.0f];
                valueLbl.textAlignment = NSTextAlignmentCenter;
                valueLbl.textColor = RGBACOLOR(254, 75, 32, 1);
                valueLbl.backgroundColor = [UIColor clearColor];
                [self addSubview:valueLbl];
                valueLbl.text = [NSString stringWithFormat:@"¥%ld",(long)self.value];
                self.sortIndex = 0;
            }
                break;
            default:
                break;
        }
    }
    return self;
}

- (void)dealloc
{
    self.discountLbl = nil;
//    [super dealloc];
}

- (void) setValue:(NSInteger)value{
    _value = value;
    valueLbl.text = [NSString stringWithFormat:@"¥%ld",(long)self.value];
}

@end

@implementation eLongSpecialPromotionView
- (id) initWithFrame:(CGRect)frame{
    if (self = [super initWithFrame:frame]) {
        _contentView = [[UIScrollView alloc] initWithFrame:self.bounds];
        _contentView.contentSize = CGSizeMake(frame.size.width, frame.size.height);
        _contentView.scrollEnabled = NO;
        [self addSubview:_contentView];

        self.items = [NSMutableArray array];

        _contentView.userInteractionEnabled = NO;
        self.userInteractionEnabled = NO;
    }
    return self;
}

-(void)dealloc{
    self.items = nil;
}

- (BOOL) scrollEnabled{
    return _contentView.scrollEnabled;
}

- (void) setScrollEnabled:(BOOL)scrollEnabled{
    _contentView.scrollEnabled = scrollEnabled;
}

- (void) reset{
    [_contentView removeAllSubviews];
//    [self removeAllSubviews];
    self.items = [NSArray array];
}

- (void) addeLongSpecialPromotionItem:(eLongSpecialPromotionItem *)item{
    float x = 0;
    float y = 0;
    NSMutableArray *tItems = [NSMutableArray arrayWithArray:self.items];
    [tItems addObject:item];

    self.items = [tItems sortedArrayWithOptions:NSSortConcurrent usingComparator:^NSComparisonResult(id obj1, id obj2) {
        NSInteger index0 = ((eLongSpecialPromotionItem *)obj1).sortIndex;
        NSInteger index1 = ((eLongSpecialPromotionItem *)obj2).sortIndex;
        if (index0 > index1) {
            return 1;
        }else if(index0 == index1){
            return 0;
        }else{
            return -1;
        }
    }];

    [_contentView removeAllSubviews];

    for (eLongSpecialPromotionItem *typeItem in self.items) {
        typeItem.frame = CGRectMake(self.frame.size.width - x - typeItem.frame.size.width, y, typeItem.frame.size.width, typeItem.frame.size.height);
        x += typeItem.frame.size.width;
        [_contentView addSubview:typeItem];
    }
    _contentView.contentSize = CGSizeMake(x, 12);
}
@end


text:
<?php

// Joaquin-V/Chatter - Telegram API for PHP 7.
// License: GNU General Public License <http://www.gnu.org/licenses/>
// Copyright (C) 2016 Joaquín Varela

namespace JoaquinV\Chatter\result;

/**
 * Represents a contact.
 */
class Contact extends Result{

	protected $mobileNumber='';
	protected $firstName='';
	protected $lastName;
	protected $userID;

	public function __construct($json){
		$json = $this->parseJSON($json);
		$this->mobileNumber = $json['phone_number'];
		$this->firstName = $json['first_name'];
		if(isset($json['last_name']))
			$this->lastName = $json['last_name'];
		if(isset($json['user_id']))
			$this->userID = $json['user_id'];
	}

	/**
	 * Gets this contact's phone number as a string.
	 * @return string
	 */
	public function getNumber(): string{
		return $this->mobileNumber;
	}

	public function getName(&$first='', &$last=''): string{
		$first = $full = $this->firstName;
		$last  = $this->lastName;
		if($last)
			$full .= ' '.$last;
		return $full;
	}

	public function getID(){
		return $this->userID;
	}
}


text:
<!DOCTYPE html>

    <meta http-equiv="content-type" content="text/html; charset=UTF-8" />

    <title>Choose a Management Information System - The best place to find information on MIS systems</title>

    <link href="/assets/stylesheets/govuk-template.css" media="screen" rel="stylesheet" type="text/css" />

      <link href="/assets/stylesheets/fonts.css" media="all" rel="stylesheet" type="text/css" />

    <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
    <meta name="viewport" content="width=device-width, initial-scale=1">

        Skip to main content

CHOOSEAMIS.UK uses cookies to make the site simpler. Find out more about cookies

              CHOOSEAMIS.UK

Browsers

Suppliers

Bromcom

Capita

Histon House

RM

Tribal

Wauton Samuel

Support links

Help

Cookies

This site is licensed under the Creative Commons Attribution 3.0 Unported License, except where otherwise stated


text: sap.ui.define(['sap/f/semantic/SemanticButton'],function(S){"use strict";var a=S.extend("sap.f.semantic.SendMessageAction",{metadata:{library:"sap.f"}});return a;},true);


text:
 .. Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

 ..   http://www.apache.org/licenses/LICENSE-2.0

 .. Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.

.. contents:: :local:

Contributions
=============

Contributions are welcome and are greatly appreciated! Every little bit helps,
and credit will always be given.

Get Mentoring Support
---------------------

If you are new to the project, you might need some help in understanding how the dynamics
of the community works and you might need to get some mentorship from other members of the
community - mostly committers. Mentoring new members of the community is part of committers
job so do not be afraid of asking committers to help you. You can do it
via comments in your Pull Request, asking on a devlist or via Slack. For your convenience,
we have a dedicated #newbie-questions Slack channel where you can ask any questions
you want - it's a safe space where it is expected that people asking questions do not know
a lot about Airflow (yet!).

If you look for more structured mentoring experience, you can apply to Apache Software Foundation's
`Official Mentoring Programme <http://community.apache.org/mentoringprogramme.html>`_. Feel free
to follow it and apply to the programme and follow up with the community.

Report Bugs
-----------

Report bugs through `Apache
JIRA <https://issues.apache.org/jira/browse/AIRFLOW>`__.

Please report relevant information and preferably code that exhibits the
problem.

Fix Bugs
--------

Look through the JIRA issues for bugs. Anything is open to whoever wants to
implement it.

Implement Features
------------------

Look through the `Apache
JIRA <https://issues.apache.org/jira/browse/AIRFLOW>`__ for features.

Any unassigned "Improvement" issue is open to whoever wants to implement it.

We've created the operators, hooks, macros and executors we needed, but we've
made sure that this part of Airflow is extensible. New operators, hooks, macros
and executors are very welcomed!

Improve Documentation
---------------------

Airflow could always use better documentation, whether as part of the official
Airflow docs, in docstrings, ``docs/*.rst`` or even on the web as blog posts or
articles.

Submit Feedback
---------------

The best way to send feedback is to open an issue on `Apache
JIRA <https://issues.apache.org/jira/browse/AIRFLOW>`__.

If you are proposing a new feature:

-   Explain in detail how it would work.
-   Keep the scope as narrow as possible to make it easier to implement.
-   Remember that this is a volunteer-driven project, and that contributions are
    welcome :)

Documentation
=============

The latest API documentation is usually available
`here <https://airflow.apache.org/>`__.

To generate a local version:

1.  Set up an Airflow development environment.

2.  Install the ``doc`` extra.

.. code-block:: bash

    pip install -e '.[doc]'

3.  Generate and serve the documentation as follows:

.. code-block:: bash

    cd docs
    ./build.sh
    ./start_doc_server.sh

.. note::
    The docs build script ``build.sh`` requires bash 4.0 or greater.
    If you are building on Mac OS, you can install latest version of bash with homebrew.

**Known issues:**

If you are creating a new directory for new integration in the ``airflow.providers`` package,
you should also update the ``docs/autoapi_templates/index.rst`` file.

If you are creating a ``hooks``, ``sensors``, ``operators`` directory in
the ``airflow.providers`` package, you should also update
the ``docs/operators-and-hooks-ref.rst`` file.

If you are creating ``example_dags`` directory, you need to create ``example_dags/__init__.py`` with Apache license or copy another ``__init__.py`` file that contains the necessary license.

Pull Request Guidelines
=======================

Before you submit a pull request (PR) from your forked repo, check that it meets
these guidelines:

-   Include tests, either as doctests, unit tests, or both, to your pull
    request.

    The airflow repo uses `Travis CI <https://travis-ci.org/apache/airflow>`__ to
    run the tests and `codecov <https://codecov.io/gh/apache/airflow>`__ to track
    coverage. You can set up both for free on your fork (see
    `Travis CI Testing Framework <TESTING.rst#travis-ci-testing-framework>`__ usage guidelines).
    It will help you make sure you do not break the build with your PR and
    that you help increase coverage.

-   `Rebase your fork <http://stackoverflow.com/a/7244456/1110993>`__, squash
    commits, and resolve all conflicts.

-   When merging PRs, wherever possible try to use **Squash and Merge** instead of **Rebase and Merge**.

-   Make sure every pull request introducing code changes has an associated
    `JIRA <https://issues.apache.org/jira/browse/AIRFLOW/?selectedTab=com.atlassian.jira.jira-projects-plugin:summary-panel>`__
    ticket. The JIRA link should also be added to the PR description. In case of documentation only changes
    the JIRA ticket is not necessary.

-   Preface your commit's subject & PR title with **[AIRFLOW-NNNN] COMMIT_MSG** where *NNNN*
    is the JIRA number. For example: [AIRFLOW-5574] Fix Google Analytics script loading. In case of
    documentation only changes you should put "[AIRFLOW-XXXX]" instead.
    We compose Airflow release notes from all commit titles in a release. By placing the JIRA number in the
    commit title and hence in the release notes, we let Airflow users look into
    JIRA and GitHub PRs for more details about a particular change.

-   Add an `Apache License <http://www.apache.org/legal/src-headers.html>`__ header
    to all new files.

    If you have `pre-commit hooks <STATIC_CODE_CHECKS.rst#pre-commit-hooks>`__ enabled, they automatically add
    license headers during commit.

-   If your pull request adds functionality, make sure to update the docs as part
    of the same PR. Doc string is often sufficient. Make sure to follow the
    Sphinx compatible standards.

-   Make sure your code fulfils all the
    `static code checks <STATIC_CODE_CHECKS.rst#pre-commit-hooks>`__ we have in our code. The easiest way
    to make sure of that is to use `pre-commit hooks <STATIC_CODE_CHECKS.rst#pre-commit-hooks>`__

-   Run tests locally before opening PR.

-   Make sure the pull request works for Python 3.6 and 3.7.

-   Adhere to guidelines for commit messages described in this `article <http://chris.beams.io/posts/git-commit/>`__.
    This makes the lives of those who come after you a lot easier.

Airflow Git Branches
====================

All new development in Airflow happens in the ``master`` branch. All PRs should target that branch.
We also have a ``v1-10-test`` branch that is used to test ``1.10.x`` series of Airflow and where committers
cherry-pick selected commits from the master branch.
Cherry-picking is done with the ``-x`` flag.

The ``v1-10-test`` branch might be broken at times during testing. Expect force-pushes there so
committers should coordinate between themselves on who is working on the ``v1-10-test`` branch -
usually these are developers with the release manager permissions.

Once the branch is stable, the ``v1-10-stable`` branch is synchronized with ``v1-10-test``.
The ``v1-10-stable`` branch is used to release ``1.10.x`` releases.

Development Environments
========================

There are two environments, available on Linux and macOS, that you can use to
develop Apache Airflow:

-   `Local virtualenv development environment <#local-virtualenv-development-environment>`_
    that supports running unit tests and can be used in your IDE.

-   `Breeze Docker-based development environment <#breeze-development-environment>`_ that provides
    an end-to-end CI solution with all software dependencies covered.

The table below summarizes differences between the two environments:

========================= ================================ =====================================
**Property**              **Local virtualenv**             **Breeze environment**
========================= ================================ =====================================
Test coverage             - (-) unit tests only            - (+) integration and unit tests
------------------------- -------------------------------- -------------------------------------
Setup                     - (+) automated with breeze cmd  - (+) automated with breeze cmd
------------------------- -------------------------------- -------------------------------------
Installation difficulty   - (-) depends on the OS setup    - (+) works whenever Docker works
------------------------- -------------------------------- -------------------------------------
Team synchronization      - (-) difficult to achieve       - (+) reproducible within team
------------------------- -------------------------------- -------------------------------------
Reproducing CI failures   - (-) not possible in many cases - (+) fully reproducible
------------------------- -------------------------------- -------------------------------------
Ability to update         - (-) requires manual updates    - (+) automated update via breeze cmd
------------------------- -------------------------------- -------------------------------------
Disk space and CPU usage  - (+) relatively lightweight     - (-) uses GBs of disk and many CPUs
------------------------- -------------------------------- -------------------------------------
IDE integration           - (+) straightforward            - (-) via remote debugging only
========================= ================================ =====================================

Typically, you are recommended to use both of these environments depending on your needs.

Local virtualenv Development Environment
----------------------------------------

All details about using and running local virtualenv environment for Airflow can be found
in `LOCAL_VIRTUALENV.rst <LOCAL_VIRTUALENV.rst>`__.

Benefits:

-   Packages are installed locally. No container environment is required.

-   You can benefit from local debugging within your IDE.

-   With the virtualenv in your IDE, you can benefit from autocompletion and running tests directly from the IDE.

Limitations:

-   You have to maintain your dependencies and local environment consistent with
    other development environments that you have on your local machine.

-   You cannot run tests that require external components, such as mysql,
    postgres database, hadoop, mongo, cassandra, redis, etc.

    The tests in Airflow are a mixture of unit and integration tests and some of
    them require these components to be set up. Local virtualenv supports only
    real unit tests. Technically, to run integration tests, you can configure
    and install the dependencies on your own, but it is usually complex.
    Instead, you are recommended to use
    `Breeze development environment <#breeze-development-environment>`__ with all required packages
    pre-installed.

-   You need to make sure that your local environment is consistent with other
    developer environments. This often leads to a "works for me" syndrome. The
    Breeze container-based solution provides a reproducible environment that is
    consistent with other developers.

-   You are **STRONGLY** encouraged to also install and use `pre-commit hooks <STATIC_CODE_CHECKS.rst#pre-commit-hooks>`_
    for your local virtualenv development environment.
    Pre-commit hooks can speed up your development cycle a lot.

Breeze Development Environment
------------------------------

All details about using and running Airflow Breeze can be found in
`BREEZE.rst <BREEZE.rst>`__.

The Airflow Breeze solution is intended to ease your local development as "*It's
a Breeze to develop Airflow*".

Benefits:

-   Breeze is a complete environment that includes external components, such as
    mysql database, hadoop, mongo, cassandra, redis, etc., required by some of
    Airflow tests. Breeze provides a preconfigured Docker Compose environment
    where all these services are available and can be used by tests
    automatically.

-   Breeze environment is almost the same as used in `Travis CI <https://travis-ci.com/>`__ automated builds.
    So, if the tests run in your Breeze environment, they will work in Travis CI as well.

Limitations:

-   Breeze environment takes significant space in your local Docker cache. There
    are separate environments for different Python and Airflow versions, and
    each of the images takes around 3GB in total.

-   Though Airflow Breeze setup is automated, it takes time. The Breeze
    environment uses pre-built images from DockerHub and it takes time to
    download and extract those images. Building the environment for a particular
    Python version takes less than 10 minutes.

-   Breeze environment runs in the background taking precious resources, such as
    disk space and CPU. You can stop the environment manually after you use it
    or even use a ``bare`` environment to decrease resource usage.

**NOTE:** Breeze CI images are not supposed to be used in production environments.
They are optimized for repeatability of tests, maintainability and speed of building rather
than production performance. The production images are not yet officially published.

Static code checks
==================

We check our code quality via static code checks. See
`STATIC_CODE_CHECKS.rst <STATIC_CODE_CHECKS.rst>`_ for details.

Your code must pass all the static code checks in Travis CI in order to be eligible for Code Review.
The easiest way to make sure your code is good before pushing is to use pre-commit checks locally
as described in the static code checks documentation.

Test Infrastructure
===================

We support the following types of tests:

* **Unit tests** are Python ``nose`` tests launched with ``run-tests``.
  Unit tests are available both in the `Breeze environment <BREEZE.rst>`_
  and `local virtualenv <LOCAL_VIRTUALENV.rst>`_.

* **Integration tests** are available in the Breeze development environment
  that is also used for Airflow Travis CI tests. Integration test are special tests that require
  additional services running, such as Postgres,Mysql, Kerberos, etc. These tests are not yet
  clearly marked as integration tests but soon they will be clearly separated by the ``pytest`` annotations.

* **System tests** are automatic tests that use external systems like
  Google Cloud Platform. These tests are intended for an end-to-end DAG execution.

For details on running different types of Airflow tests, see `TESTING.rst <TESTING.rst>`_.

Metadata Database Updates
==============================

When developing features, you may need to persist information to the metadata
database. Airflow has `Alembic <https://github.com/sqlalchemy/alembic>`__ built-in
module to handle all schema changes. Alembic must be installed on your
development machine before continuing with migration.

.. code-block:: bash

    # starting at the root of the project
    $ pwd
    ~/airflow
    # change to the airflow directory
    $ cd airflow
    $ alembic revision -m "add new field to db"
       Generating
    ~/airflow/airflow/migrations/versions/12341123_add_new_field_to_db.py

Node.js Environment Setup
=========================

``airflow/www/`` contains all yarn-managed, front-end assets. Flask-Appbuilder
itself comes bundled with jQuery and bootstrap. While they may be phased out
over time, these packages are currently not managed with yarn.

Make sure you are using recent versions of node and yarn. No problems have been
found with node\>=8.11.3 and yarn\>=1.19.1.

Installing yarn and its packages
--------------------------------

Make sure yarn is available in your environment.

To install yarn on macOS:

1.  Run the following commands (taken from `this source <https://gist.github.com/DanHerbert/9520689>`__):

.. code-block:: bash

    brew install node --without-npm
    brew install yarn
    yarn config set prefix ~/.yarn

2.  Add ``~/.yarn/bin`` to your ``PATH`` so that commands you are installing
    could be used globally.

3.  Set up your ``.bashrc`` file and then ``source ~/.bashrc`` to reflect the
    change.

.. code-block:: bash

    export PATH="$HOME/.yarn/bin:$PATH"

4.  Install third-party libraries defined in ``package.json`` by running the
    following commands within the ``airflow/www/`` directory:

.. code-block:: bash

    # from the root of the repository, move to where our JS package.json lives
    cd airflow/www/
    # run yarn install to fetch all the dependencies
    yarn install

These commands install the libraries in a new ``node_modules/`` folder within
``www/``.

Should you add or upgrade a node package, run
``yarn add --dev <package>`` for packages needed in development or
``yarn add <package>`` for packages used by the code.
Then push the newly generated ``package.json`` and ``yarn.lock`` file so that we
could get a reproducible build. See the `Yarn docs
<https://yarnpkg.com/en/docs/cli/add#adding-dependencies->`_ for more details.

Generate Bundled Files with yarn
----------------------------------

To parse and generate bundled files for Airflow, run either of the following
commands:

.. code-block:: bash

    # Compiles the production / optimized js & css
    yarn run prod

    # Starts a web server that manages and updates your assets as you modify them
    yarn run dev

Follow Javascript Style Guide
-----------------------------

We try to enforce a more consistent style and follow the JS community
guidelines.

Once you add or modify any javascript code in the project, please make sure it
follows the guidelines defined in `Airbnb
JavaScript Style Guide <https://github.com/airbnb/javascript>`__.

Apache Airflow uses `ESLint <https://eslint.org/>`__ as a tool for identifying and
reporting on patterns in JavaScript. To use it, run any of the following
commands:

.. code-block:: bash

    # Check JS code in .js and .html files, and report any errors/warnings
    yarn run lint

    # Check JS code in .js and .html files, report any errors/warnings and fix them if possible
    yarn run lint:fix

Contribution Workflow Example
==============================

Typically, you start your first contribution by reviewing open tickets
at `Apache JIRA <https://issues.apache.org/jira/browse/AIRFLOW>`__.

For example, you want to have the following sample ticket assigned to you:
`AIRFLOW-5934: Add extra CC: to the emails sent by Aiflow <https://issues.apache.org/jira/browse/AIRFLOW-5934>`_.

In general, your contribution includes the following stages:

.. image:: images/workflow.png
    :align: center
    :alt: Contribution Workflow

1. Make your own `fork <https://help.github.com/en/github/getting-started-with-github/fork-a-repo>`__ of
   the Apache Airflow `main repository <https://github.com/apache/airflow>`__.

2. Create a `local virtualenv <LOCAL_VIRTUALENV.rst>`_,
   initialize the `Breeze environment <BREEZE.rst>`__, and
   install `pre-commit framework <STATIC_CODE_CHECKS.rst#pre-commit-hooks>`__.
   If you want to add more changes in the future, set up your own `Travis CI
   fork <https://github.com/PolideaInternal/airflow/blob/more-gsod-improvements/TESTING.rst#travis-ci-testing-framework>`__.

3. Join `devlist <https://lists.apache.org/list.html?dev@airflow.apache.org>`__
   and set up a `Slack account <https://apache-airflow-slack.herokuapp.com>`__.

4. Make the change and create a `Pull Request from your fork <https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork>`__.

5. Ping @ #development slack, comment @people. Be annoying. Be considerate.

Step 1: Fork the Apache Repo
----------------------------
From the `apache/airflow <https://github.com/apache/airflow>`_ repo,
`create a fork <https://help.github.com/en/github/getting-started-with-github/fork-a-repo>`_:

.. image:: images/fork.png
    :align: center
    :alt: Creating a fork

Step 2: Configure Your Environment
----------------------------------
Configure the Docker-based Breeze development environment and run tests.

You can use the default Breeze configuration as follows:

1. Install the latest versions of the Docker Community Edition
   and Docker Compose and add them to the PATH.

2. Enter Breeze: ``./breeze``

   Breeze starts with downloading the Airflow CI image from
   the Docker Hub and installing all required dependencies.

3. Enter the Docker environment and mount your local sources
   to make them immediately visible in the environment.

4. Create a local virtualenv, for example:

.. code-block:: bash

   mkvirtualenv myenv --python=python3.6

5. Initialize the created environment:

.. code-block:: bash

   ./breeze --initialize-local-virtualenv

6. Open your IDE (for example, PyCharm) and select the virtualenv you created
   as the project's default virtualenv in your IDE.

Step 3: Connect with People
---------------------------

For effective collaboration, make sure to join the following Airflow groups:

- Mailing lists:

  - Developer's mailing list `<dev-subscribe@airflow.apache.org>`_
    (quite substantial traffic on this list)

  - All commits mailing list: `<commits-subscribe@airflow.apache.org>`_
    (very high traffic on this list)

  - Airflow users mailing list: `<users-subscribe@airflow.apache.org>`_
    (reasonably small traffic on this list)

- `Issues on Apache's JIRA <https://issues.apache.org/jira/browse/AIRFLOW>`__

- `Slack (chat) <https://apache-airflow-slack.herokuapp.com/>`__

Step 4: Prepare PR
------------------

1. Update the local sources to address the JIRA ticket.

   For example, to address this example JIRA ticket, do the following:

   * Read about `email configuration in Airflow <https://airflow.readthedocs.io/en/latest/howto/email-config.html>`__.

   * Find the class you should modify. For the example ticket,
     this is `email.py <https://github.com/apache/airflow/blob/master/airflow/utils/email.py>`__.

   * Find the test class where you should add tests. For the example ticket,
     this is `test_email.py <https://github.com/apache/airflow/blob/master/tests/utils/test_email.py>`__.

   * Create a local branch for your development. Make sure to use latest
     ``apache/master`` as base for the branch. See `How to Rebase PR <#how-to-rebase-pr>`_ for some details
     on setting up the ``apache`` remote. Note - some people develop their changes directy in their own
     ``master`` branches - this is OK and you can make PR from your master to ``apache/master`` but we
     recommend to always create a local branch for your development. This allows you to easily compare
     changes, have several changes that you work on at the same time and many more.
     If you have ``apache`` set as remote then you can make sure that you have latest changes in your master
     by ``git pull apache master`` when you are in the local ``master`` branch. If you have conflicts and
     want to override your locally changed master you can override your local changes with
     ``git fetch apache; git reset --hard apache/master``.

   * Modify the class and add necessary code and unit tests.

   * Run the unit tests from the `IDE <TESTING.rst#running-unit-tests-from-ide>`__
     or `local virtualenv <TESTING.rst#running-unit-tests-from-local-virtualenv>`__ as you see fit.

   * Run the tests in `Breeze <TESTING.rst#running-unit-tests-inside-breeze>`__.

   * Run and fix all the `static checks <STATIC_CODE_CHECKS>`__. If you have
     `pre-commits installed <STATIC_CODE_CHECKS.rst#pre-commit-hooks>`__,
     this step is automatically run while you are committing your code. If not, you can do it manually
     via ``git add`` and then ``pre-commit run``.

2. Rebase your fork, squash commits, and resolve all conflicts. See `How to rebase PR <#how-to-rebase-pr>`_
   if you need help with rebasing your change. Remember to rebase often if your PR takes a lot of time to
   review/fix. This will make rebase process much easier and less painful - and the more often you do it,
   the more comfortable you will feel doing it.

3. Re-run static code checks again.

4. Create a pull request with the following title for the sample ticket:
   ``[AIRFLOW-5934] Added extra CC: field to the Airflow emails.``

Make sure to follow other PR guidelines described in `this document <#pull-request-guidelines>`_.

Step 5: Pass PR Review
----------------------

.. image:: images/review.png
    :align: center
    :alt: PR Review

Note that committers will use **Squash and Merge** instead of **Rebase and Merge**
when merging PRs and your commit will be squashed to single commit.

How to rebase PR
================

A lot of people are unfamiliar with rebase workflow in Git, but we think it is an excellent workflow,
much better than merge workflow, so here is a short guide for those who would like to learn it. It's really
worth to spend a few minutes learning it. As opposed to merge workflow, the rebase workflow allows to
clearly separate your changes from changes of others, puts responsibility of proper rebase on the
author of the change. It also produces a "single-line" series of commits in master branch which
makes it much easier to understand what was going on and to find reasons for problems (it is especially
useful for "bisecting" when looking for a commit that introduced some bugs.

First of all - you can read about rebase workflow here:
`Merging vs. rebasing <https://www.atlassian.com/git/tutorials/merging-vs-rebasing>`_ - this is an
excellent article that describes all ins/outs of rebase. I recommend reading it and keeping it as reference.

The goal of rebasing your PR on top of ``apache/master`` is to "transplant" your change on top of
the latest changes that are merged by others. It also allows you to fix all the conflicts
that are result of other people changing the same files as you and merging the changes to ``apache/master``.

Here is how rebase looks in practice:

1. You need to add Apache remote to your git repository. You can add it as "apache" remote so that
   you can refer to it easily:

``git remote add apache git@github.com:apache/airflow.git`` if you use ssh or
``git remote add apache https://github.com/apache/airflow.git`` if you use https.

Later on

2. You need to make sure that you have the latest master fetched from ``apache`` repository. You can do it
   by ``git fetch apache`` for apache remote or ``git fetch --all`` to fetch all remotes.

3. Assuming that your feature is in a branch in your repository called ``my-branch`` you can check easily
   what is the base commit you should rebase from by: ``git merge-base my-branch apache/master``.
   This will print the HASH of the base commit which you should use to rebase your feature from -
   for example: ``5abce471e0690c6b8d06ca25685b0845c5fd270f``. You can also find this commit hash manually -
   if you want better control. Run ``git log`` and find the first commit that you DO NOT want to "transplant".
   ``git rebase HASH`` will "trasplant" all commits after the commit with the HASH.

4. Make sure you checked out your branch locally:

``git checkout my-branch``

5. Rebase:
   Run: ``git rebase HASH --onto apache/master``
   for example: ``git rebase 5abce471e0690c6b8d06ca25685b0845c5fd270f --onto apache/master``

6. If you have no conflicts - that's cool. You rebased. You can now run ``git push --force-with-lease`` to
   push your changes to your repository. That should trigger the build in CI if you have a
   Pull Request opened already.

7. While rebasing you might have conflicts. Read carefully what git tells you when it prints information
   about the conflicts. You need to solve the conflicts manually. This is sometimes the most difficult
   part and requires deliberate correcting your code looking what has changed since you developed your
   changes. There are various tools that can help you with that. You can use ``git mergetool`` (and you can
   configure different merge tools with it). Also you can use IntelliJ/PyCharm excellent merge tool.
   When you open project in PyCharm which has conflict you can go to VCS->Git->Resolve Conflicts and there
   you have a very intuitive and helpful merge tool. You can see more information
   about it in `Resolve conflicts <https://www.jetbrains.com/help/idea/resolving-conflicts.html.>`_

8. After you solved conflicts simply run ``git rebase --continue`` and go either to point 6. or 7.
   above depending if you have more commits that cause conflicts in your PR (rebasing applies each
   commit from your PR one-by-one).

How to communicate
==================

Apache Airflow is a Community within Apache Software Foundation. As the motto of
the Apache Software Foundation states "Community over Code" - people in the
community are far more important than their contribution.

This means that communication plays a big role in it, and this chapter is all about it.

We have various channels of communication - starting from the official devlist, comments
in the Pull Requests, Slack, wiki.

All those channels can be used for different purposes.
You can join the channels via links at the `Airflow Community page <https://airflow.apache.org/community/>`_

* The `Apache Airflow devlist <https://lists.apache.org/list.html?dev@airflow.apache.org>`_ for:
   * official communication
   * general issues, asking community for opinion
   * discussing proposals
   * voting
* The `Airflow CWiki <https://cwiki.apache.org/confluence/display/AIRFLOW/Airflow+Home?src=breadcrumbs>`_ for:
   * detailed discussions on big proposals (Airflow Improvement Proposals also name AIPs)
   * helpful, shared resources (for example Apache Airflow logos
   * information that can be re-used by others (for example instructions on preparing workshops)
* Github `Pull Requests (PRs) <https://github.com/apache/airflow/pulls>`_ for:
   * discussing implementation details of PRs
   * not for architectural discussions (use the devlist for that)
* The `Apache Airflow Slack <https://apache-airflow-slack.herokuapp.com/>`_ for:
   * ad-hoc questions related to development (#development channel)
   * asking for review (#development channel)
   * asking for help with PRs (#how-to-pr channel)
   * troubleshooting (#troubleshooting channel)
   * group talks (including SIG - special interest groups) (#sig-* channels)
   * notifications (#announcements channel)
   * random queries (#random channel)
   * regional announcements (#users-* channels)
   * newbie questions (#newbie-questions channel)
   * occasional discussions (wherever appropriate including group and 1-1 discussions)

The devlist is the most important and official communication channel. Often at Apache project you can
hear "if it is not in the devlist - it did not happen". If you discuss and agree with someone from the
community on something important for the community (including if it is with committer or PMC member) the
discussion must be captured and reshared on devlist in order to give other members of the community to
participate in it.

We are using certain prefixes for email subjects for different purposes. Start your email with one of those:
  * ``[DISCUSS]`` - if you want to discuss something but you have no concrete proposal yet
  * ``[PROPOSAL]`` - if usually after "[DISCUSS]" thread discussion you want to propose something and see
    what other members of the community think about it.
  * ``[AIP-NN]`` - if the mail is about one of the Airflow Improvement Proposals
  * ``[VOTE]`` - if you would like to start voting on a proposal discussed before in a "[PROPOSAL]" thread

Voting is governed by the rules described in `Voting <https://www.apache.org/foundation/voting.html>`_

We are all devoting our time for community as individuals who except for being active in Apache Airflow have
families, daily jobs, right for vacation. Sometimes we are in different time zones or simply are
busy with day-to-day duties that our response time might be delayed. For us it's crucial
to remember to respect each other in the project with no formal structure.
There are no managers, departments, most of us is autonomous in our opinions, decisions.
All of it makes Apache Airflow community a great space for open discussion and mutual respect
for various opinions.

Disagreements are expected, discussions might include strong opinions and contradicting statements.
Sometimes you might get two committers asking you to do things differently. This all happened in the past
and will continue to happen. As a community we have some mechanisms to facilitate discussion and come to
a consensus, conclusions or we end up voting to make important decisions. It is important that these
decisions are not treated as personal wins or looses. At the end it's the community that we all care about
and what's good for community, should be accepted even if you have a different opinion. There is a nice
motto that you should follow in case you disagree with community decision "Disagree but engage". Even
if you do not agree with a community decision, you should follow it and embrace (but you are free to
express your opinion that you don't agree with it).

As a community - we have high requirements for code quality. This is mainly because we are a distributed
and loosely organised team. We have both - contributors that commit one commit only, and people who add
more commits. It happens that some people assume informal "stewardship" over parts of code for some time -
but at any time we should make sure that the code can be taken over by others, without excessive communication.
Setting high requirements for the code (fairly strict code review, static code checks, requirements of
automated tests, pre-commit checks) is the best way to achieve that - by only accepting good quality
code. Thanks to full test coverage we can make sure that we will be able to work with the code in the future.
So do not be surprised if you are asked to add more tests or make the code cleaner -
this is for the sake of maintainability.

Here are a few rules that are important to keep in mind when you enter our community:

 * Do not be afraid to ask questions
 * The communication is asynchronous - do not expect immediate answers, ping others on slack
   (#development channel) if blocked
 * There is a #newbie-questions channel in slack as a safe place to ask questions
 * You can ask one of the committers to be a mentor for you, committers can guide within the community
 * You can apply to more structured `Apache Mentoring Programme <https://community.apache.org/mentoringprogramme.html>`_
 * It's your responsibility as an author to take your PR from start-to-end including leading communication
   in the PR
 * It's your responsibility as an author to ping committers to review your PR - be mildly annoying sometimes,
   it's OK to be slightly annoying with your change - it is also a sign for committers that you care
 * Be considerate to the high code quality/test coverage requirements for Apache Airflow
 * If in doubt - ask the community for their opinion or propose to vote at the devlist
 * Discussions should concern subject matters - judge or criticise the merit but never criticise people
 * It's OK to express your own emotions while communicating - it helps other people to understand you
 * Be considerate for feelings of others. Tell about how you feel not what you think of others

Resources & Links
=================
- `Airflow's official documentation <http://airflow.apache.org/>`__

- `More resources and links to Airflow related content on the Wiki <https://cwiki.apache.org/confluence/display/AIRFLOW/Airflow+Links>`__


text:
package org.apache.flink.table.api.stream.sql.validation

import org.apache.flink.api.scala._
import org.apache.flink.table.api.TableException
import org.apache.flink.table.api.scala._
import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
import org.junit.Test

class JoinValidationTest extends TableTestBase {

  private val streamUtil: StreamTableTestUtil = streamTestUtil()
  streamUtil.addTable[(Int, String, Long)]("MyTable", 'a, 'b, 'c.rowtime, 'proctime.proctime)
  streamUtil.addTable[(Int, String, Long)]("MyTable2", 'a, 'b, 'c.rowtime, 'proctime.proctime)

  /** Both time attributes in a join condition must be of the same type **/
  @Test(expected = classOf[TableException])
  def testWindowJoinDiffTimeIndicator() = {
    val sql =
      """
        |SELECT t2.a FROM
        |MyTable t1 JOIN MyTable2 t2 ON
        |  t1.a = t2.a AND
        |  t1.proctime > t2.proctime - INTERVAL '5' SECOND AND
        |  t1.proctime < t2.c + INTERVAL '5' SECOND""".stripMargin
    streamUtil.verifySql(sql, "n/a")
  }

  /** The time conditions should be an And condition **/
  @Test(expected = classOf[TableException])
  def testWindowJoinNotCnfCondition() = {
    val sql =
      """
        |SELECT t2.a
        |FROM MyTable t1 JOIN MyTable2 t2 ON
        |  t1.a = t2.a AND
        |  (t1.proctime > t2.proctime - INTERVAL '5' SECOND OR
        |   t1.proctime < t2.c + INTERVAL '5' SECOND)""".stripMargin
    streamUtil.verifySql(sql, "n/a")
  }

  /** Validates that no rowtime attribute is in the output schema **/
  @Test(expected = classOf[TableException])
  def testNoRowtimeAttributeInResult(): Unit = {
    val sql =
      """
        |SELECT *
        |FROM MyTable t1, MyTable2 t2
        |WHERE t1.a = t2.a AND
        |  t1.proctime BETWEEN t2.proctime - INTERVAL '5' SECOND AND t2.proctime
        | """.stripMargin

    streamUtil.verifySql(sql, "n/a")
  }

  /** Validates that range and equality predicate are not accepted **/
  @Test(expected = classOf[TableException])
  def testRangeAndEqualityPredicates(): Unit = {
    val sql =
      """
        |SELECT *
        |FROM MyTable t1, MyTable2 t2
        |WHERE t1.a = t2.a AND
        |  t1.proctime > t2.proctime - INTERVAL '5' SECOND AND
        |  t1.proctime = t2.proctime
        | """.stripMargin

    streamUtil.verifySql(sql, "n/a")
  }

  /** Validates that equality predicate with offset are not accepted **/
  @Test(expected = classOf[TableException])
  def testEqualityPredicateWithOffset(): Unit = {
    val sql =
      """
        |SELECT *
        |FROM MyTable t1, MyTable2 t2
        |WHERE t1.a = t2.a AND
        |  t1.proctime = t2.proctime - INTERVAL '5' SECOND
        | """.stripMargin

    streamUtil.verifySql(sql, "n/a")
  }

  /** Validates that no rowtime attribute is in the output schema for non-window inner join **/
  @Test(expected = classOf[TableException])
  def testNoRowtimeAttributeInResultForNonWindowInnerJoin(): Unit = {
    val sql =
      """
        |SELECT *
        |FROM MyTable t1, MyTable2 t2
        |WHERE t1.a = t2.a
        | """.stripMargin

    streamUtil.verifySql(sql, "n/a")
  }

  /** Validates that no proctime attribute is in remaining predicate for non-window inner join **/
  @Test(expected = classOf[TableException])
  def testNoProctimeAttributeInResultForNonWindowInnerJoin(): Unit = {
    val sql =
      """
        |SELECT *
        |FROM MyTable t1, MyTable2 t2
        |WHERE t1.a = t2.a AND t1.proctime > t2.proctime
        | """.stripMargin

    streamUtil.verifySql(sql, "n/a")
  }

  /** Rowtime attributes cannot be accessed in filter conditions yet. */
  @Test
  def testJoinWithRowtimeCondition(): Unit = {
    expectedException.expect(classOf[TableException])
    expectedException.expectMessage(
      "Rowtime attributes must not be in the input rows of a regular join.")

    val sql =
      """
        |SELECT t2.a
        |FROM MyTable t1 JOIN MyTable2 t2 ON
        |  t1.a = t2.a AND
        |  t1.c > t2.c - INTERVAL '5' SECOND
        |""".stripMargin

    streamUtil.verifySql(sql, "n/a")
  }

  /** Rowtime attributes cannot be accessed in filter conditions yet. */
  @Test
  def testJoinWithRowtimeConditionFromComplexQuery(): Unit = {
    expectedException.expect(classOf[TableException])
    expectedException.expectMessage(
      "Rowtime attributes must not be in the input rows of a regular join.")

    val util = streamTestUtil()

    util.addTable[(Long, Long)]("MyTable1", 'id, 'eventTs.rowtime)

    util.addTable[(Long, Long)]("MyTable2", 'id, 'eventTs.rowtime)

    val sql1 =
      """SELECT
        |  id,
        |  eventTs AS t1,
        |  COUNT(*) OVER (
        |    PARTITION BY id ORDER BY eventTs ROWS BETWEEN 100 PRECEDING AND CURRENT ROW
        |  ) AS cnt1
        |FROM MyTable1
        |""".stripMargin
    val sql2 =
      """SELECT DISTINCT
        |  id AS r_id,
        |  eventTs AS t2,
        |  COUNT(*) OVER (
        |    PARTITION BY id ORDER BY eventTs ROWS BETWEEN 50 PRECEDING AND CURRENT ROW
        |  ) AS cnt2
        |FROM MyTable2
        |""".stripMargin

    val left = util.tableEnv.sqlQuery(sql1)
    val right = util.tableEnv.sqlQuery(sql2)
    val result = left.join(right).where("id === r_id && t1 === t2").select("id, t1")

    util.verifyTable(result, "n/a")
  }

  /** Rowtime attributes cannot be accessed in projection yet. */
  @Test
  def testJoinWithRowtimeProjection(): Unit = {
    expectedException.expect(classOf[TableException])
    expectedException.expectMessage(
      "Rowtime attributes must not be in the input rows of a regular join.")

    val sql =
      """
        |SELECT t2.a, t2.c
        |FROM MyTable t1 JOIN MyTable2 t2 ON
        |  t1.a = t2.a
        |""".stripMargin

    streamUtil.verifySql(sql, "n/a")
  }
}


text:
module Azure::EventGrid::Mgmt::V2018_09_15_preview
  module Models
    #
    # Defines values for InputSchema
    #
    module InputSchema
      EventGridSchema = "EventGridSchema"
      CustomEventSchema = "CustomEventSchema"
      CloudEventV01Schema = "CloudEventV01Schema"
    end
  end
end


text:
'use strict';

const models = require('./index');

/**
 * @class
 * Initializes a new instance of the TaskAddCollectionParameter class.
 * @constructor
 * @summary A collection of Azure Batch tasks to add.
 *
 * @member {array} value The collection of tasks to add.
 *
 */
class TaskAddCollectionParameter {
  constructor() {
  }

  /**
   * Defines the metadata of TaskAddCollectionParameter
   *
   * @returns {object} metadata of TaskAddCollectionParameter
   *
   */
  mapper() {
    return {
      required: false,
      serializedName: 'TaskAddCollectionParameter',
      type: {
        name: 'Composite',
        className: 'TaskAddCollectionParameter',
        modelProperties: {
          value: {
            required: true,
            serializedName: 'value',
            constraints: {
              MaxItems: 100
            },
            type: {
              name: 'Sequence',
              element: {
                  required: false,
                  serializedName: 'TaskAddParameterElementType',
                  type: {
                    name: 'Composite',
                    className: 'TaskAddParameter'
                  }
              }
            }
          }
        }
      }
    };
  }
}

module.exports = TaskAddCollectionParameter;